Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822
Fork of SenseAirLP8 by
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 | 
