class Frame:
# Sensor types
- ACC_SNS = 0x00
- MAG_SNS = 0x01
- LGT_SNS = 0x02
- TCH_SNS = 0x03
- A2D_SNS = 0x04
+ SNS_ACC = 0x00
+ SNS_MAG = 0x01
+ SNS_LGT = 0x02
+ SNS_TCH = 0x03
+ SNS_A2D = 0x04
SNS_NUM = 0x05
SNS_SHIFT = 4
SNS_MASK = 0xF0
# Data types
- INT = 0
- LONG = 1
- FLOAT = 2
- DOUBLE = 3
-
- TYP_NUM = 4
+ TYP_S8 = 0
+ TYP_S16 = 1
+ TYP_S32 = 2
+ TYP_U8 = 3
+ TYP_U16 = 4
+ TYP_U32 = 5
+ TYP_F32 = 6
+ TYP_F64 = 7
+
+ TYP_NUM = 8
TYP_SHIFT = 0
TYP_MASK = 0x0F
# Command codes
- STOP = 0
- START = 1
- RATE = 2
+ CMD_STOP = 0
+ CMD_START = 1
+ CMD_RATE = 2
- OPER_NUM = 3
- OPER_SHIFT = 0
- OPER_MASK = 0x0F
+ CMD_NUM = 3
+ CMD_SHIFT = 0
+ CMD_MASK = 0x0F
# Frame information
HEADER = 0x02
DATA_POS = 3
# Maps
- snsMap = {ACC_SNS: 'acc',
- MAG_SNS: 'mag',
- LGT_SNS: 'lgt',
- TCH_SNS: 'tch',
- A2D_SNS: 'a2d'}
-
- cmdMap = {START, 'start',
- STOP, 'stop',
- RATE, 'rate'}
-
- sizeMap = {INT: 2,
- LONG: 4,
- FLOAT: 4,
- DOUBLE: 8}
-
- fmtMap = {INT: 'h',
- LONG: 'i',
- FLOAT: 'f',
- DOUBLE: 'd'}
+ snsMap = {SNS_ACC: 'acc',
+ SNS_MAG: 'mag',
+ SNS_LGT: 'lgt',
+ SNS_TCH: 'tch',
+ SNS_A2D: 'a2d'}
+
+ cmdMap = {CMD_START, 'start',
+ CMD_STOP, 'stop',
+ CMD_RATE, 'rate'}
+
+ sizeMap = {TYP_S8: 1, TYP_S16: 2, TYP_S32: 4,
+ TYP_U8: 1, TYP_U16: 2, TYP_U32: 4,
+ TYP_F32: 4, TYP_F64: 8}
+
+ fmtMap = {TYP_S8: 'b', TYP_S16: 'h', TYP_S32: 'i',
+ TYP_U8: 'B', TYP_U16: 'H', TYP_U32: 'I',
+ TYP_F32: 'f', TYP_F64: 'd'}
# Parser data
index = 0 # read index
def set_rate(self, sensor, interval):
sns = Frame.findCode(Frame.snsMap, sensor)
- bits = (sns << Frame.SNS_SHIFT) | \
- (Frame.RATE << Frame.OPER_SHIFT)
+ bits = (sns << Frame.SNS_SHIFT) | \
+ (Frame.CMD_RATE << Frame.CMD_SHIFT)
self._write_binary('Bf', bits, interval)
def set_enable(self, sensor, enabled):
sns = Frame.findCode(Frame.snsMap, sensor)
- oper = Frame.START if enabled else Frame.STOP
- bits = (sns << Frame.SNS_SHIFT) | \
- (oper << Frame.OPER_SHIFT)
+ cmd = Frame.CMD_START if enabled else Frame.CMD_STOP
+ bits = (sns << Frame.SNS_SHIFT) | \
+ (cmd << Frame.CMD_SHIFT)
self._write_binary('B', bits)
def process(self):
self.accs = get_objects(['accx', 'accy', 'accz'])
self.mags = get_objects(['magx', 'magy', 'magz'])
self.lgts = get_objects(['lgt'])
- self.tchs = get_objects(['tch'])
+ self.tchs = get_objects(['tchp', 'tchd'])
self.a2ds = get_objects(['a2d0', 'a2d1', 'a2d2', 'a2d3', 'a2d4', 'a2d5'])
# Signal handlers
def update(self, state):
- def setxyz(objs, vals):
- if vals[0]: objs[0].set_text('X: %f' % vals[0])
- if vals[1]: objs[1].set_text('Y: %f' % vals[1])
- if vals[2]: objs[2].set_text('Z: %f' % vals[2])
- def setabs(objs, vals):
+ def setval(objs, vals, lbls):
for i in range(0,len(objs)):
- if vals[i]: objs[i].set_text('%f' % vals[i])
-
- setxyz(self.accs, state.acc)
- setxyz(self.mags, state.mag)
- setabs(self.lgts, state.lgt)
- setabs(self.tchs, state.tch)
- setabs(self.a2ds, state.a2d)
+ if vals[i] == None:
+ continue
+ if lbls and lbls[i]:
+ objs[i].set_text('%s: %f' % (lbls[i], vals[i]))
+ else:
+ objs[i].set_text('%f' % vals[i])
+
+ setval(self.accs, state.acc, ['X', 'Y', 'Z'])
+ setval(self.mags, state.mag, ['X', 'Y', 'Z'])
+ setval(self.lgts, state.lgt, [])
+ setval(self.tchs, state.tch, ['P', 'D'])
+ setval(self.a2ds, state.a2d, [])
def debug(self, state):
print('update: ' + str(state))
print('\tacc - ' + str(state.acc))
print('\tmag - ' + str(state.mag))
print('\tlgt - ' + str(state.lgt))
- print('\ttch - ' + str(state.tch))
+ print('\ttch - ' + str(state.touch))
print('\ta2d - ' + str(state.a2d))
def timer(self):
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
+ <object class="GtkToggleAction" id="serial_act">
+ <property name="label" translatable="yes">Serial</property>
+ <property name="stock_id">gtk-connect</property>
+ <signal name="activate" handler="on_serial" swapped="no"/>
+ </object>
+ <object class="GtkAction" id="settings_act">
+ <property name="label" translatable="yes">Settings</property>
+ <property name="stock_id">gtk-preferences</property>
+ <signal name="activate" handler="on_show" swapped="no"/>
+ </object>
+ <object class="GtkToggleAction" id="xively_act">
+ <property name="label" translatable="yes">Xively</property>
+ <property name="stock_id">gtk-connect</property>
+ <signal name="activate" handler="on_xively" swapped="no"/>
+ </object>
<object class="GtkAdjustment" id="a2d_adj">
<property name="upper">100</property>
<property name="value">1</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
- <object class="GtkAdjustment" id="mag_adj">
- <property name="upper">100</property>
- <property name="value">1</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkToggleAction" id="serial_act">
- <property name="label" translatable="yes">Serial</property>
- <property name="stock_id">gtk-connect</property>
- <signal name="activate" handler="on_serial" swapped="no"/>
- </object>
- <object class="GtkAction" id="settings_act">
- <property name="label" translatable="yes">Settings</property>
- <property name="stock_id">gtk-preferences</property>
- <signal name="activate" handler="on_show" swapped="no"/>
- </object>
- <object class="GtkToggleAction" id="xively_act">
- <property name="label" translatable="yes">Xively</property>
- <property name="stock_id">gtk-connect</property>
- <signal name="activate" handler="on_xively" swapped="no"/>
+ <object class="GtkAction" id="flush_act">
+ <property name="label" translatable="yes">Upload</property>
+ <property name="stock_id">gtk-floppy</property>
+ <signal name="activate" handler="on_flush" swapped="no"/>
</object>
<object class="GtkAdjustment" id="datab_adj">
<property name="lower">6</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
- <object class="GtkAction" id="flush_act">
- <property name="label" translatable="yes">Upload</property>
- <property name="stock_id">gtk-floppy</property>
- <signal name="activate" handler="on_flush" swapped="no"/>
- </object>
<object class="GtkAdjustment" id="lgt_adj">
<property name="upper">100</property>
<property name="value">1</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
+ <object class="GtkAdjustment" id="mag_adj">
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
<object class="GtkAdjustment" id="rate_adj">
<property name="upper">100</property>
<property name="step_increment">1</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="accel_val">
+ <object class="GtkHBox" id="acc_val">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="tch">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">0.0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="lgt">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">0.0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="accel_lbl">
+ <object class="GtkLabel" id="acc_lbl">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
+ <child>
+ <object class="GtkHBox" id="tch_val">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="tchp">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">P: 0.0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="tchd">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">D: 0.0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="lgt_val">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="lgt">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">0.0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
#define TIME_ACCURACY 0.01\r
\r
#define ACC_SNS_DEFAULT 0.1 // default collecting interval in seconds\r
-#define MAG_SNS_DEFAULT 1.0\r
-#define LGT_SNS_DEFAULT 1.0\r
-#define TCH_SNS_DEFAULT 1.0\r
-#define A2D_SNS_DEFAULT 1.0\r
+#define MAG_SNS_DEFAULT 0.1\r
+#define LGT_SNS_DEFAULT 0.1\r
+#define TCH_SNS_DEFAULT 0.1\r
+#define A2D_SNS_DEFAULT 0.1\r
#define LED_OUT_DEFAULT 0.5\r
\r
#define MIN_RATE 1E-4 // 1 kHz\r
\r
#define MAX_FRAME_SIZE 256\r
\r
-#define SNS_NUM 5\r
-#define TYPE_NUM 4\r
-#define OPER_NUM 3\r
+#define SNS_NUM 5\r
+#define TYP_NUM 8\r
+#define CMD_NUM 3\r
\r
typedef enum {\r
- ACC_SNS,\r
- MAG_SNS,\r
- LGT_SNS,\r
- TCH_SNS,\r
- A2D_SNS,\r
+ SNS_ACC,\r
+ SNS_MAG,\r
+ SNS_LGT,\r
+ SNS_TCH,\r
+ SNS_A2D,\r
} sns_t;\r
\r
typedef enum {\r
- INT,\r
- LONG,\r
- FLOAT,\r
- DOUBLE,\r
+ TYP_S8, TYP_S16, TYP_S32,\r
+ TYP_U8, TYP_U16, TYP_U32,\r
+ TYP_F32, TYP_F64,\r
} type_t;\r
\r
typedef enum {\r
- STOP,\r
- START,\r
- RATE,\r
-} oper_t;\r
+ CMD_STOP,\r
+ CMD_START,\r
+ CMD_RATE,\r
+} cmd_t;\r
\r
// Data Frame Information\r
typedef struct {\r
typedef struct {\r
uint8_t header;\r
struct {\r
- uint8_t oper : 4;\r
- uint8_t sns : 4;\r
+ uint8_t cmd : 4;\r
+ uint8_t sns : 4;\r
} bits;\r
float interval;\r
-} __attribute__((__packed__)) command_t;\r
+} __attribute__((__packed__)) control_t;\r
\r
// Define Devices & Pins\r
MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);\r
float a2dTmr = A2D_SNS_DEFAULT;\r
float ledTmr = LED_OUT_DEFAULT;\r
\r
-bool accEnable = false;\r
-bool magEnable = true;\r
+bool accEnable = true;\r
+bool magEnable = false;\r
bool lgtEnable = false;\r
bool tchEnable = false;\r
bool a2dEnable = false;\r
bool ledEnable = true;\r
\r
-bool useStr = true;\r
+bool useStr = false;\r
bool useHex = false;\r
-bool useBin = false;\r
+bool useBin = true;\r
\r
uint8_t txFrame[MAX_FRAME_SIZE];\r
uint8_t rxFrame[MAX_FRAME_SIZE];\r
void clock1_interrupt(void);\r
void serialRx_interrupt(void);\r
\r
-void runCommand(command_t *cmd);\r
+void runCommand(control_t *cmd);\r
\r
void sendAccInfo(void);\r
void sendMagInfo(void);\r
static int index = 0;\r
static int length = 0;\r
\r
- command_t *cmd = (command_t*)rxFrame;\r
+ control_t *cmd = (control_t*)rxFrame;\r
\r
while (serial.readable()) {\r
rxFrame[index++] = serial.getc();\r
index = 0;\r
break;\r
case 1: // Bits\r
- if (cmd->bits.sns >= SNS_NUM ||\r
- cmd->bits.oper >= OPER_NUM) {\r
+ if (cmd->bits.sns >= SNS_NUM ||\r
+ cmd->bits.cmd >= CMD_NUM) {\r
state = index = 0;\r
- } else if (cmd->bits.oper == RATE) {\r
+ } else if (cmd->bits.cmd == CMD_RATE) {\r
length = 4;\r
state = 2;\r
} else {\r
* Command handler *\r
*******************/\r
\r
-void runCommand(command_t *cmd)\r
+void runCommand(control_t *cmd)\r
{\r
// Validate interval\r
- sns_t snsType = (sns_t )cmd->bits.sns;\r
- oper_t operType = (oper_t)cmd->bits.oper;\r
- float interval = CLAMP(cmd->interval, MIN_RATE, MAX_RATE);\r
+ sns_t snsType = (sns_t)cmd->bits.sns;\r
+ cmd_t cmdType = (cmd_t)cmd->bits.cmd;\r
+ float interval = CLAMP(cmd->interval, MIN_RATE, MAX_RATE);\r
\r
// Save value to global data\r
switch(snsType){\r
- case ACC_SNS:\r
- switch(operType){\r
- case STOP: accEnable = false; break;\r
- case START: accEnable = true; break;\r
- case RATE: accTmr = interval; break;\r
+ case SNS_ACC:\r
+ switch(cmdType){\r
+ case CMD_STOP: accEnable = false; break;\r
+ case CMD_START: accEnable = true; break;\r
+ case CMD_RATE: accTmr = interval; break;\r
}\r
break;\r
\r
- case MAG_SNS:\r
- switch(operType){\r
- case STOP: magEnable = false; break;\r
- case START: magEnable = true; break;\r
- case RATE: magTmr = interval; break;\r
+ case SNS_MAG:\r
+ switch(cmdType){\r
+ case CMD_STOP: magEnable = false; break;\r
+ case CMD_START: magEnable = true; break;\r
+ case CMD_RATE: magTmr = interval; break;\r
}\r
break;\r
\r
- case LGT_SNS:\r
- switch(operType){\r
- case STOP: lgtEnable = false; break;\r
- case START: lgtEnable = true; break;\r
- case RATE: lgtTmr = interval; break;\r
+ case SNS_LGT:\r
+ switch(cmdType){\r
+ case CMD_STOP: lgtEnable = false; break;\r
+ case CMD_START: lgtEnable = true; break;\r
+ case CMD_RATE: lgtTmr = interval; break;\r
}\r
break;\r
\r
- case TCH_SNS:\r
- switch(operType){\r
- case STOP: tchEnable = false; break;\r
- case START: tchEnable = true; break;\r
- case RATE: tchTmr = interval; break;\r
+ case SNS_TCH:\r
+ switch(cmdType){\r
+ case CMD_STOP: tchEnable = false; break;\r
+ case CMD_START: tchEnable = true; break;\r
+ case CMD_RATE: tchTmr = interval; break;\r
}\r
break;\r
\r
- case A2D_SNS:\r
- switch(operType){\r
- case STOP: a2dEnable = false; break;\r
- case START: a2dEnable = true; break;\r
- case RATE: a2dTmr = interval; break;\r
+ case SNS_A2D:\r
+ switch(cmdType){\r
+ case CMD_STOP: a2dEnable = false; break;\r
+ case CMD_START: a2dEnable = true; break;\r
+ case CMD_RATE: a2dTmr = interval; break;\r
}\r
break;\r
}\r
accData[0] = accSensor.getAccX();\r
accData[1] = accSensor.getAccY();\r
accData[2] = accSensor.getAccZ();\r
- int len = packToFrame(txFrame, ACC_SNS, FLOAT, 3, accData);\r
+ int len = packToFrame(txFrame, SNS_ACC, TYP_F32, 3, accData);\r
\r
printStr("[ACC] accX=%-2.4f accY=%-2.4f accZ=%-2.4f\r\n",\r
accData[0], accData[1], accData[2]);\r
}\r
\r
void sendMagInfo(void){\r
- int magData[3];\r
- magSensor.getValues(&magData[0], &magData[1], &magData[2]);\r
- int len = packToFrame(txFrame, MAG_SNS, INT, 3, magData);\r
+ // magSensor uses the wrong types,\r
+ // so we have to convert it\r
+ int tmp[3];\r
+ magSensor.getValues(&tmp[0], &tmp[1], &tmp[2]);\r
+ uint16_t magData[3];\r
+ magData[0] = tmp[0];\r
+ magData[1] = tmp[1];\r
+ magData[2] = tmp[2];\r
+ int len = packToFrame(txFrame, SNS_MAG, TYP_S16, 3, magData);\r
\r
printStr("[MAG] magX=%hd magY=%hd magZ=%hd %d\r\n",\r
magData[0], magData[1], magData[2], sizeof(int));\r
\r
void sendLgtInfo(void){\r
float lgtData = lgtSensor.read();\r
- int len = packToFrame(txFrame, LGT_SNS, FLOAT, 1, &lgtData);\r
+ int len = packToFrame(txFrame, SNS_LGT, TYP_F32, 1, &lgtData);\r
\r
printStr("[LGT] intensity=%f\r\n",\r
lgtSensor.read());\r
float tchData[2];\r
tchData[0] = tchSensor.readPercentage();\r
tchData[1] = tchSensor.readDistance();\r
- int len = packToFrame(txFrame, TCH_SNS, FLOAT, 2, tchData);\r
+ int len = packToFrame(txFrame, SNS_TCH, TYP_F32, 2, tchData);\r
\r
printStr("[TCH] force=%0.4f distance=%2.2f\r\n",\r
tchData[0], tchData[1]);\r
a2dData[3] = 0;\r
a2dData[4] = 0;\r
a2dData[5] = 0;\r
- int len = packToFrame(txFrame, A2D_SNS, FLOAT, 6, a2dData);\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
a2dData[0], a2dData[1], a2dData[2],\r
\r
int calDataSize(type_t dataType){\r
switch(dataType){\r
- case INT: return 2;\r
- case LONG: return 4;\r
- case FLOAT: return 4;\r
- case DOUBLE: return 8;\r
+ case TYP_S8: return 1;\r
+ case TYP_S16: return 2;\r
+ case TYP_S32: return 4;\r
+ case TYP_U8: return 1;\r
+ case TYP_U16: return 2;\r
+ case TYP_U32: return 4;\r
+ case TYP_F32: return 4;\r
+ case TYP_F64: return 8;\r
}\r
return 4;\r
}\r