]> Pileus Git - ~andy/csm213a-hw/blobdiff - yue/main.cpp
Pull changes from Yue
[~andy/csm213a-hw] / yue / main.cpp
index 5b82803062bc8f9865ece13ebef0cbabd8b78540..d3addb1e679d7b004e67ff01d77631c11b91a32b 100644 (file)
-#include "mbed.h"
-#include "TSISensor.h"          // Touch Sensor
-#include "MAG3110.h"            // Magnetic Sensor
-#include "MMA8451Q.h"           // AcceleroMeter
-
-
-#define MMA8451_I2C_ADDRESS (0x1d<<1)   // acc sensor address
-#define TIME_ACCURACY 0.1
-#define LIGHT_SNS_DEFAULT 1             // default collecting interval in seconds
-#define ACC_SNS_DEFAULT 1
-#define MAG_SNS_DEFAULT 1
-#define TOUCH_SNS_DEFAULT 1
-
-// Define Devices & Pins
-MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);
-TSISensor touchSensor;
-MAG3110 magSensor(PTE25, PTE24);
-Serial serial(USBTX, USBRX);
-Ticker clock1;
-AnalogIn lightSensor(PTE22);
-
-
-// Global Variables
-// Initial interval: in seconds
-float lightTmr = LIGHT_SNS_DEFAULT;
-float accTmr = ACC_SNS_DEFAULT;
-float magTmr = MAG_SNS_DEFAULT;
-float touchTmr = TOUCH_SNS_DEFAULT;
-
-bool lightEnable = true;
-bool accEnable = true;
-bool magEnable = true;
-bool touchEnable = true;
-
-void clock1_interrupt();
-void serialRx_interrupt();
-void sendLightInfo();
-void sendAccInfo();
-void sendMagInfo();
-void sendTouchInfo();
-
-
-int main() {
-    // Initialization
-    // Interruption Declarations
-    clock1.attach(&clock1_interrupt, TIME_ACCURACY);    // maximun accuracy be 0.1s
-    serial.attach(&serialRx_interrupt, Serial::RxIrq);  // receive interrupt for serialS
-    serial.baud(921600);
-    magSensor.begin();
-
-    serial.printf("\r\n============= Start of the program ============\r\n");
-    while(1){
-        wait(3);
-    }
-}
-
-
-/*---------------------------------------------------------------
-  ## Receive Interruption of the Serial ##
-  -> used to receive & process user command
-  -> and configure the board accordingly
-  ---------------------------------------------------------------*/
-void serialRx_interrupt(){
-    clock1.detach();                // close the interrupt
-    serial.printf("\r\n");
-
-    // Receive the Serial Input
-    float interval;
-    char buffer[255];
-    char temp[255];
-    char ch = serial.getc();
-    int i;
-    for (i=0 ; ch!='\n' && ch!='\r'; i++){
-        serial.putc(ch);
-        buffer[i] = ch;
-        if (ch==127){                // BackSpace
-            i--;
-            i--;
-        }
-        ch = serial.getc();
-    }
-    buffer[i] = '\0';
-    serial.printf("\r\nBUFFER: %s %d\r\n", buffer,i);
-    // TODO: buffer -> lower case
-
-    // Process the Serial Input
-    // Set-Interval Command
-    if (strstr(buffer, "set")!=NULL && strstr(buffer, "int")!= NULL){
-        sscanf(buffer, "%*[^0123456789.]%s", temp);       // find the number in buffer
-        sscanf(temp, "%f", &interval);                    // translate into float
-        if (interval<0.1 || interval>5){
-            interval  = 1;
-        }
-        if (strstr(buffer, "acc")){
-            accTmr = interval;
-        }
-        if (strstr(buffer, "mag")){
-            magTmr = interval;
-        }
-        if (strstr(buffer, "light")){
-            lightTmr = interval;
-        }
-        if (strstr(buffer, "touch")){
-            touchTmr = interval;
-        }
-    }
-
-    // Stop Command
-    else if (strstr(buffer, "stop")!= NULL){
-        serial.printf("STOP\r\n");
-        if (strstr(buffer, "acc")){
-            accEnable = false;
-            accTmr = ACC_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "mag")){
-            magEnable = false;
-            magTmr = MAG_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "light")){
-            lightEnable = false;
-            lightTmr = LIGHT_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "touch")){
-            touchEnable = false;
-            touchTmr = TOUCH_SNS_DEFAULT;
-        }
-    }
-
-    // Start Command
-    else if (strstr(buffer, "start")!=NULL){
-        if (strstr(buffer, "acc") && !accEnable){
-            accEnable = true;
-            accTmr = ACC_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "mag") && !magEnable){
-            magEnable = true;
-            magTmr = MAG_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "light") && !lightEnable){
-            lightEnable = true;
-            lightTmr = LIGHT_SNS_DEFAULT;
-        }
-        if (strstr(buffer, "touch") && !touchEnable){
-            touchEnable = true;
-            touchTmr = TOUCH_SNS_DEFAULT;
-        }
-    }
-    clock1.attach(&clock1_interrupt,0.1);
-}
-
-
-void clock1_interrupt(){
-    static int accCnt;
-    static int magCnt;
-    static int lightCnt;
-    static int touchCnt;
-
-    accCnt++;
-    magCnt++;
-    lightCnt++;
-    touchCnt++;
-
-    // TODO: send data through Serial
-    if (lightEnable && (lightCnt<0 || lightCnt>=lightTmr/TIME_ACCURACY)){
-        sendLightInfo();
-        lightCnt = 0;
-    }
-    if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){
-        sendMagInfo();
-        magCnt = 0;
-    }
-    if (touchEnable && (touchCnt<0 || touchCnt>=touchTmr/TIME_ACCURACY)){
-        sendTouchInfo();
-        touchCnt = 0;
-    }
-    if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){
-        sendAccInfo();
-        accCnt = 0;
-    }
-}
-
-void sendLightInfo(){
-    serial.printf("[LGT] Light Intensity=%f\r\n", lightSensor.read());
-}
-
-
-void sendAccInfo(){
-    // get acc data
-    float accX = accSensor.getAccX();
-    float accY = accSensor.getAccY();
-    float accZ = accSensor.getAccZ();
-
-    // send acc data
-    serial.printf("[ACC] accX=%-2.4f accY=%-2.4f accZ=%-2.4f\r\n",accX,accY,accZ);
-}
-
-void sendTouchInfo(){
-    // get data
-    float touchForce = touchSensor.readPercentage();
-    float distance = touchSensor.readDistance();
-
-    // send data
-    serial.printf("[TCH] Force=%0.4f Distance=%2.2f\r\n", touchForce, distance);
-}
-
-void sendMagInfo(){
-    // get data
-    int magX, magY, magZ;
-    magSensor.getValues(&magX, &magY, &magZ);
-
-    // send data
-    serial.printf("[MAG] magX=%d magY=%d magZ=%d\r\n",magX,magY,magZ);
-}
+#include "mbed.h"\r
+#include "TSISensor.h"          // Touch Sensor\r
+#include "MAG3110.h"            // Magnetic Sensor\r
+#include "MMA8451Q.h"           // AcceleroMeter\r
+//#include "DataFrame.h"\r
+\r
+\r
+\r
+#define MMA8451_I2C_ADDRESS (0x1d<<1)   // acc sensor address\r
+#define TIME_ACCURACY     0.1\r
+#define LGT_SNS_DEFAULT   2             // default collecting interval in seconds\r
+#define ACC_SNS_DEFAULT   2\r
+#define MAG_SNS_DEFAULT   2\r
+#define TCH_SNS_DEFAULT   2\r
+\r
+// Parameters in Data Frame\r
+// TODO: need to sync with the pc program\r
+\r
+#define HEADER    0x02\r
+\r
+#define SNS_BITS  5\r
+#define LGT_SNS   0x00\r
+#define ACC_SNS   0x01\r
+#define MAG_SNS   0x02\r
+#define TCH_SNS   0x03\r
+#define ADC_SNS_1 0x04\r
+\r
+#define INT    0\r
+#define LONG   1\r
+#define FLOAT  2\r
+#define DOUBLE 3\r
+#define TAIL   0x0A             // '\n'\r
+\r
+// Command Frame\r
+#define START   0\r
+#define STOP    1\r
+#define SET_INT 2\r
+\r
+\r
+\r
+#define MAX_FRAME_LEN 255\r
+// Define Devices & Pins\r
+MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);\r
+TSISensor touchSensor;\r
+MAG3110 magSensor(PTE25, PTE24);\r
+Serial serial(USBTX, USBRX);\r
+Ticker clock1;\r
+AnalogIn lightSensor(PTE22);\r
+\r
+\r
+// Global Variables\r
+// Initial interval: in seconds\r
+float lgtTmr = LGT_SNS_DEFAULT;\r
+float accTmr = ACC_SNS_DEFAULT;\r
+float magTmr = MAG_SNS_DEFAULT;\r
+float tchTmr = TCH_SNS_DEFAULT;\r
+\r
+bool lgtEnable = false;\r
+bool accEnable = false;\r
+bool magEnable = true;\r
+bool tchEnable = false;\r
+\r
+void clock1_interrupt();\r
+void serialRx_interrupt();\r
+void sendLightInfo();\r
+void sendAccInfo();\r
+void sendMagInfo();\r
+void sendTouchInfo();\r
+int packToFrame(char*, char, char, int, void*);\r
+char* floatToByte(float);\r
+float byteToFloat(char*);\r
+int calDataSize(char);\r
+void printHex(char*);\r
+void sendFrame(char*, int);\r
+\r
+\r
+int main() {\r
+    // Initialization\r
+    // Interruption Declarations\r
+    clock1.attach(&clock1_interrupt, TIME_ACCURACY);    // maximun accuracy be 0.1s\r
+    serial.attach(&serialRx_interrupt, Serial::RxIrq);  // receive interrupt for serialS\r
+    magSensor.begin();\r
+\r
+    serial.printf("\r\n============= Start of the program ============\r\n");\r
+    while(1){\r
+        wait(3);\r
+    }\r
+}\r
+\r
+\r
+/*---------------------------------------------------------------\r
+  ## Receive Interruption of the Serial ##\r
+  -> used to receive & process user command\r
+  -> and configure the board accordingly\r
+  ---------------------------------------------------------------*/\r
+/*void serialRx_interrupt_userFriendlyVersion(){\r
+    clock1.detach();                // close the interrupt\r
+    serial.printf("\r\n");\r
+\r
+    // Receive the Serial Input\r
+    float interval;\r
+    char buffer[255];\r
+    char temp[255];\r
+    char ch = serial.getc();\r
+    int i;\r
+    for (i=0 ; ch!='\n' && ch!='\r'; i++){\r
+        serial.putc(ch);\r
+        buffer[i] = ch;\r
+        if (ch==127){                // BackSpace\r
+            i--;\r
+            i--;\r
+        }\r
+        ch = serial.getc();\r
+    }\r
+    buffer[i] = '\0';\r
+    serial.printf("\r\nBUFFER: %s %d\r\n", buffer,i);\r
+    // TODO: buffer -> lower case\r
+\r
+    // Process the Serial Input\r
+    // Set-Interval Command\r
+    if (strstr(buffer, "set")!=NULL && strstr(buffer, "int")!= NULL){\r
+        sscanf(buffer, "%*[^0123456789.]%s", temp);       // find the number in buffer\r
+        sscanf(temp, "%f", &interval);                    // translate into float\r
+        if (interval<0.1 || interval>5){\r
+            interval  = 1;\r
+        }\r
+        if (strstr(buffer, "acc")){\r
+            accTmr = interval;\r
+        }\r
+        if (strstr(buffer, "mag")){\r
+            magTmr = interval;\r
+        }\r
+        if (strstr(buffer, "light")){\r
+            lgtTmr = interval;\r
+        }\r
+        if (strstr(buffer, "touch")){\r
+            tchTmr = interval;\r
+        }\r
+    }\r
+\r
+    // Stop Command\r
+    else if (strstr(buffer, "stop")!= NULL){\r
+        serial.printf("STOP\r\n");\r
+        if (strstr(buffer, "acc")){\r
+            accEnable = false;\r
+            accTmr = ACC_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "mag")){\r
+            magEnable = false;\r
+            magTmr = MAG_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "light")){\r
+            lgtEnable = false;\r
+            lgtTmr = LGT_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "touch")){\r
+            tchEnable = false;\r
+            tchTmr = TCH_SNS_DEFAULT;\r
+        }\r
+    }\r
+\r
+    // Start Command\r
+    else if (strstr(buffer, "start")!=NULL){\r
+        if (strstr(buffer, "acc") && !accEnable){\r
+            accEnable = true;\r
+            accTmr = ACC_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "mag") && !magEnable){\r
+            magEnable = true;\r
+            magTmr = MAG_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "light") && !lgtEnable){\r
+            lgtEnable = true;\r
+            lgtTmr = LGT_SNS_DEFAULT;\r
+        }\r
+        if (strstr(buffer, "touch") && !tchEnable){\r
+            tchEnable = true;\r
+            tchTmr = TCH_SNS_DEFAULT;\r
+        }\r
+    }\r
+    clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
+}\r
+*/\r
+\r
+void serialRx_interrupt(){                          // Byte version\r
+    clock1.detach();                                // close the interrupt temporarily\r
+    int i = 0;\r
+    char frame[MAX_FRAME_LEN];\r
+    char ch = serial.getc();\r
+    while (ch!=HEADER){\r
+        if (serial.readable()){\r
+            ch = serial.getc();\r
+        }\r
+        else{\r
+            serial.printf("[ERROR] broken data!\r\n");\r
+            clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
+            return;\r
+        }\r
+    }\r
+    //TODO: ticker for time out\r
+    while (serial.readable()){\r
+        frame[i] = ch;\r
+        if (ch=='\n'){\r
+            break;\r
+        }\r
+        ch = serial.getc();\r
+        i++;\r
+    }\r
+    frame[++i] = '\0';\r
+    float interval=-1;\r
+    char snsType = frame[1]|0x1F;\r
+    char oper = (frame[1]|0xE0)>>SNS_BITS;              // operation type\r
+    if (oper==SET_INT){\r
+        memcpy(&interval,&frame[2],4);\r
+        if (interval<0.0001||interval>10){\r
+            interval = 1;\r
+        }\r
+    }\r
+    switch(snsType){\r
+        case ACC_SNS:\r
+        {\r
+            switch(oper){\r
+                case START:     accEnable = true;  break;\r
+                case STOP:      accEnable = false; break;\r
+                case SET_INT:   accTmr = interval; break;\r
+            }\r
+        }\r
+        case MAG_SNS:\r
+        {\r
+            switch(oper){\r
+                case START:     magEnable = true;  break;\r
+                case STOP:      magEnable = false; break;\r
+                case SET_INT:   magTmr = interval; break;\r
+            }\r
+        }\r
+        case LGT_SNS:\r
+        {\r
+            switch(oper){\r
+                case START:     lgtEnable = true;  break;\r
+                case STOP:      lgtEnable = false; break;\r
+                case SET_INT:   lgtTmr = interval; break;\r
+            }\r
+        }\r
+        case TCH_SNS:\r
+        {\r
+            switch(oper){\r
+                case START:     tchEnable = true;  break;\r
+                case STOP:      tchEnable = false; break;\r
+                case SET_INT:   tchTmr = interval; break;\r
+            }\r
+        }\r
+    }\r
+    clock1.attach(&clock1_interrupt,TIME_ACCURACY);\r
+}\r
+\r
+void clock1_interrupt(){\r
+    static int accCnt;\r
+    static int magCnt;\r
+    static int lgtCnt;\r
+    static int tchCnt;\r
+\r
+    accCnt++;\r
+    magCnt++;\r
+    lgtCnt++;\r
+    tchCnt++;\r
+\r
+    // TODO: send data through Serial\r
+    if (lgtEnable && (lgtCnt<0 || lgtCnt>=lgtTmr/TIME_ACCURACY)){\r
+        sendLightInfo();\r
+        lgtCnt = 0;\r
+    }\r
+    if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){\r
+        sendMagInfo();\r
+        magCnt = 0;\r
+    }\r
+    if (tchEnable && (tchCnt<0 || tchCnt>=tchTmr/TIME_ACCURACY)){\r
+        sendTouchInfo();\r
+        tchCnt = 0;\r
+    }\r
+    if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){\r
+        sendAccInfo();\r
+        accCnt = 0;\r
+    }\r
+}\r
+\r
+void sendLightInfo(){\r
+    char frame[MAX_FRAME_LEN];\r
+    float lightData = lightSensor.read();\r
+    packToFrame(frame,LGT_SNS,FLOAT,1,&lightData);\r
+    serial.printf("[LGT] %s\r\n", frame);\r
+    //printHex(frame);\r
+    //serial.printf("[LGT] Light Intensity=%f\r\n", lightSensor.read());\r
+}\r
+\r
+\r
+void sendTouchInfo(){\r
+    char frame[MAX_FRAME_LEN];\r
+    float touchData[2];\r
+    touchData[0] = touchSensor.readPercentage();\r
+    touchData[1] = touchSensor.readDistance();\r
+    packToFrame(frame,TCH_SNS,FLOAT,2,touchData);\r
+    serial.printf("[TCH] %s\r\n", frame);\r
+    //printHex(frame);\r
+}\r
+\r
+void sendMagInfo(){\r
+    char frame[MAX_FRAME_LEN];\r
+    int magData[3];\r
+    magSensor.getValues(magData, magData+1, magData+2);\r
+    //serial.printf("[MAG] magX=%d magY=%d magZ=%d\r\n",magData[0],magData[1],magData[2]);\r
+    int len = packToFrame(frame,MAG_SNS,INT,3,magData);\r
+    sendFrame(frame, len);\r
+    //memcpy(magData, &frame[3], 2);\r
+    //serial.printf("[MAG] %d\r\n", magData[0]);\r
+    //printHex(frame);\r
+}\r
+\r
+void sendAccInfo(){\r
+    // get acc data\r
+    char frame[MAX_FRAME_LEN];\r
+    float accData[3];\r
+    accData[0] = accSensor.getAccX();\r
+    accData[1] = accSensor.getAccY();\r
+    accData[2] = accSensor.getAccZ();\r
+    packToFrame(frame, ACC_SNS,FLOAT,3,accData);\r
+    serial.printf("[ACC] %s\n\r", frame);\r
+    //int num = int(frame[2]);\r
+    //memcpy(&accZ, &frame[3], 4);\r
+    // send acc data\r
+    //printHex(frame);\r
+}\r
+int calDataSize(char 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
+    }\r
+    return 4;\r
+}\r
+\r
+void printHex(char* frame){\r
+    int dataType = frame[1]&0xE0;\r
+    int dataSize = calDataSize(dataType);\r
+    int dataNum = frame[2];\r
+    for (int i=0; i<4+dataSize*dataNum; i++){\r
+        serial.printf("0x%x ",frame[i]);\r
+    }\r
+    serial.printf("\r\n");\r
+}\r
+\r
+int packToFrame(char* frame, char snsType,char dataType, int dataNum, void* data){\r
+    int dataSize = calDataSize(dataType);\r
+    frame[0] = HEADER;\r
+    frame[1] = (snsType|(dataType<<SNS_BITS));\r
+    frame[2] = dataNum;\r
+    memcpy(frame+3, data, dataSize*dataNum);\r
+    frame[3+dataNum*dataSize]= TAIL;\r
+    frame[4+dataNum*dataSize]= '\0';\r
+    frame[3] = 0x00;\r
+    return (4+dataNum*dataSize);\r
+}\r
+\r
+\r
+void sendFrame (char* frame, int len){\r
+    for (int i=0; i<len; i++){\r
+        serial.putc(frame[i]);\r
+    }\r
+}\r