Reading SenseAir LP8 CO2 sensor over bluetooth low energy

Dependencies:   BLE_API mbed nRF51822

main.cpp

Committer:
jony1401
Date:
2017-08-18
Revision:
3:933dd59ad44d
Parent:
2:d02255d8c36f

File content as of revision 3:933dd59ad44d:

#include "mbed.h"
#include "BLE.h"
#include "LP8_Service.h"
#include "LP8.h"

//Sensor and ble Configuration parameters
#define     SENSOR_TIMER                        16.0                                    //lp8 polling interval (seconds)
#define     BLE_ADV_INTERVAL                    500                                     //advertisment interval (milliseconds)


//setup ble stack
BLE             ble;                                                                    //BLE object

// setup Pins 
DigitalOut      Res(P0_0, 1);                                                           //reset, pull Low for reset
DigitalIn       RDY(P0_10);                                                             //rdy
DigitalOut      VBB_EN(P0_5, 0);                                                        //set to low at startup
Serial          Device(P0_9, P0_11);                                                    //tx, rx

// Timers
Timer           lp8Wait;                                                                //timer for sensor communication
Ticker          lp8Timer;                                                               //timer object for sensor polling 

//BLE device name and uuid list setup
const static char       DEVICE_NAME[] = "SenseAir LP8";
static const uint16_t   uuid16_list[] = {LP8_Service::LP8_SERVICE_UUID};

//check for sensor triggering
bool                    triggerSensor = false;                                          //sensor polling flag
bool                    doCalibration = false;                                          //background calibration flag
bool                    initCheck     = true;                                           //check for init sensor state

LP8_Service             *lp8ServicePtr;                                                 //

uint8_t                 ccByte = 0x20;                                                  //calculation control byte to LP8




//****************************   ble callback functions      ***************************
// on Disconnect interupt
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    initCheck = true;
    //turn of sensor at ble disconnect
    VBB_EN.write( 0 );
    //cancel sensor timer
    lp8Timer.detach();
    
    //restart broadcast
    ble.gap().startAdvertising();
}
//sensor polling 
void triggerSensorPollingInterupt()
{
    triggerSensor = true;
      
    //reset callback timer
    lp8Timer.detach();
    lp8Timer.attach(&triggerSensorPollingInterupt, SENSOR_TIMER);
    
};

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    lp8Timer.attach( triggerSensorPollingInterupt, 4 );
}

//on BLE data written
void calibrationCallback(const GattWriteCallbackParams *eventData)
{
    doCalibration = true;
    ccByte = eventData-> data[0];
}



//****************************     main      **************************************
int main()
{
    wait(1); 

    ble.init();
    
    //callbacks
    ble.gap().onConnection( connectionCallback );
    ble.gap().onDisconnection( disconnectionCallback );                                  //
    ble.gattServer().onDataWritten( calibrationCallback );                               //

//************************     LP8 variables      *********************************
    int                     co2Value    = 99;                                            //initial CO2 value
    float                   tempValue   = 99;                                            //init temp value
    int                     Vcap        = 99;                                            //mV    
    uint32_t                errorFlag   = 0;                                             //error bits from lp8
    uint8_t                 sentCCbyte  = 0x99;
    

//setup LP8 object 
LP8                  *lp8 = new LP8(Device, VBB_EN, RDY, Res, lp8Wait);    

     
//Setup GattService
//    LP8_Service      lp8Service(ble, co2Value, tempValue, 
 //                    Vcap, errorFlag, ccByte, sentCCbyte);                              
    lp8ServicePtr     = new LP8_Service(ble, co2Value, tempValue, 
                     Vcap, errorFlag, ccByte, sentCCbyte);                              // lp8Service;                                                    


// setup ble advertising parameters 
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);            //general bluetooth information(only support for ble
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); //service list
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(BLE_ADV_INTERVAL);                                 /* advertising interval in ms. */
    ble.gap().startAdvertising();                                                       
    
// Wait for initialization to complete.
    while (ble.hasInitialized()  == false) { 
    /* spin loop */ 
    }



//***************************     start the main loop      ***********************************
    while ( true ) 
    {

        if(triggerSensor && ble.gap().getState().connected )                            //trigger when timer interupts and there is an established ble connection
        {
            if ( initCheck ) {
                lp8->responsePurge(50);                                                  //purge buffer
                if ( lp8->lp8Init() != true ) {
                    //initCheck = true;
                    }
                else {
                    initCheck = false;                   
                    
                }                                                          
           }
          
            else if ( lp8->lp8Talk( ccByte ) != true ) {
                //restart with init sequence if sensor state is lost or communication fails
                initCheck = true;
                ccByte = 0xff;                                                          //app error flag
            }
                        
            //reset polling check
            triggerSensor = false;
            
            //update the gattServer characteristic values
            lp8ServicePtr->updateCo2Value( lp8->getValue() );                            //get CO2 value
            lp8ServicePtr->updateTempValue( lp8->getTempValue() );                       //
            lp8ServicePtr->updateVcapValue( lp8->getVcapValue() );                       //
            lp8ServicePtr->updateError( lp8->getErrorStatus() );                         //
            lp8ServicePtr->updateDataWritten( lp8->getCCbyte() );                        //send back the calculation control byte that was used in LP8 measurement
            lp8ServicePtr->updateReWrite( ccByte ); 
            
            //reset calibration control
            ccByte = 0x20;      /* resets to 0x20 (subs. talk) after one sample.
            Check lp8Talk() function. */                                                         
        }
        
        else { ble.waitForEvent(); }                                                    //ble save energy
    }
    
};