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();
}
}
}
}