Reading SenseAir LP8 CO2 sensor over bluetooth low energy

Dependencies:   BLE_API mbed nRF51822

Committer:
jony1401
Date:
Mon Jun 05 11:10:28 2017 +0000
Revision:
1:b512a405b584
Parent:
0:ee3787c8e209
Child:
2:d02255d8c36f
Reading Senseair LP8 CO2 sensor over bluetooth low energy with readbearlabs ble nano.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jony1401 0:ee3787c8e209 1 #include "mbed.h"
jony1401 0:ee3787c8e209 2 #include "BLE.h"
jony1401 0:ee3787c8e209 3 #include "LP8_Service.h"
jony1401 0:ee3787c8e209 4 #include "LP8.h"
jony1401 0:ee3787c8e209 5
jony1401 0:ee3787c8e209 6 //setup ble stack
jony1401 0:ee3787c8e209 7 BLE ble; //BLE object
jony1401 0:ee3787c8e209 8
jony1401 0:ee3787c8e209 9 // Pins and timers needed for lp8 communication
jony1401 1:b512a405b584 10 DigitalIn RDY(P0_5); //
jony1401 1:b512a405b584 11 DigitalOut VBB_EN(P0_29, 0); //set to low at startup
jony1401 0:ee3787c8e209 12 Serial Device(P0_9, P0_11); //tx, rx
jony1401 0:ee3787c8e209 13 Timer lp8Wait; //timer for sensor communication
jony1401 0:ee3787c8e209 14
jony1401 0:ee3787c8e209 15
jony1401 0:ee3787c8e209 16
jony1401 0:ee3787c8e209 17 //Sensor and ble Configuration parameters
jony1401 1:b512a405b584 18 #define SENSOR_TIMER 20.0 //lp8 polling interval (seconds)
jony1401 1:b512a405b584 19 #define BLE_ADV_INTERVAL 1000 //advertisment interval (milliseconds)
jony1401 0:ee3787c8e209 20
jony1401 0:ee3787c8e209 21
jony1401 0:ee3787c8e209 22
jony1401 0:ee3787c8e209 23 //device name and uuid list setup
jony1401 0:ee3787c8e209 24 const static char DEVICE_NAME[] = "SenseAir LP8";
jony1401 0:ee3787c8e209 25 static const uint16_t uuid16_list[] = {LP8_Service::LP8_SERVICE_UUID};
jony1401 0:ee3787c8e209 26
jony1401 0:ee3787c8e209 27
jony1401 0:ee3787c8e209 28 //check for sensor triggering and uppdating Gatt Server
jony1401 1:b512a405b584 29 bool triggerSensor = false; //check for sensor polling, used with interupt
jony1401 0:ee3787c8e209 30 LP8_Service *lp8ServicePtr; //pointer to lp8 service object
jony1401 0:ee3787c8e209 31
jony1401 0:ee3787c8e209 32
jony1401 0:ee3787c8e209 33
jony1401 0:ee3787c8e209 34 //**************************** ble functions *******************************
jony1401 0:ee3787c8e209 35 // on Disconnect, Restart BroadCasting
jony1401 0:ee3787c8e209 36 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
jony1401 0:ee3787c8e209 37 {
jony1401 1:b512a405b584 38 //turn of sensor at ble disconnect
jony1401 1:b512a405b584 39 VBB_EN.write( 0 );
jony1401 0:ee3787c8e209 40 //restart broadcast
jony1401 0:ee3787c8e209 41 ble.gap().startAdvertising();
jony1401 0:ee3787c8e209 42 }
jony1401 1:b512a405b584 43 //timer function callback
jony1401 0:ee3787c8e209 44 void triggerSensorPollingInterupt()
jony1401 0:ee3787c8e209 45 {
jony1401 0:ee3787c8e209 46 triggerSensor = true;
jony1401 0:ee3787c8e209 47 };
jony1401 0:ee3787c8e209 48
jony1401 0:ee3787c8e209 49
jony1401 0:ee3787c8e209 50
jony1401 0:ee3787c8e209 51 //main
jony1401 0:ee3787c8e209 52 int main(void)
jony1401 0:ee3787c8e209 53 {
jony1401 1:b512a405b584 54 wait(1);
jony1401 0:ee3787c8e209 55
jony1401 0:ee3787c8e209 56 Ticker lp8Timer; //timer object for sensor polling interupts
jony1401 0:ee3787c8e209 57 lp8Timer.attach(&triggerSensorPollingInterupt, SENSOR_TIMER); //trigger sensor reading every X.Y sec
jony1401 0:ee3787c8e209 58
jony1401 0:ee3787c8e209 59 ble.init();
jony1401 0:ee3787c8e209 60 ble.gap().onDisconnection(disconnectionCallback); //do callback if disconnection occurs
jony1401 0:ee3787c8e209 61
jony1401 0:ee3787c8e209 62
jony1401 1:b512a405b584 63 int co2Value = 400; //initial CO2 value to display
jony1401 1:b512a405b584 64 bool initCheck = true; //check for init sensor state (or lost state)
jony1401 1:b512a405b584 65 bool successCheck = false; //check for sensor communication
jony1401 1:b512a405b584 66 //calibration control bytes for the lp 8
jony1401 1:b512a405b584 67 uint8_t subsequentMeasurement = 0x20; //lp8 calculation control byte for subs. measurements
jony1401 1:b512a405b584 68 uint8_t noResetABC = 0x70; //abc calibration byte with no reset on filters
jony1401 1:b512a405b584 69 uint8_t resetABC = 0x72; //abc calibration AND resets filters
jony1401 1:b512a405b584 70 uint8_t backgroundCalibration = 0x52; //background calibration using unfilterd data + resets filters
jony1401 0:ee3787c8e209 71
jony1401 1:b512a405b584 72 //setup LP8 object
jony1401 1:b512a405b584 73 LP8 lp8(Device, VBB_EN, RDY, lp8Wait); //constructor needs 4 arguments
jony1401 0:ee3787c8e209 74
jony1401 0:ee3787c8e209 75
jony1401 0:ee3787c8e209 76 //setup for GattService
jony1401 0:ee3787c8e209 77 /* Setup Gatt server */
jony1401 0:ee3787c8e209 78 LP8_Service lp8Service(ble, co2Value); //pass in ble object and initial co2 value
jony1401 0:ee3787c8e209 79 lp8ServicePtr = &lp8Service; //set pointer to "real" lp8 service object
jony1401 0:ee3787c8e209 80
jony1401 0:ee3787c8e209 81
jony1401 1:b512a405b584 82 /* setup ble advertising parameters */
jony1401 0:ee3787c8e209 83 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); //general bluetooth information(only support for ble
jony1401 0:ee3787c8e209 84 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); //service list
jony1401 0:ee3787c8e209 85 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
jony1401 0:ee3787c8e209 86 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jony1401 1:b512a405b584 87 ble.gap().setAdvertisingInterval(BLE_ADV_INTERVAL); /* advertising interval in ms. */
jony1401 1:b512a405b584 88 ble.gap().startAdvertising(); //start broadcast
jony1401 0:ee3787c8e209 89
jony1401 1:b512a405b584 90 /* SpinWait for initialization to complete. */
jony1401 0:ee3787c8e209 91 while (ble.hasInitialized() == false) { /* spin loop */ }
jony1401 0:ee3787c8e209 92
jony1401 0:ee3787c8e209 93
jony1401 0:ee3787c8e209 94
jony1401 1:b512a405b584 95 //start the main loop
jony1401 0:ee3787c8e209 96 while ( true )
jony1401 0:ee3787c8e209 97 {
jony1401 1:b512a405b584 98 if(triggerSensor && ble.gap().getState().connected ) //trigger when timer interupts and there is an established ble connection
jony1401 0:ee3787c8e209 99 {
jony1401 0:ee3787c8e209 100 if ( initCheck ) {
jony1401 1:b512a405b584 101 successCheck = lp8.lp8Init(); //initialize talking with the lp8 (first call on startup)
jony1401 0:ee3787c8e209 102
jony1401 1:b512a405b584 103 if ( successCheck ) {
jony1401 0:ee3787c8e209 104 initCheck = false;
jony1401 1:b512a405b584 105 }
jony1401 0:ee3787c8e209 106 }
jony1401 0:ee3787c8e209 107 else {
jony1401 1:b512a405b584 108 lp8.lp8Talk( subsequentMeasurement ); //Communication with the lp8, sends calculation control: 0x20 == subs. talks
jony1401 0:ee3787c8e209 109 }
jony1401 1:b512a405b584 110 //reset polling check
jony1401 1:b512a405b584 111 triggerSensor = false;
jony1401 0:ee3787c8e209 112
jony1401 1:b512a405b584 113 //update the gattServer with new CO2 value
jony1401 0:ee3787c8e209 114 lp8ServicePtr->updateCo2Value( lp8.getValue() );
jony1401 0:ee3787c8e209 115 }
jony1401 0:ee3787c8e209 116
jony1401 1:b512a405b584 117 else { ble.waitForEvent(); } //ble save energy
jony1401 0:ee3787c8e209 118 }
jony1401 0:ee3787c8e209 119
jony1401 0:ee3787c8e209 120 };
jony1401 0:ee3787c8e209 121