Reading SenseAir LP8 CO2 sensor over bluetooth low energy
Dependencies: BLE_API mbed nRF51822
main.cpp@2:d02255d8c36f, 2017-08-14 (annotated)
- Committer:
- jony1401
- Date:
- Mon Aug 14 20:52:48 2017 +0000
- Revision:
- 2:d02255d8c36f
- Parent:
- 1:b512a405b584
- Child:
- 3:933dd59ad44d
v2.0
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:d02255d8c36f | 6 | //Sensor and ble Configuration parameters |
jony1401 | 2:d02255d8c36f | 7 | #define SENSOR_TIMER 20.0 //lp8 polling interval (seconds) |
jony1401 | 2:d02255d8c36f | 8 | #define BLE_ADV_INTERVAL 500 //advertisment interval (milliseconds) |
jony1401 | 2:d02255d8c36f | 9 | #define BACKGROUND_CALIBRATION_TIME 180 //timer to do background calibration (seconds) |
jony1401 | 2:d02255d8c36f | 10 | |
jony1401 | 2:d02255d8c36f | 11 | |
jony1401 | 2:d02255d8c36f | 12 | |
jony1401 | 0:ee3787c8e209 | 13 | //setup ble stack |
jony1401 | 0:ee3787c8e209 | 14 | BLE ble; //BLE object |
jony1401 | 0:ee3787c8e209 | 15 | |
jony1401 | 2:d02255d8c36f | 16 | // setup Pins |
jony1401 | 2:d02255d8c36f | 17 | DigitalOut Res(P0_0, 1); //reset, pull Low for reset |
jony1401 | 2:d02255d8c36f | 18 | DigitalIn RDY(P0_10); //rdy |
jony1401 | 2:d02255d8c36f | 19 | DigitalOut VBB_EN(P0_5, 0); //set to low at startup |
jony1401 | 0:ee3787c8e209 | 20 | Serial Device(P0_9, P0_11); //tx, rx |
jony1401 | 2:d02255d8c36f | 21 | |
jony1401 | 2:d02255d8c36f | 22 | // Timers |
jony1401 | 0:ee3787c8e209 | 23 | Timer lp8Wait; //timer for sensor communication |
jony1401 | 2:d02255d8c36f | 24 | Timer bCalibration; //timer for background calibration |
jony1401 | 0:ee3787c8e209 | 25 | |
jony1401 | 0:ee3787c8e209 | 26 | |
jony1401 | 2:d02255d8c36f | 27 | //BLE device name and uuid list setup |
jony1401 | 0:ee3787c8e209 | 28 | const static char DEVICE_NAME[] = "SenseAir LP8"; |
jony1401 | 0:ee3787c8e209 | 29 | static const uint16_t uuid16_list[] = {LP8_Service::LP8_SERVICE_UUID}; |
jony1401 | 0:ee3787c8e209 | 30 | |
jony1401 | 0:ee3787c8e209 | 31 | |
jony1401 | 2:d02255d8c36f | 32 | //check for sensor triggering and uppdating the GattServer |
jony1401 | 2:d02255d8c36f | 33 | bool triggerSensor = false; //sensor polling flag |
jony1401 | 2:d02255d8c36f | 34 | bool doCalibration = false; //background calibration flag |
jony1401 | 2:d02255d8c36f | 35 | |
jony1401 | 2:d02255d8c36f | 36 | LP8_Service *lp8ServicePtr; //pointer to lp8 BLE service object |
jony1401 | 2:d02255d8c36f | 37 | uint8_t ccByte = 0x20; //calculation control byte to LP8 |
jony1401 | 0:ee3787c8e209 | 38 | |
jony1401 | 0:ee3787c8e209 | 39 | |
jony1401 | 0:ee3787c8e209 | 40 | |
jony1401 | 0:ee3787c8e209 | 41 | //**************************** ble functions ******************************* |
jony1401 | 0:ee3787c8e209 | 42 | // on Disconnect, Restart BroadCasting |
jony1401 | 0:ee3787c8e209 | 43 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
jony1401 | 0:ee3787c8e209 | 44 | { |
jony1401 | 1:b512a405b584 | 45 | //turn of sensor at ble disconnect |
jony1401 | 1:b512a405b584 | 46 | VBB_EN.write( 0 ); |
jony1401 | 0:ee3787c8e209 | 47 | //restart broadcast |
jony1401 | 0:ee3787c8e209 | 48 | ble.gap().startAdvertising(); |
jony1401 | 0:ee3787c8e209 | 49 | } |
jony1401 | 2:d02255d8c36f | 50 | //sensor polling interupt |
jony1401 | 0:ee3787c8e209 | 51 | void triggerSensorPollingInterupt() |
jony1401 | 0:ee3787c8e209 | 52 | { |
jony1401 | 0:ee3787c8e209 | 53 | triggerSensor = true; |
jony1401 | 0:ee3787c8e209 | 54 | }; |
jony1401 | 2:d02255d8c36f | 55 | //app interupt for calibration... |
jony1401 | 2:d02255d8c36f | 56 | void calibrationCallback(const GattWriteCallbackParams *eventData) |
jony1401 | 2:d02255d8c36f | 57 | { |
jony1401 | 2:d02255d8c36f | 58 | ccByte = eventData-> data[0]; |
jony1401 | 2:d02255d8c36f | 59 | doCalibration = true; |
jony1401 | 2:d02255d8c36f | 60 | } |
jony1401 | 0:ee3787c8e209 | 61 | |
jony1401 | 0:ee3787c8e209 | 62 | |
jony1401 | 0:ee3787c8e209 | 63 | |
jony1401 | 2:d02255d8c36f | 64 | //**************************** main ************************************** |
jony1401 | 2:d02255d8c36f | 65 | int main() |
jony1401 | 0:ee3787c8e209 | 66 | { |
jony1401 | 1:b512a405b584 | 67 | wait(1); |
jony1401 | 2:d02255d8c36f | 68 | |
jony1401 | 0:ee3787c8e209 | 69 | |
jony1401 | 0:ee3787c8e209 | 70 | Ticker lp8Timer; //timer object for sensor polling interupts |
jony1401 | 2:d02255d8c36f | 71 | |
jony1401 | 2:d02255d8c36f | 72 | //timer callback |
jony1401 | 2:d02255d8c36f | 73 | lp8Timer.attach(&triggerSensorPollingInterupt, SENSOR_TIMER); //trigger sensor reading every X sec |
jony1401 | 2:d02255d8c36f | 74 | |
jony1401 | 2:d02255d8c36f | 75 | ble.init(); |
jony1401 | 2:d02255d8c36f | 76 | |
jony1401 | 2:d02255d8c36f | 77 | //disconnect callback |
jony1401 | 2:d02255d8c36f | 78 | ble.gap().onDisconnection( disconnectionCallback ); //do callback if ble disconnect |
jony1401 | 2:d02255d8c36f | 79 | //on data recevied callback |
jony1401 | 2:d02255d8c36f | 80 | ble.onDataWritten( calibrationCallback ); //trigger for calibration control |
jony1401 | 2:d02255d8c36f | 81 | |
jony1401 | 2:d02255d8c36f | 82 | //************************ LP8 variables ********************************* |
jony1401 | 2:d02255d8c36f | 83 | int co2Value = 400; //initial CO2 value |
jony1401 | 2:d02255d8c36f | 84 | double tempValue = 20.0; //init temp value |
jony1401 | 2:d02255d8c36f | 85 | int Vcap = 3000; //mV |
jony1401 | 2:d02255d8c36f | 86 | uint32_t errorFlag = 0; //error bits from lp8 |
jony1401 | 0:ee3787c8e209 | 87 | |
jony1401 | 2:d02255d8c36f | 88 | //************************ Checks ********************************* |
jony1401 | 2:d02255d8c36f | 89 | bool initCheck = true; //check for init sensor state |
jony1401 | 2:d02255d8c36f | 90 | bool successCheck = false; //check for sensor communication |
jony1401 | 2:d02255d8c36f | 91 | |
jony1401 | 2:d02255d8c36f | 92 | //************************ Calculation control bytes ******************** |
jony1401 | 2:d02255d8c36f | 93 | // uint8_t sM = 0x20; //lp8 calculation control byte using Subesquent Measurments mode |
jony1401 | 2:d02255d8c36f | 94 | // uint8_t bC = 0x52; //Background Calibration using unfilterd data + reset filters |
jony1401 | 2:d02255d8c36f | 95 | |
jony1401 | 2:d02255d8c36f | 96 | |
jony1401 | 2:d02255d8c36f | 97 | //setup LP8 object |
jony1401 | 2:d02255d8c36f | 98 | LP8 lp8(Device, VBB_EN, RDY, Res, lp8Wait); //pass pins: serial, vbb, rdy, res, timer |
jony1401 | 2:d02255d8c36f | 99 | |
jony1401 | 2:d02255d8c36f | 100 | //Setup GattService |
jony1401 | 2:d02255d8c36f | 101 | LP8_Service lp8Service(ble, co2Value, tempValue, |
jony1401 | 2:d02255d8c36f | 102 | Vcap, errorFlag, ccByte); // |
jony1401 | 2:d02255d8c36f | 103 | lp8ServicePtr = &lp8Service; // |
jony1401 | 0:ee3787c8e209 | 104 | |
jony1401 | 0:ee3787c8e209 | 105 | |
jony1401 | 2:d02255d8c36f | 106 | // setup ble advertising parameters |
jony1401 | 0:ee3787c8e209 | 107 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); //general bluetooth information(only support for ble |
jony1401 | 0:ee3787c8e209 | 108 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); //service list |
jony1401 | 0:ee3787c8e209 | 109 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
jony1401 | 0:ee3787c8e209 | 110 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
jony1401 | 1:b512a405b584 | 111 | ble.gap().setAdvertisingInterval(BLE_ADV_INTERVAL); /* advertising interval in ms. */ |
jony1401 | 1:b512a405b584 | 112 | ble.gap().startAdvertising(); //start broadcast |
jony1401 | 0:ee3787c8e209 | 113 | |
jony1401 | 2:d02255d8c36f | 114 | // Wait for initialization to complete. |
jony1401 | 2:d02255d8c36f | 115 | while (ble.hasInitialized() == false) { |
jony1401 | 2:d02255d8c36f | 116 | /* spin loop */ |
jony1401 | 2:d02255d8c36f | 117 | } |
jony1401 | 0:ee3787c8e209 | 118 | |
jony1401 | 0:ee3787c8e209 | 119 | |
jony1401 | 0:ee3787c8e209 | 120 | |
jony1401 | 2:d02255d8c36f | 121 | //*************************** start the main loop *********************************** |
jony1401 | 0:ee3787c8e209 | 122 | while ( true ) |
jony1401 | 0:ee3787c8e209 | 123 | { |
jony1401 | 1:b512a405b584 | 124 | if(triggerSensor && ble.gap().getState().connected ) //trigger when timer interupts and there is an established ble connection |
jony1401 | 0:ee3787c8e209 | 125 | { |
jony1401 | 0:ee3787c8e209 | 126 | if ( initCheck ) { |
jony1401 | 2:d02255d8c36f | 127 | |
jony1401 | 1:b512a405b584 | 128 | successCheck = lp8.lp8Init(); //initialize talking with the lp8 (first call on startup) |
jony1401 | 0:ee3787c8e209 | 129 | |
jony1401 | 1:b512a405b584 | 130 | if ( successCheck ) { |
jony1401 | 0:ee3787c8e209 | 131 | initCheck = false; |
jony1401 | 1:b512a405b584 | 132 | } |
jony1401 | 0:ee3787c8e209 | 133 | } |
jony1401 | 2:d02255d8c36f | 134 | /* |
jony1401 | 2:d02255d8c36f | 135 | else if ( doCalibration && ccByte == bC ){ |
jony1401 | 2:d02255d8c36f | 136 | lp8.lp8Talk( bC ); //do background calibration |
jony1401 | 2:d02255d8c36f | 137 | bCalibration.start(); |
jony1401 | 2:d02255d8c36f | 138 | if( bCalibration.read() >= BACKGROUND_CALIBRATION_TIME ){ |
jony1401 | 2:d02255d8c36f | 139 | bCalibration.stop(); |
jony1401 | 2:d02255d8c36f | 140 | bCalibration.reset(); |
jony1401 | 2:d02255d8c36f | 141 | doCalibration = false; |
jony1401 | 2:d02255d8c36f | 142 | ccByte = 0xff; |
jony1401 | 2:d02255d8c36f | 143 | } |
jony1401 | 2:d02255d8c36f | 144 | } |
jony1401 | 2:d02255d8c36f | 145 | */ |
jony1401 | 0:ee3787c8e209 | 146 | else { |
jony1401 | 2:d02255d8c36f | 147 | lp8.lp8Talk( ccByte ); //Communication with lp8, pass Calculation control byte |
jony1401 | 0:ee3787c8e209 | 148 | } |
jony1401 | 2:d02255d8c36f | 149 | |
jony1401 | 1:b512a405b584 | 150 | //reset polling check |
jony1401 | 1:b512a405b584 | 151 | triggerSensor = false; |
jony1401 | 0:ee3787c8e209 | 152 | |
jony1401 | 2:d02255d8c36f | 153 | //update the gattServer |
jony1401 | 2:d02255d8c36f | 154 | lp8ServicePtr->updateCo2Value( lp8.getValue() ); //get CO2 value |
jony1401 | 2:d02255d8c36f | 155 | lp8ServicePtr->updateTempValue( lp8.getTempValue() ); // |
jony1401 | 2:d02255d8c36f | 156 | lp8ServicePtr->updateVcapValue( lp8.getVcapValue() ); // |
jony1401 | 2:d02255d8c36f | 157 | lp8ServicePtr->updateError( lp8.getErrorStatus() ); // |
jony1401 | 2:d02255d8c36f | 158 | lp8ServicePtr->updateDataWritten( lp8.getCCbyte() ); //send back the calculation control byte that was used in LP8 measurement |
jony1401 | 0:ee3787c8e209 | 159 | } |
jony1401 | 0:ee3787c8e209 | 160 | |
jony1401 | 1:b512a405b584 | 161 | else { ble.waitForEvent(); } //ble save energy |
jony1401 | 0:ee3787c8e209 | 162 | } |
jony1401 | 0:ee3787c8e209 | 163 | |
jony1401 | 0:ee3787c8e209 | 164 | }; |
jony1401 | 0:ee3787c8e209 | 165 |