]> Pileus Git - ~andy/csm213a-hw/blob - yue/main.cpp
Pull changes from Yue
[~andy/csm213a-hw] / yue / main.cpp
1 #include "mbed.h"\r
2 #include "TSISensor.h"          // Touch Sensor\r
3 #include "MAG3110.h"            // Magnetic Sensor\r
4 #include "MMA8451Q.h"           // AcceleroMeter\r
5 //#include "DataFrame.h"\r
6 \r
7 \r
8 \r
9 #define MMA8451_I2C_ADDRESS (0x1d<<1)   // acc sensor address\r
10 #define TIME_ACCURACY     0.1\r
11 #define LGT_SNS_DEFAULT   2             // default collecting interval in seconds\r
12 #define ACC_SNS_DEFAULT   2\r
13 #define MAG_SNS_DEFAULT   2\r
14 #define TCH_SNS_DEFAULT   2\r
15 \r
16 // Parameters in Data Frame\r
17 // TODO: need to sync with the pc program\r
18 \r
19 #define HEADER    0x02\r
20 \r
21 #define SNS_BITS  5\r
22 #define LGT_SNS   0x00\r
23 #define ACC_SNS   0x01\r
24 #define MAG_SNS   0x02\r
25 #define TCH_SNS   0x03\r
26 #define ADC_SNS_1 0x04\r
27 \r
28 #define INT    0\r
29 #define LONG   1\r
30 #define FLOAT  2\r
31 #define DOUBLE 3\r
32 #define TAIL   0x0A             // '\n'\r
33 \r
34 // Command Frame\r
35 #define START   0\r
36 #define STOP    1\r
37 #define SET_INT 2\r
38 \r
39 \r
40 \r
41 #define MAX_FRAME_LEN 255\r
42 // Define Devices & Pins\r
43 MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);\r
44 TSISensor touchSensor;\r
45 MAG3110 magSensor(PTE25, PTE24);\r
46 Serial serial(USBTX, USBRX);\r
47 Ticker clock1;\r
48 AnalogIn lightSensor(PTE22);\r
49 \r
50 \r
51 // Global Variables\r
52 // Initial interval: in seconds\r
53 float lgtTmr = LGT_SNS_DEFAULT;\r
54 float accTmr = ACC_SNS_DEFAULT;\r
55 float magTmr = MAG_SNS_DEFAULT;\r
56 float tchTmr = TCH_SNS_DEFAULT;\r
57 \r
58 bool lgtEnable = false;\r
59 bool accEnable = false;\r
60 bool magEnable = true;\r
61 bool tchEnable = false;\r
62 \r
63 void clock1_interrupt();\r
64 void serialRx_interrupt();\r
65 void sendLightInfo();\r
66 void sendAccInfo();\r
67 void sendMagInfo();\r
68 void sendTouchInfo();\r
69 int packToFrame(char*, char, char, int, void*);\r
70 char* floatToByte(float);\r
71 float byteToFloat(char*);\r
72 int calDataSize(char);\r
73 void printHex(char*);\r
74 void sendFrame(char*, int);\r
75 \r
76 \r
77 int main() {\r
78     // Initialization\r
79     // Interruption Declarations\r
80     clock1.attach(&clock1_interrupt, TIME_ACCURACY);    // maximun accuracy be 0.1s\r
81     serial.attach(&serialRx_interrupt, Serial::RxIrq);  // receive interrupt for serialS\r
82     magSensor.begin();\r
83 \r
84     serial.printf("\r\n============= Start of the program ============\r\n");\r
85     while(1){\r
86         wait(3);\r
87     }\r
88 }\r
89 \r
90 \r
91 /*---------------------------------------------------------------\r
92   ## Receive Interruption of the Serial ##\r
93   -> used to receive & process user command\r
94   -> and configure the board accordingly\r
95   ---------------------------------------------------------------*/\r
96 /*void serialRx_interrupt_userFriendlyVersion(){\r
97     clock1.detach();                // close the interrupt\r
98     serial.printf("\r\n");\r
99 \r
100     // Receive the Serial Input\r
101     float interval;\r
102     char buffer[255];\r
103     char temp[255];\r
104     char ch = serial.getc();\r
105     int i;\r
106     for (i=0 ; ch!='\n' && ch!='\r'; i++){\r
107         serial.putc(ch);\r
108         buffer[i] = ch;\r
109         if (ch==127){                // BackSpace\r
110             i--;\r
111             i--;\r
112         }\r
113         ch = serial.getc();\r
114     }\r
115     buffer[i] = '\0';\r
116     serial.printf("\r\nBUFFER: %s %d\r\n", buffer,i);\r
117     // TODO: buffer -> lower case\r
118 \r
119     // Process the Serial Input\r
120     // Set-Interval Command\r
121     if (strstr(buffer, "set")!=NULL && strstr(buffer, "int")!= NULL){\r
122         sscanf(buffer, "%*[^0123456789.]%s", temp);       // find the number in buffer\r
123         sscanf(temp, "%f", &interval);                    // translate into float\r
124         if (interval<0.1 || interval>5){\r
125             interval  = 1;\r
126         }\r
127         if (strstr(buffer, "acc")){\r
128             accTmr = interval;\r
129         }\r
130         if (strstr(buffer, "mag")){\r
131             magTmr = interval;\r
132         }\r
133         if (strstr(buffer, "light")){\r
134             lgtTmr = interval;\r
135         }\r
136         if (strstr(buffer, "touch")){\r
137             tchTmr = interval;\r
138         }\r
139     }\r
140 \r
141     // Stop Command\r
142     else if (strstr(buffer, "stop")!= NULL){\r
143         serial.printf("STOP\r\n");\r
144         if (strstr(buffer, "acc")){\r
145             accEnable = false;\r
146             accTmr = ACC_SNS_DEFAULT;\r
147         }\r
148         if (strstr(buffer, "mag")){\r
149             magEnable = false;\r
150             magTmr = MAG_SNS_DEFAULT;\r
151         }\r
152         if (strstr(buffer, "light")){\r
153             lgtEnable = false;\r
154             lgtTmr = LGT_SNS_DEFAULT;\r
155         }\r
156         if (strstr(buffer, "touch")){\r
157             tchEnable = false;\r
158             tchTmr = TCH_SNS_DEFAULT;\r
159         }\r
160     }\r
161 \r
162     // Start Command\r
163     else if (strstr(buffer, "start")!=NULL){\r
164         if (strstr(buffer, "acc") && !accEnable){\r
165             accEnable = true;\r
166             accTmr = ACC_SNS_DEFAULT;\r
167         }\r
168         if (strstr(buffer, "mag") && !magEnable){\r
169             magEnable = true;\r
170             magTmr = MAG_SNS_DEFAULT;\r
171         }\r
172         if (strstr(buffer, "light") && !lgtEnable){\r
173             lgtEnable = true;\r
174             lgtTmr = LGT_SNS_DEFAULT;\r
175         }\r
176         if (strstr(buffer, "touch") && !tchEnable){\r
177             tchEnable = true;\r
178             tchTmr = TCH_SNS_DEFAULT;\r
179         }\r
180     }\r
181     clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
182 }\r
183 */\r
184 \r
185 void serialRx_interrupt(){                          // Byte version\r
186     clock1.detach();                                // close the interrupt temporarily\r
187     int i = 0;\r
188     char frame[MAX_FRAME_LEN];\r
189     char ch = serial.getc();\r
190     while (ch!=HEADER){\r
191         if (serial.readable()){\r
192             ch = serial.getc();\r
193         }\r
194         else{\r
195             serial.printf("[ERROR] broken data!\r\n");\r
196             clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
197             return;\r
198         }\r
199     }\r
200     //TODO: ticker for time out\r
201     while (serial.readable()){\r
202         frame[i] = ch;\r
203         if (ch=='\n'){\r
204             break;\r
205         }\r
206         ch = serial.getc();\r
207         i++;\r
208     }\r
209     frame[++i] = '\0';\r
210     float interval=-1;\r
211     char snsType = frame[1]|0x1F;\r
212     char oper = (frame[1]|0xE0)>>SNS_BITS;              // operation type\r
213     if (oper==SET_INT){\r
214         memcpy(&interval,&frame[2],4);\r
215         if (interval<0.0001||interval>10){\r
216             interval = 1;\r
217         }\r
218     }\r
219     switch(snsType){\r
220         case ACC_SNS:\r
221         {\r
222             switch(oper){\r
223                 case START:     accEnable = true;  break;\r
224                 case STOP:      accEnable = false; break;\r
225                 case SET_INT:   accTmr = interval; break;\r
226             }\r
227         }\r
228         case MAG_SNS:\r
229         {\r
230             switch(oper){\r
231                 case START:     magEnable = true;  break;\r
232                 case STOP:      magEnable = false; break;\r
233                 case SET_INT:   magTmr = interval; break;\r
234             }\r
235         }\r
236         case LGT_SNS:\r
237         {\r
238             switch(oper){\r
239                 case START:     lgtEnable = true;  break;\r
240                 case STOP:      lgtEnable = false; break;\r
241                 case SET_INT:   lgtTmr = interval; break;\r
242             }\r
243         }\r
244         case TCH_SNS:\r
245         {\r
246             switch(oper){\r
247                 case START:     tchEnable = true;  break;\r
248                 case STOP:      tchEnable = false; break;\r
249                 case SET_INT:   tchTmr = interval; break;\r
250             }\r
251         }\r
252     }\r
253     clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
254 }\r
255 \r
256 void clock1_interrupt(){\r
257     static int accCnt;\r
258     static int magCnt;\r
259     static int lgtCnt;\r
260     static int tchCnt;\r
261 \r
262     accCnt++;\r
263     magCnt++;\r
264     lgtCnt++;\r
265     tchCnt++;\r
266 \r
267     // TODO: send data through Serial\r
268     if (lgtEnable && (lgtCnt<0 || lgtCnt>=lgtTmr/TIME_ACCURACY)){\r
269         sendLightInfo();\r
270         lgtCnt = 0;\r
271     }\r
272     if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){\r
273         sendMagInfo();\r
274         magCnt = 0;\r
275     }\r
276     if (tchEnable && (tchCnt<0 || tchCnt>=tchTmr/TIME_ACCURACY)){\r
277         sendTouchInfo();\r
278         tchCnt = 0;\r
279     }\r
280     if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){\r
281         sendAccInfo();\r
282         accCnt = 0;\r
283     }\r
284 }\r
285 \r
286 void sendLightInfo(){\r
287     char frame[MAX_FRAME_LEN];\r
288     float lightData = lightSensor.read();\r
289     packToFrame(frame,LGT_SNS,FLOAT,1,&lightData);\r
290     serial.printf("[LGT] %s\r\n", frame);\r
291     //printHex(frame);\r
292     //serial.printf("[LGT] Light Intensity=%f\r\n", lightSensor.read());\r
293 }\r
294 \r
295 \r
296 void sendTouchInfo(){\r
297     char frame[MAX_FRAME_LEN];\r
298     float touchData[2];\r
299     touchData[0] = touchSensor.readPercentage();\r
300     touchData[1] = touchSensor.readDistance();\r
301     packToFrame(frame,TCH_SNS,FLOAT,2,touchData);\r
302     serial.printf("[TCH] %s\r\n", frame);\r
303     //printHex(frame);\r
304 }\r
305 \r
306 void sendMagInfo(){\r
307     char frame[MAX_FRAME_LEN];\r
308     int magData[3];\r
309     magSensor.getValues(magData, magData+1, magData+2);\r
310     //serial.printf("[MAG] magX=%d magY=%d magZ=%d\r\n",magData[0],magData[1],magData[2]);\r
311     int len = packToFrame(frame,MAG_SNS,INT,3,magData);\r
312     sendFrame(frame, len);\r
313     //memcpy(magData, &frame[3], 2);\r
314     //serial.printf("[MAG] %d\r\n", magData[0]);\r
315     //printHex(frame);\r
316 }\r
317 \r
318 void sendAccInfo(){\r
319     // get acc data\r
320     char frame[MAX_FRAME_LEN];\r
321     float accData[3];\r
322     accData[0] = accSensor.getAccX();\r
323     accData[1] = accSensor.getAccY();\r
324     accData[2] = accSensor.getAccZ();\r
325     packToFrame(frame, ACC_SNS,FLOAT,3,accData);\r
326     serial.printf("[ACC] %s\n\r", frame);\r
327     //int num = int(frame[2]);\r
328     //memcpy(&accZ, &frame[3], 4);\r
329     // send acc data\r
330     //printHex(frame);\r
331 }\r
332 int calDataSize(char dataType){\r
333     switch(dataType){\r
334         case INT:    return 2;\r
335         case LONG:   return 4;\r
336         case FLOAT:  return 4;\r
337         case DOUBLE: return 8;\r
338     }\r
339     return 4;\r
340 }\r
341 \r
342 void printHex(char* frame){\r
343     int dataType = frame[1]&0xE0;\r
344     int dataSize = calDataSize(dataType);\r
345     int dataNum = frame[2];\r
346     for (int i=0; i<4+dataSize*dataNum; i++){\r
347         serial.printf("0x%x ",frame[i]);\r
348     }\r
349     serial.printf("\r\n");\r
350 }\r
351 \r
352 int packToFrame(char* frame, char snsType,char dataType, int dataNum, void* data){\r
353     int dataSize = calDataSize(dataType);\r
354     frame[0] = HEADER;\r
355     frame[1] = (snsType|(dataType<<SNS_BITS));\r
356     frame[2] = dataNum;\r
357     memcpy(frame+3, data, dataSize*dataNum);\r
358     frame[3+dataNum*dataSize]= TAIL;\r
359     frame[4+dataNum*dataSize]= '\0';\r
360     frame[3] = 0x00;\r
361     return (4+dataNum*dataSize);\r
362 }\r
363 \r
364 \r
365 void sendFrame (char* frame, int len){\r
366     for (int i=0; i<len; i++){\r
367         serial.putc(frame[i]);\r
368     }\r
369 }\r