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