Run a K30 CO2 sensor on a Nordic nRF52DK Board
Fork of mbed-os-example-ble-BatteryLevel by
Diff: source/main.cpp
- Revision:
- 61:a5d14d0a94a1
- Parent:
- 46:6b66d08f304e
- Child:
- 62:e947447e0d8c
--- a/source/main.cpp Wed Apr 04 17:15:08 2018 +0100 +++ b/source/main.cpp Tue May 01 17:45:11 2018 +0000 @@ -18,39 +18,122 @@ #include <mbed.h> #include "ble/BLE.h" #include "ble/Gap.h" -#include "ble/services/BatteryService.h" +#include "k30.h" +#include "nrf_nvic.h" -DigitalOut led1(LED1, 1); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +//I2C i2c(p24 , p25); +I2C i2c(p26, p27); + /** If you want to debug, or see output, uncomment this **/ +//Serial pc(USBTX, USBRX); // tx, rx -const static char DEVICE_NAME[] = "BATTERY"; -static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE}; +/* 7-bit address of the K30 CO2 Sensor */ +const int addr = 0xD0; + +/* keep track of the number of sensor failures */ +static int failures = 0; -static uint8_t batteryLevel = 50; -static BatteryService* batteryServicePtr; +/** Device name, and the Serice UUID **/ +const static char DEVICE_NAME[] = "CO2Sensor"; +static const uint16_t uuid16_list[] = {K30Service::K30_SERVICE_UUID}; +/** random initial level and a Service pointer **/ +static float co2Level = 50.0; +static K30Service* k30ServicePtr; + +/** Event Queue **/ static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); +/** light pattern in a circle **/ +void lightsFwd(){ + led1 = !led1; + wait(.15); + led2 = !led2; + wait(.15); + led4 = !led4; + wait(.15); + led3 = !led3; + wait(.15); +} +/** reverser light pattern **/ +void lightsRev(){ + led1 = !led1; + wait(.15); + led3 = !led3; + wait(.15); + led4 = !led4; + wait(.15); + led2 = !led2; + wait(.15); +} + +/** here we read the sensor **/ +void readSensor(){ + + // register values + char cmd[4] = {0x22, 0x00, 0x08, 0x2A}; + int ack = i2c.write(addr, cmd, 4); + wait(0.5); + char readBuff[4]; + i2c.read(addr, readBuff, 4, false); + int high = readBuff[1]; //high byte for value is 4th byte in packet in the packet + int low = readBuff[2]; //low byte for value is 5th byte in the packet + float CO2 = high*256 + low; //Combine high byte and low byte with this formula to get value + char sum = readBuff[0] + readBuff[1] + readBuff[2]; //Byte addition utilizes overflow + if (sum == readBuff[3] & ack == 0){ + //pc.printf("CO2 value = %f\n", CO2); + k30ServicePtr->updateK30Value(CO2); + if(failures > 0){ + failures--; + } + } else { + //pc.printf("** Sensor Failure **\n"); + failures++; + CO2 = -1; + k30ServicePtr->updateK30Value(CO2); + if(failures > 5){ // Keep track of the number of failures. If more than 5, reboot the board. + i2c.stop(); + for(int x = 0; x < 10; x++){ + lightsRev(); + } + NVIC_SystemReset(); + } + + } +} void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { + //pc.printf("Disconnected!\n"); BLE::Instance().gap().startAdvertising(); } + + void updateSensorValue() { - batteryLevel++; - if (batteryLevel > 100) { - batteryLevel = 20; - } + lightsFwd(); + readSensor(); + wait(1.5); + lightsFwd(); + wait(1.5 - batteryServicePtr->updateBatteryLevel(batteryLevel); + // k30ServicePtr->updateK30Value(co2Level); } - +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) +{ + // pc.printf("Connected!\n"); + BLE::Instance().gap().stopAdvertising(); + eventQueue.call(updateSensorValue); +} void blinkCallback(void) { - led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ - BLE &ble = BLE::Instance(); if (ble.gap().getState().connected) { eventQueue.call(updateSensorValue); + } else { + lightsFwd(); } } @@ -68,11 +151,11 @@ Gap::AddressType_t addr_type; Gap::Address_t address; BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); + //pc.printf("DEVICE MAC ADDRESS: "); for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); + // printf("%02x:", address[i]); } - printf("%02x\r\n", address[0]); + //pc.printf("%02x\r\n", address[0]); } /** @@ -95,9 +178,10 @@ } ble.gap().onDisconnection(disconnectionCallback); + ble.gap().onConnection(connectionCallback); /* Setup primary service */ - batteryServicePtr = new BatteryService(ble, batteryLevel); + k30ServicePtr = new K30Service(ble, co2Level); /* Setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); @@ -107,7 +191,7 @@ ble.gap().setAdvertisingInterval(1000); /* 1000ms */ ble.gap().startAdvertising(); - printMacAddress(); + //printMacAddress(); } void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { @@ -117,13 +201,10 @@ int main() { - eventQueue.call_every(500, blinkCallback); - + eventQueue.call_every(1000, blinkCallback); BLE &ble = BLE::Instance(); ble.onEventsToProcess(scheduleBleEventsProcessing); ble.init(bleInitComplete); - eventQueue.dispatch_forever(); - return 0; }