]> Pileus Git - ~andy/csm213a-hw/commitdiff
Finish up
authorAndy Spencer <andy753421@gmail.com>
Thu, 13 Feb 2014 00:29:21 +0000 (00:29 +0000)
committerAndy Spencer <andy753421@gmail.com>
Thu, 13 Feb 2014 00:29:21 +0000 (00:29 +0000)
.gitignore
hw1/report.docx
hw1/report.htm [new file with mode: 0644]
vis/logger.py
vis/makefile
vis/visual.py
yue/main.cpp
yue/makefile

index eec85d625969bdca772320ce1029e46bbae2622a..1f72ef646b3872051973e96c8353bd894642b979 100644 (file)
@@ -5,6 +5,7 @@
 *.o
 *.pyc
 *.swp
+*.zip
 *~
 __pycache__
 xively
index 4078b0686c646b0ec0a59ea0b3a63a8d9dcb2348..9ad42d62290f63438a98deca9f379a54e0af6af4 100644 (file)
Binary files a/hw1/report.docx and b/hw1/report.docx differ
diff --git a/hw1/report.htm b/hw1/report.htm
new file mode 100644 (file)
index 0000000..9a869d7
--- /dev/null
@@ -0,0 +1,158 @@
+<!--
+
+1. Prepare a simple web page (I recommend using sites.google.com or just a plan
+   google doc and publishing it) with the following:
+
+   a. Text that briefly describes your software organization for mbed and the
+      host (e.g. event handlers, threads etc. and what they do in plain text),
+      and the precise protocol and format for data that is exchanged between
+      the host and the mbed.
+
+   b. URLS for: (i) Code for PC as a .zip file (you could put the .zip file on
+      Dropbox or on Github), (ii) Code for mbed on mbed.org (you can publish it
+      there), and (iii) The video.
+
+2. When you have everything ready, fill the form at
+   https://docs.google.com/forms/d/1AaTB7dhT99_khnrwIP3ZzDkjRRhPj7Ql9nE3RqRPwQw/viewform
+
+-->
+
+<h2>Brief Description</h2>
+
+<p>The objective of this homework is to explore organizing embedded software
+   using mbed as the platform in context of a simple system. Sensor data flows
+   in the direction of: mbed → PC → Xively.</p>
+
+<h2>Embedded Target Design</h2>
+
+<p>The mbed code is organized in a single main.cpp file which invokes libraries
+   to read the sensor data. The Accelerometer, Magnetometer, and Touch Sensor
+   libraries were acquired through the mbed website and the Analog Input and
+   Output libraries were included in the mbed SDK.</p>
+
+<p>The software consists of preemptable sensor loop running at a fixed rate, a
+   serial data receive interrupt handler, and a direct-memory access serial
+   transmitter. On each iteration of the sensor loop a time counter is checked
+   to determine which sensor are due for reading. Each sensor function polls
+   data from the sensor, packs the data into an output frame, and then write
+   the frame to the output queue.</p>
+
+<p><i>Note: the sensor reading was originally performed in a timer interrupt
+      routine, however, it moved to a background task to minimize interference
+      with the reception of serial commands.</i></p>
+
+<h2>Data Logger Design</h2>
+
+The data logger is implemented as a Graphical User Interface using Python and
+the GTK+ Toolkit. The source code is organized around the following classes:
+
+<ul>
+       <li>A Main class which performs basic initialization</li>
+       <li>A Config class for storing user preferences</li>
+       <li>A Device class to interfaces with the mbed using PySerial</li>
+       <li>A Logger class to transmit the recorded data to Xively</li>
+       <li>A Visual class to display the user interface</li>
+</ul>
+
+<h2>Data Collection</h2>
+
+<p>The mbed FRDM-KL46Z is responsible for data collection and sending it to the
+   host via Serial-over-USB. Sensors data is collected at a periodic rate and
+   is transmitted to the PC using the DATA_FRAME format shown below. The Serial
+   data transmit is handled by the KL46Z Direct-Memory Access (DMA) controller
+   so that data transmission does not block the CPU. When sensor data is ready,
+   it is packed and appended to a transmit buffer. At the end of the periodic
+   loop the DMA controller is enabled and data transmission begins</p>
+
+<p>Commands are sent to the mbed using the COMMAND_FRAME format and are
+   processed using a serial interrupt handler. The handler parses the incoming
+   messages and performs command processing when a valid COMMAND_FRAME is
+   received.</p>
+
+<h2>Serial Message Formats</h2>
+
+<p>As is mentioned above, the mbed and communicate via UART, thus working based
+   on serial protocol. Since the mbed can be perceived as a slave to the PC, we
+   let the mbed collect and send DATA_FRAME, while PC is responsible for
+   generating COMMAND_FRAME. The frame structure is as follows:</p>
+
+<h3>Data Frame</h3>
+<table cellspacing="0" cellpadding="2" border="1">
+<tr><td>1 Byte</td><td>4 bits  </td><td>4 bits </td><td>1 Byte </td><td>(Varied Size)</td><td>1 Byte</td></tr>
+<tr><td>HEADER</td><td>dataType</td><td>snsType</td><td>dataNum</td><td>data         </td><td>TAIL  </td></tr>
+</table>
+
+<h4>Field Descriptions</h4>
+<table cellspacing="0" cellpadding="2" border="1">
+       <tr><t4>HEADER:  </td><td>0x02, constant, indicating the start of a frame</td></tr>
+       <tr><td>dataType:</td><td>Data Type:<table>
+               <tr><td style="padding-left:3em">0-  int8</td><td style="padding-left:1em">1 -  int16</td><td style="padding-left:1em">2 -  int32</td></tr>
+               <tr><td style="padding-left:3em">3- uint8</td><td style="padding-left:1em">4 - uint16</td><td style="padding-left:1em">5 - uint32</td></tr>
+               <tr><td style="padding-left:3em">6- float</td><td style="padding-left:1em">7 - double</td><td style="padding-left:1em">          </td></tr>
+       </table></td></tr>
+       <tr><td>snsType: </td><td>Sensor Type:<ul style="list-style-type: none;">
+               <li>0 - LIGHT_SENSOR</li>
+               <li>1 - ACC_SENSOR</li>
+               <li>2 - MAG_SENSOR</li>
+               <li>3 - TOUCH_SENSOR</li>
+               <li>4 - ADC_SENSOR</li>
+       </ul></td></tr>
+       <tr><td>dataNum: </td><td>Data number. Number of data pack in the frame</td></tr>
+       <tr><td>data:    </td><td>Sensor data. How it is packed is based on dataType and dataNum</td></tr>
+       <tr><td>TAIL:    </td><td>0x0A, constant, indicating the end of a frame</td></tr>
+</table>
+
+<h3>Command Frame</h3>
+<table cellspacing="0" cellpadding="2" border="1">
+<tr><td>1 Byte</td><td>4 bits </td><td>4 bits </td><td>4 Byte  </td><td>1 Byte</td></tr>
+<tr><td>HEADER</td><td>cmdType</td><td>snsType</td><td>Interval</td><td>TAIL  </td></tr>
+</table>
+
+<h4>Field Descriptions</h4>
+<table cellspacing="0" cellpadding="2" border="1">
+       <tr><td>HEADER:  </td><td>0x02, constant, indicating the start of a frame</td></tr>
+       <tr><td>cmdType: </td><td>Command Type:<ul style="list-style-type: none;">
+               <li>0 - START</li>
+               <li>1 - STOP</li>
+               <li>2 - SET_INT</li>
+       </td></tr>
+       <tr><td>Interval:</td><td>sampling rate. Representing a float of 4 Bytes.</td></tr>
+       <tr><td>TAIL:    </td><td>0x0A, constant, indicating the end of a frame</td></tr>
+</table>
+
+<!--
+   a. Text that briefly describes your software organization for mbed and the
+      host (e.g. event handlers, threads etc. and what they do in plain text),
+      and the precise protocol and format for data that is exchanged between
+      the host and the mbed.
+-->
+
+<h2>Sampling Rate</h2>
+
+<p>The following sampling rates were obtained for each sensor, and a combined
+   sampling rate when all sensors are sampling simultaneously. Data collection
+   was performed using a 230400 serial baud rate.</p>
+
+<table>
+       <tr><th>Sensor           </th><th style="padding-left: 1em;">Sampling Rate</th></tr>
+       <tr><td>Accelerometer    </td><td style="padding-left: 1em;"> 560 Hz      </td></tr>
+       <tr><td>Magnetometer     </td><td style="padding-left: 1em;"> 530 Hz      </td></tr>
+       <tr><td>Touch Sensor     </td><td style="padding-left: 1em;">1930 Hz      </td></tr>
+       <tr><td>Light Sensor     </td><td style="padding-left: 1em;">2414 Hz      </td></tr>
+       <tr><td>Analog to Digital</td><td style="padding-left: 1em;"> 820 Hz      </td></tr>
+       <tr><td>All Combined     </td><td style="padding-left: 1em;"> 150 Hz      </td></tr>
+</table>
+
+<h2>Online Submission</h2>
+
+<dl>
+       <dt>Code for mbed</dt>
+       <dd><a href="http://mbed.org/users/andy753421/code/Sensors/">http://mbed.org/users/andy753421/code/Sensors/</a></dd>
+
+       <dt>Code for PC</dt>
+       <dd><a href="https://sites.google.com/a/g.ucla.edu/ibeaconnav/homework1/python.zip">https://sites.google.com/a/g.ucla.edu/ibeaconnav/homework1/python.zip</a></dd>
+
+
+       <dt>Video Link</dt>
+       <dd>(we will do a demo during office hours)</dd>
+</dl>
index bd394a1fdef2b0f14ec6bed489f7c51c063d5231..a1cccf7624ab82e464b704506493c66b501d9d72 100644 (file)
@@ -37,7 +37,7 @@ class Logger:
                self.queue.append(state)
                delta = datetime.utcnow() - self.last
                if delta.total_seconds() > self.config.maxrate:
-                       self.flush()
+                       return self.flush()
 
        # Private methods
        def flush(self):
@@ -54,14 +54,26 @@ class Logger:
                if not self.running() or len(self.queue) == 0:
                        return
 
+               # Limit data to 500 samples per upload
+               limit  = 500
+               upload = self.queue
+               if len(upload) > limit:
+                       print("upload: cropping - %d -> %d" %
+                                       (len(upload), limit))
+                       upload = upload[0:limit-1]
+
                self.feed.datastreams = [
-                       get(self.queue, 'acc'),
-                       get(self.queue, 'mag'),
-                       get(self.queue, 'tch'),
-                       get(self.queue, 'lgt'),
-                       get(self.queue, 'a2d'),
+                       get(upload, 'acc'),
+                       get(upload, 'mag'),
+                       get(upload, 'tch'),
+                       get(upload, 'lgt'),
+                       get(upload, 'a2d'),
                ]
-               self.feed.update()
+
+               try:
+                       self.feed.update()
+               except Exception as ex:
+                       return str(ex)
 
                self.last  = datetime.utcnow()
                self.queue = []
index a8665419dc54c66eed81c8d95e4331f32e4b0198..306cb36dc85900505717bfe1e679f47769e40890 100644 (file)
@@ -8,3 +8,6 @@ test:
 
 clean:
        rm -rf *.pyc __pycache__
+
+dist:
+       zip python.zip *.py xively/*.py
index f2deed65d24ffe7b16e87525ef3d4d0ebdac8e94..737e2d9a3b61cc3fd08b3c58a3601cfb2ff47e6d 100644 (file)
@@ -17,7 +17,7 @@ else:
 
 class Visual:
        FRAMES_PER_SEC = 60 # hz
-       RATES_PER_SEC  = 10 # hz
+       RATES_PER_SEC  = 1  # hz
 
        def __init__(self, config, device, logger):
                def get_objects(names):
@@ -61,14 +61,14 @@ class Visual:
                if act.get_active():
                        self.status(self.device.connect())
                else:
-                       self.status(self.device.disconnect())
+                       self.device.disconnect()
                return True
 
        def on_xively(self, act):
                if act.get_active():
                        self.status(self.logger.connect())
                else:
-                       self.status(self.logger.disconnect())
+                       self.logger.disconnect()
                return True
 
        def on_flush(self, act):
@@ -224,7 +224,8 @@ class Visual:
 
        # Private methods
        def status(self, msg):
+               status = self.builder.get_object("status")
+               status.pop(context_id=0)
                if not msg:
                        return
-               status = self.builder.get_object("status")
                status.push(text=('Error: ' + msg), context_id=0)
index 218b27a9bbf8e96336ff8667e510d8c93f493063..150be36fd8ce0c1c93b356f99a62baa409ed72bf 100644 (file)
@@ -87,7 +87,13 @@ MMA8451Q   accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);
 MAG3110    magSensor(PTE25, PTE24);\r
 TSISensor  tchSensor;\r
 AnalogIn   lgtSensor(PTE22);\r
-AnalogIn   a2dSensor(A0);\r
+\r
+AnalogIn   a2dSensor0(A0);\r
+AnalogIn   a2dSensor1(A1);\r
+AnalogIn   a2dSensor2(A2);\r
+AnalogIn   a2dSensor3(A3);\r
+AnalogIn   a2dSensor4(A4);\r
+AnalogIn   a2dSensor5(A5);\r
 \r
 AnalogOut  a2dOutput(PTE30);\r
 \r
@@ -220,7 +226,7 @@ void clock1_interrupt(void){
     static int ledCnt;\r
 \r
     // Write A2D output sine wave\r
-    a2dOutput.write(sin(a2dCnt * TIME_ACCURACY * (2*PI) * 0.1));\r
+    //a2dOutput.write(sin(a2dCnt * TIME_ACCURACY * (2*PI) * 0.1));\r
 \r
     // Send data through Serial\r
     if (accEnable && accCnt >= (int)(accTmr/TIME_ACCURACY+0.5)){\r
@@ -373,12 +379,12 @@ void sendTchInfo(void){
 \r
 void sendA2dInfo(void){\r
     float a2dData[6];\r
-    a2dData[0] = a2dSensor.read();\r
-    a2dData[1] = 0;\r
-    a2dData[2] = 0;\r
-    a2dData[3] = 0;\r
-    a2dData[4] = 0;\r
-    a2dData[5] = 0;\r
+    a2dData[0] = a2dSensor0.read();\r
+    a2dData[1] = a2dSensor1.read();\r
+    a2dData[2] = a2dSensor2.read();\r
+    a2dData[3] = a2dSensor3.read();\r
+    a2dData[4] = a2dSensor4.read();\r
+    a2dData[5] = a2dSensor5.read();\r
     int len = packToFrame(txFrame, SNS_A2D, TYP_F32, 6, a2dData);\r
 \r
     printStr("[A2D] data=%2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\r\n",\r
index 19f0bbb5359d4e059d3d78f520f8abe8e5771f97..86b2f59b1e7ad72184fb65d098b4255b8290f7ad 100644 (file)
@@ -6,5 +6,8 @@ LDFLAGS  = -lm
 
 default: info install
 
+dist:
+       zip mbed.zip makefile ../common.mk *.{c,cpp,h} */*.{cpp,.h}
+
 -include ../config.mk
 -include ../common.mk