configure sensors on FRDM KL46Z and send data through Serial port. Need host(PC) software to interact with. Sampling rate can vary by proper instruction
Dependencies: EventFramework mbed
main.cpp
- Committer:
- xmnan
- Date:
- 2014-02-15
- Revision:
- 0:2b49a387e831
File content as of revision 0:2b49a387e831:
#include "mbed.h" #include "TSISensor.h" #include "MMA8451Q.h" #include "MAG3110.h" #include "EventFramework/EventFramework.h" #include <cstdlib> #define OFF 0 #define ON 1 #define DEBUG PwmOut rled(PTE29); PwmOut gled(PTD5); Serial pc(USBTX, USBRX); MMA8451Q acc51(PTE25, PTE24, 0x1D<<1); MAG3110 mag(PTE25, PTE24); AnalogIn lightSensor(PTE22); TSISensor tsi; AnalogIn sinewave(PTB1); // labels for different data channel char MAG_X = 0x00; char MAG_Y = 0x01; char MAG_Z = 0x02; char MAG_H = 0x03; char ACC_X = 0x04; char ACC_Y = 0x05; char ACC_Z = 0x06; char LIT_X = 0x07; char TOU_X = 0x08; char SIN_X = 0x09; int MAG_STATUS = OFF; int ACCL_STATUS = OFF; int LIGHT_STATUS = OFF; int TOUCH_STATUS = OFF; int SINE_STATUS = OFF; Timer t1; Timer t2; Timer t3; Timer t4; Timer t5; //time threshold, equals to 1/sampling_rate int interval1 = 10000; int interval2 = 10000; int interval3 = 10000; int interval4 = 10000; int interval5 = 10000; // framework creation with cooperative scheduling mechanism. EventFramework kernel(EventFramework::SCHED_VALUE_COOPERATIVE); // Events creation Event accl_Evt(0); Event mag_Evt(0); Event light_Evt(0); Event touch_Evt(0); Event sine_Evt(0); // EventHandlers creation EventHandler eh_accl(0); EventHandler eh_mag(0); EventHandler eh_light(0); EventHandler eh_touch(0); EventHandler eh_sine(0); // declaration of event dispatching functions that will be attached to previous EventHandlers EventDispatchingRoutine ev_accl_handle_func; EventDispatchingRoutine ev_mag_handle_func; EventDispatchingRoutine ev_light_handle_func; EventDispatchingRoutine ev_touch_handle_func; EventDispatchingRoutine ev_sine_handle_func; int START = OFF; void sendint(char label,int x){ char *p = (char *)&x; pc.putc(label); pc.putc(*p); pc.putc(*(p+1)); pc.putc(*(p+2)); pc.putc(*(p+3)); } void sendfloat(char label,float x){ char *p = (char *)&x; pc.putc(label); pc.putc(*p); pc.putc(*(p+1)); pc.putc(*(p+2)); pc.putc(*(p+3)); } void calXY() //magnetometer calibration: finding max and min of X, Y axis { int tempXmax, tempXmin, tempYmax, tempYmin, newX, newY; rled = ON; printf("Waiting for initial press\n"); // Wait for slider to be pressed while( tsi.readDistance() == 0 ) { rled = ON; wait(0.2); rled = OFF; wait(0.2); } printf("Waiting for release\n"); // Wait for release while( tsi.readDistance() != 0 ) { rled = OFF; wait(0.2); rled = ON; wait(0.2); } rled = OFF; wait(0.5); printf("Rotate\n"); tempXmax = tempXmin = mag.readVal(MAG_OUT_X_MSB); tempYmax = tempYmin = mag.readVal(MAG_OUT_Y_MSB); while(tsi.readDistance() == 0) { gled = ON; wait(0.1); gled = OFF; wait(0.1); newX = mag.readVal(MAG_OUT_X_MSB); newY = mag.readVal(MAG_OUT_Y_MSB); if (newX > tempXmax) tempXmax = newX; if (newX < tempXmin) tempXmin = newX; if (newY > tempYmax) tempYmax = newY; if (newY < tempYmin) tempYmin = newY; } mag.setCalibration( tempXmin, tempXmax, tempYmin, tempYmax ); // Wait for release while( tsi.readDistance() != 0 ) { gled = OFF; wait(0.2); gled = ON; wait(0.2); } gled = OFF; wait(1.0); } uint32_t ev_accl_handle_func(void* me, void* args){ float temp_x = acc51.getAccX(); float temp_y = acc51.getAccY(); float temp_z = acc51.getAccZ(); __disable_irq(); sendfloat(ACC_X,temp_x); sendfloat(ACC_Y,temp_y); sendfloat(ACC_Z,temp_z); __enable_irq(); } uint32_t ev_mag_handle_func(void* me, void* args){ int temp_x = 0, temp_y = 0, temp_z = 0; float temp_h = mag.getHeading(); mag.getValues(&temp_x, &temp_y, &temp_z); __disable_irq(); sendint(MAG_X,temp_x); sendint(MAG_Y,temp_y); sendint(MAG_Z,temp_z); sendfloat(MAG_H,temp_h); __enable_irq(); } uint32_t ev_light_handle_func(void* me, void* args){ float temp_x = lightSensor; __disable_irq(); sendfloat(LIT_X,temp_x); __enable_irq(); } uint32_t ev_touch_handle_func(void* me, void* args){ float temp_x = tsi.readPercentage();; __disable_irq(); sendfloat(TOU_X,temp_x); __enable_irq(); } uint32_t ev_sine_handle_func(void* me, void* args){ float temp_x = sinewave.read();; __disable_irq(); sendfloat(SIN_X,temp_x); __enable_irq(); } void pc_command(){ kernel.SaveContext(); char command = pc.getc(); float sr; char temp[4]; switch(command) { case 0xEE : // configuration or reconfiguration header command = pc.getc(); if (command == 0x01){ // check the status of magnetometer MAG_STATUS = ON;// turn it on temp[0] = pc.getc(); temp[1] = pc.getc(); temp[2] = pc.getc(); temp[3] = pc.getc(); sr = *(float*)temp;//sampling rate interval1 =(int) 1/sr *1000;//threshold t1.reset();//timer reset } else{ MAG_STATUS = OFF;//turn it off t1.stop(); } command = pc.getc(); if (command == 0x01){ // check the status of accelerometer ACCL_STATUS = ON; temp[0] = pc.getc(); temp[1] = pc.getc(); temp[2] = pc.getc(); temp[3] = pc.getc(); sr = *(float*)temp; interval2 =(int) 1/sr *1000; t2.reset(); } else{ ACCL_STATUS = OFF; t2.stop(); } command = pc.getc(); if (command == 0x01){ // check the status of the light sensor LIGHT_STATUS = ON; temp[0] = pc.getc(); temp[1] = pc.getc(); temp[2] = pc.getc(); temp[3] = pc.getc(); sr = *(float*)temp; interval3 =(int) 1/sr *1000; t3.reset(); } else{ LIGHT_STATUS = OFF; t3.stop(); } command = pc.getc(); if (command == 0x01){ // check the status of the touch sensor TOUCH_STATUS = ON; temp[0] = pc.getc(); temp[1] = pc.getc(); temp[2] = pc.getc(); temp[3] = pc.getc(); sr = *(float*)temp; interval4 =(int) 1/sr *1000; t4.reset(); } else{ TOUCH_STATUS = OFF; t4.stop(); } command = pc.getc(); if (command == 0x01){ // check the status of the sine wave receiver SINE_STATUS = ON; temp[0] = pc.getc(); temp[1] = pc.getc(); temp[2] = pc.getc(); temp[3] = pc.getc(); sr = *(float*)temp; interval5 =(int) 1/sr *1000; t5.reset(); } else{ SINE_STATUS = OFF; t5.stop(); } START = ON; rled = ON; break; } kernel.RestoreContext(); } int main() { // events must be registered into the framework kernel.AddEvent(&mag_Evt); kernel.AddEvent(&accl_Evt); kernel.AddEvent(&light_Evt); kernel.AddEvent(&touch_Evt); kernel.AddEvent(&sine_Evt); eh_mag.Attach(&ev_mag_handle_func); eh_accl.Attach(&ev_accl_handle_func); eh_light.Attach(&ev_light_handle_func); eh_touch.Attach(&ev_touch_handle_func); eh_sine.Attach(&ev_sine_handle_func); // handlers are registered into the kernel to listen to specific events. [eh1] listens to [ev1], [eh2] listens to [ev2]. kernel.AddEventListener(&mag_Evt, &eh_mag); kernel.AddEventListener(&accl_Evt, &eh_accl); kernel.AddEventListener(&light_Evt, &eh_light); kernel.AddEventListener(&touch_Evt, &eh_touch); kernel.AddEventListener(&sine_Evt, &eh_sine); calXY(); pc.attach(&pc_command); while(START == OFF){ pc.putc(0xFF); } pc.putc(0xFE); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); // the event-driven kernel starts its operation. while(1) { kernel.Schedule(); if (MAG_STATUS == ON){ if (t1.read_ms()>interval1){ kernel.PublishEvent(&mag_Evt, 0); t1.reset(); } } if (ACCL_STATUS == ON){ if (t2.read_ms()>interval2){ kernel.PublishEvent(&accl_Evt, 0); t2.reset(); } } if (LIGHT_STATUS == ON){ if (t3.read_ms()>interval3){ kernel.PublishEvent(&light_Evt, 0); t3.reset(); } } if (TOUCH_STATUS == ON){ if (t4.read_ms()>interval4){ kernel.PublishEvent(&touch_Evt, 0); t4.reset(); } } if (SINE_STATUS == ON){ if (t5.read_ms()>interval5){ kernel.PublishEvent(&sine_Evt, 0); t5.reset(); } } } }