(x) > (max) ? (max) : (x))\r
\r
#define MMA8451_I2C_ADDRESS (0x1d<<1) // acc sensor address\r
-#define TIME_ACCURACY 0.01\r
+#define TIME_ACCURACY 0.0005\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 ACC_SNS_DEFAULT 0.01 // default collecting interval in seconds\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
+#pragma pack(1)\r
typedef struct {\r
uint8_t header;\r
struct {\r
} bits;\r
uint8_t count;\r
uint8_t data[];\r
-} __attribute__((__packed__)) state_t;\r
+} state_t;\r
+#pragma pack()\r
\r
// Command Frame Information\r
+#pragma pack(1)\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
+} control_t;\r
+#pragma pack()\r
\r
// Define Devices & Pins\r
MMA8451Q accSensor(PTE25, PTE24, MMA8451_I2C_ADDRESS);\r
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
DigitalOut led1(LED1);\r
DigitalOut led2(LED2);\r
float ledTmr = LED_OUT_DEFAULT;\r
\r
bool accEnable = false;\r
-bool magEnable = true;\r
+bool magEnable = false;\r
bool lgtEnable = false;\r
bool tchEnable = false;\r
-bool a2dEnable = false;\r
+bool a2dEnable = true;\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
int main(void) {\r
// Initialization\r
// Interruption Declarations\r
- clock1.attach(&clock1_interrupt, TIME_ACCURACY); // maximun accuracy be 0.1s\r
+ //clock1.attach(&clock1_interrupt, TIME_ACCURACY); // maximun accuracy be 0.1s\r
serial.attach(&serialRx_interrupt, Serial::RxIrq); // receive interrupt for serialS\r
- serial.baud(115200);\r
+ //serial.baud(115200);\r
+ serial.baud(230400);\r
magSensor.begin();\r
\r
sdma_setup(UART0, 0);\r
\r
printStr("\r\n============= Start of the program ============\r\n");\r
\r
+ int ticks = 0, tocks = 0;\r
while(1){\r
- wait(3);\r
+ ticks = (us_ticker_read()*1E-6) / TIME_ACCURACY;\r
+ if (tocks < ticks) {\r
+ clock1_interrupt();\r
+ tocks++;\r
+ }\r
}\r
}\r
\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
static int tchCnt;\r
static int a2dCnt;\r
static int ledCnt;\r
+ static int sinCnt;\r
\r
- accCnt++;\r
- magCnt++;\r
- lgtCnt++;\r
- tchCnt++;\r
- a2dCnt++;\r
- ledCnt++;\r
+ static float sinAmp = 0.5; // 0..1\r
+ static float sinFreq = 0.25; // Hz\r
+\r
+ // Write A2D output sine wave\r
+ a2dOutput.write(sinAmp*sin(sinCnt * TIME_ACCURACY * (2*PI) * sinFreq)*0.5 + 0.5);\r
\r
// Send data through Serial\r
- if (accEnable && (accCnt<0 || accCnt>=accTmr/TIME_ACCURACY)){\r
+ if (accEnable && accCnt >= (int)(accTmr/TIME_ACCURACY+0.5)){\r
sendAccInfo();\r
accCnt = 0;\r
}\r
- if (magEnable && (magCnt<0 || magCnt>=magTmr/TIME_ACCURACY)){\r
+ if (magEnable && magCnt >= (int)(magTmr/TIME_ACCURACY+0.5)){\r
sendMagInfo();\r
magCnt = 0;\r
}\r
- if (lgtEnable && (lgtCnt<0 || lgtCnt>=lgtTmr/TIME_ACCURACY)){\r
+ if (lgtEnable && lgtCnt >= (int)(lgtTmr/TIME_ACCURACY+0.5)){\r
sendLgtInfo();\r
lgtCnt = 0;\r
}\r
- if (tchEnable && (tchCnt<0 || tchCnt>=tchTmr/TIME_ACCURACY)){\r
+ if (tchEnable && tchCnt >= (int)(tchTmr/TIME_ACCURACY+0.5)){\r
sendTchInfo();\r
tchCnt = 0;\r
}\r
- if (a2dEnable && (a2dCnt<0 || a2dCnt>=a2dTmr/TIME_ACCURACY)){\r
+ if (a2dEnable && a2dCnt >= (int)(a2dTmr/TIME_ACCURACY+0.5)){\r
sendA2dInfo();\r
a2dCnt = 0;\r
}\r
\r
// Toggel LED for debugging\r
- if (ledEnable && (ledCnt<0 || ledCnt>=ledTmr/TIME_ACCURACY)){\r
+ if (ledEnable && ledCnt>=ledTmr/TIME_ACCURACY){\r
led1 = !led1;\r
ledCnt = 0;\r
}\r
\r
+ accCnt++;\r
+ magCnt++;\r
+ lgtCnt++;\r
+ tchCnt++;\r
+ a2dCnt++;\r
+ ledCnt++;\r
+ sinCnt++;\r
+\r
sdma_flush();\r
}\r
\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
\r
void sendA2dInfo(void){\r
float a2dData[6];\r
- a2dData[0] = 0;\r
- a2dData[1] = 0;\r
- a2dData[2] = 0;\r
- a2dData[3] = 0;\r
- a2dData[4] = 0;\r
- a2dData[5] = 0;\r
- int len = packToFrame(txFrame, A2D_SNS, FLOAT, 6, a2dData);\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
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