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
--- /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