![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
Diff: main.cpp
- Revision:
- 0:2b49a387e831
diff -r 000000000000 -r 2b49a387e831 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Feb 15 07:52:46 2014 +0000 @@ -0,0 +1,354 @@ +#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(); + } + } + } +} \ No newline at end of file