Run a K30 CO2 sensor on a Nordic nRF52DK Board

Fork of mbed-os-example-ble-BatteryLevel by mbed-os-examples

Committer:
davidgsIoT
Date:
Tue May 01 17:45:11 2018 +0000
Revision:
61:a5d14d0a94a1
Parent:
46:6b66d08f304e
Child:
62:e947447e0d8c
Run a K30 CO2 Sensor on a Nordic nRF52DK board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 4:52bffaff7f0b 1 /* mbed Microcontroller Library
mbed_official 4:52bffaff7f0b 2 * Copyright (c) 2006-2014 ARM Limited
mbed_official 4:52bffaff7f0b 3 *
mbed_official 4:52bffaff7f0b 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 4:52bffaff7f0b 5 * you may not use this file except in compliance with the License.
mbed_official 4:52bffaff7f0b 6 * You may obtain a copy of the License at
mbed_official 4:52bffaff7f0b 7 *
mbed_official 4:52bffaff7f0b 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 4:52bffaff7f0b 9 *
mbed_official 4:52bffaff7f0b 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 4:52bffaff7f0b 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 4:52bffaff7f0b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 4:52bffaff7f0b 13 * See the License for the specific language governing permissions and
mbed_official 4:52bffaff7f0b 14 * limitations under the License.
mbed_official 4:52bffaff7f0b 15 */
mbed_official 4:52bffaff7f0b 16
mbed_official 13:eaa1343657a8 17 #include <events/mbed_events.h>
mbed_official 4:52bffaff7f0b 18 #include <mbed.h>
mbed_official 4:52bffaff7f0b 19 #include "ble/BLE.h"
mbed_official 4:52bffaff7f0b 20 #include "ble/Gap.h"
davidgsIoT 61:a5d14d0a94a1 21 #include "k30.h"
davidgsIoT 61:a5d14d0a94a1 22 #include "nrf_nvic.h"
mbed_official 4:52bffaff7f0b 23
davidgsIoT 61:a5d14d0a94a1 24 DigitalOut led1(LED1);
davidgsIoT 61:a5d14d0a94a1 25 DigitalOut led2(LED2);
davidgsIoT 61:a5d14d0a94a1 26 DigitalOut led3(LED3);
davidgsIoT 61:a5d14d0a94a1 27 DigitalOut led4(LED4);
davidgsIoT 61:a5d14d0a94a1 28 //I2C i2c(p24 , p25);
davidgsIoT 61:a5d14d0a94a1 29 I2C i2c(p26, p27);
davidgsIoT 61:a5d14d0a94a1 30 /** If you want to debug, or see output, uncomment this **/
davidgsIoT 61:a5d14d0a94a1 31 //Serial pc(USBTX, USBRX); // tx, rx
mbed_official 4:52bffaff7f0b 32
davidgsIoT 61:a5d14d0a94a1 33 /* 7-bit address of the K30 CO2 Sensor */
davidgsIoT 61:a5d14d0a94a1 34 const int addr = 0xD0;
davidgsIoT 61:a5d14d0a94a1 35
davidgsIoT 61:a5d14d0a94a1 36 /* keep track of the number of sensor failures */
davidgsIoT 61:a5d14d0a94a1 37 static int failures = 0;
mbed_official 4:52bffaff7f0b 38
davidgsIoT 61:a5d14d0a94a1 39 /** Device name, and the Serice UUID **/
davidgsIoT 61:a5d14d0a94a1 40 const static char DEVICE_NAME[] = "CO2Sensor";
davidgsIoT 61:a5d14d0a94a1 41 static const uint16_t uuid16_list[] = {K30Service::K30_SERVICE_UUID};
mbed_official 4:52bffaff7f0b 42
davidgsIoT 61:a5d14d0a94a1 43 /** random initial level and a Service pointer **/
davidgsIoT 61:a5d14d0a94a1 44 static float co2Level = 50.0;
davidgsIoT 61:a5d14d0a94a1 45 static K30Service* k30ServicePtr;
davidgsIoT 61:a5d14d0a94a1 46
davidgsIoT 61:a5d14d0a94a1 47 /** Event Queue **/
mbed_official 29:7a6aff8c9468 48 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
mbed_official 4:52bffaff7f0b 49
davidgsIoT 61:a5d14d0a94a1 50 /** light pattern in a circle **/
davidgsIoT 61:a5d14d0a94a1 51 void lightsFwd(){
davidgsIoT 61:a5d14d0a94a1 52 led1 = !led1;
davidgsIoT 61:a5d14d0a94a1 53 wait(.15);
davidgsIoT 61:a5d14d0a94a1 54 led2 = !led2;
davidgsIoT 61:a5d14d0a94a1 55 wait(.15);
davidgsIoT 61:a5d14d0a94a1 56 led4 = !led4;
davidgsIoT 61:a5d14d0a94a1 57 wait(.15);
davidgsIoT 61:a5d14d0a94a1 58 led3 = !led3;
davidgsIoT 61:a5d14d0a94a1 59 wait(.15);
davidgsIoT 61:a5d14d0a94a1 60 }
davidgsIoT 61:a5d14d0a94a1 61 /** reverser light pattern **/
davidgsIoT 61:a5d14d0a94a1 62 void lightsRev(){
davidgsIoT 61:a5d14d0a94a1 63 led1 = !led1;
davidgsIoT 61:a5d14d0a94a1 64 wait(.15);
davidgsIoT 61:a5d14d0a94a1 65 led3 = !led3;
davidgsIoT 61:a5d14d0a94a1 66 wait(.15);
davidgsIoT 61:a5d14d0a94a1 67 led4 = !led4;
davidgsIoT 61:a5d14d0a94a1 68 wait(.15);
davidgsIoT 61:a5d14d0a94a1 69 led2 = !led2;
davidgsIoT 61:a5d14d0a94a1 70 wait(.15);
davidgsIoT 61:a5d14d0a94a1 71 }
davidgsIoT 61:a5d14d0a94a1 72
davidgsIoT 61:a5d14d0a94a1 73 /** here we read the sensor **/
davidgsIoT 61:a5d14d0a94a1 74 void readSensor(){
davidgsIoT 61:a5d14d0a94a1 75
davidgsIoT 61:a5d14d0a94a1 76 // register values
davidgsIoT 61:a5d14d0a94a1 77 char cmd[4] = {0x22, 0x00, 0x08, 0x2A};
davidgsIoT 61:a5d14d0a94a1 78 int ack = i2c.write(addr, cmd, 4);
davidgsIoT 61:a5d14d0a94a1 79 wait(0.5);
davidgsIoT 61:a5d14d0a94a1 80 char readBuff[4];
davidgsIoT 61:a5d14d0a94a1 81 i2c.read(addr, readBuff, 4, false);
davidgsIoT 61:a5d14d0a94a1 82 int high = readBuff[1]; //high byte for value is 4th byte in packet in the packet
davidgsIoT 61:a5d14d0a94a1 83 int low = readBuff[2]; //low byte for value is 5th byte in the packet
davidgsIoT 61:a5d14d0a94a1 84 float CO2 = high*256 + low; //Combine high byte and low byte with this formula to get value
davidgsIoT 61:a5d14d0a94a1 85 char sum = readBuff[0] + readBuff[1] + readBuff[2]; //Byte addition utilizes overflow
davidgsIoT 61:a5d14d0a94a1 86 if (sum == readBuff[3] & ack == 0){
davidgsIoT 61:a5d14d0a94a1 87 //pc.printf("CO2 value = %f\n", CO2);
davidgsIoT 61:a5d14d0a94a1 88 k30ServicePtr->updateK30Value(CO2);
davidgsIoT 61:a5d14d0a94a1 89 if(failures > 0){
davidgsIoT 61:a5d14d0a94a1 90 failures--;
davidgsIoT 61:a5d14d0a94a1 91 }
davidgsIoT 61:a5d14d0a94a1 92 } else {
davidgsIoT 61:a5d14d0a94a1 93 //pc.printf("** Sensor Failure **\n");
davidgsIoT 61:a5d14d0a94a1 94 failures++;
davidgsIoT 61:a5d14d0a94a1 95 CO2 = -1;
davidgsIoT 61:a5d14d0a94a1 96 k30ServicePtr->updateK30Value(CO2);
davidgsIoT 61:a5d14d0a94a1 97 if(failures > 5){ // Keep track of the number of failures. If more than 5, reboot the board.
davidgsIoT 61:a5d14d0a94a1 98 i2c.stop();
davidgsIoT 61:a5d14d0a94a1 99 for(int x = 0; x < 10; x++){
davidgsIoT 61:a5d14d0a94a1 100 lightsRev();
davidgsIoT 61:a5d14d0a94a1 101 }
davidgsIoT 61:a5d14d0a94a1 102 NVIC_SystemReset();
davidgsIoT 61:a5d14d0a94a1 103 }
davidgsIoT 61:a5d14d0a94a1 104
davidgsIoT 61:a5d14d0a94a1 105 }
davidgsIoT 61:a5d14d0a94a1 106 }
mbed_official 4:52bffaff7f0b 107 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
mbed_official 4:52bffaff7f0b 108 {
davidgsIoT 61:a5d14d0a94a1 109 //pc.printf("Disconnected!\n");
mbed_official 4:52bffaff7f0b 110 BLE::Instance().gap().startAdvertising();
mbed_official 4:52bffaff7f0b 111 }
mbed_official 4:52bffaff7f0b 112
davidgsIoT 61:a5d14d0a94a1 113
davidgsIoT 61:a5d14d0a94a1 114
mbed_official 4:52bffaff7f0b 115 void updateSensorValue() {
davidgsIoT 61:a5d14d0a94a1 116 lightsFwd();
davidgsIoT 61:a5d14d0a94a1 117 readSensor();
davidgsIoT 61:a5d14d0a94a1 118 wait(1.5);
davidgsIoT 61:a5d14d0a94a1 119 lightsFwd();
davidgsIoT 61:a5d14d0a94a1 120 wait(1.5
mbed_official 4:52bffaff7f0b 121
davidgsIoT 61:a5d14d0a94a1 122 // k30ServicePtr->updateK30Value(co2Level);
mbed_official 4:52bffaff7f0b 123 }
davidgsIoT 61:a5d14d0a94a1 124 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
davidgsIoT 61:a5d14d0a94a1 125 {
davidgsIoT 61:a5d14d0a94a1 126 // pc.printf("Connected!\n");
davidgsIoT 61:a5d14d0a94a1 127 BLE::Instance().gap().stopAdvertising();
davidgsIoT 61:a5d14d0a94a1 128 eventQueue.call(updateSensorValue);
davidgsIoT 61:a5d14d0a94a1 129 }
mbed_official 4:52bffaff7f0b 130 void blinkCallback(void)
mbed_official 4:52bffaff7f0b 131 {
mbed_official 4:52bffaff7f0b 132 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 133 if (ble.gap().getState().connected) {
mbed_official 13:eaa1343657a8 134 eventQueue.call(updateSensorValue);
davidgsIoT 61:a5d14d0a94a1 135 } else {
davidgsIoT 61:a5d14d0a94a1 136 lightsFwd();
mbed_official 4:52bffaff7f0b 137 }
mbed_official 4:52bffaff7f0b 138 }
mbed_official 4:52bffaff7f0b 139
mbed_official 4:52bffaff7f0b 140 /**
mbed_official 4:52bffaff7f0b 141 * This function is called when the ble initialization process has failled
mbed_official 4:52bffaff7f0b 142 */
mbed_official 4:52bffaff7f0b 143 void onBleInitError(BLE &ble, ble_error_t error)
mbed_official 4:52bffaff7f0b 144 {
mbed_official 4:52bffaff7f0b 145 /* Initialization error handling should go here */
mbed_official 4:52bffaff7f0b 146 }
mbed_official 4:52bffaff7f0b 147
mbed_official 46:6b66d08f304e 148 void printMacAddress()
mbed_official 46:6b66d08f304e 149 {
mbed_official 46:6b66d08f304e 150 /* Print out device MAC address to the console*/
mbed_official 46:6b66d08f304e 151 Gap::AddressType_t addr_type;
mbed_official 46:6b66d08f304e 152 Gap::Address_t address;
mbed_official 46:6b66d08f304e 153 BLE::Instance().gap().getAddress(&addr_type, address);
davidgsIoT 61:a5d14d0a94a1 154 //pc.printf("DEVICE MAC ADDRESS: ");
mbed_official 46:6b66d08f304e 155 for (int i = 5; i >= 1; i--){
davidgsIoT 61:a5d14d0a94a1 156 // printf("%02x:", address[i]);
mbed_official 46:6b66d08f304e 157 }
davidgsIoT 61:a5d14d0a94a1 158 //pc.printf("%02x\r\n", address[0]);
mbed_official 46:6b66d08f304e 159 }
mbed_official 46:6b66d08f304e 160
mbed_official 4:52bffaff7f0b 161 /**
mbed_official 4:52bffaff7f0b 162 * Callback triggered when the ble initialization process has finished
mbed_official 4:52bffaff7f0b 163 */
mbed_official 4:52bffaff7f0b 164 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
mbed_official 4:52bffaff7f0b 165 {
mbed_official 4:52bffaff7f0b 166 BLE& ble = params->ble;
mbed_official 4:52bffaff7f0b 167 ble_error_t error = params->error;
mbed_official 4:52bffaff7f0b 168
mbed_official 4:52bffaff7f0b 169 if (error != BLE_ERROR_NONE) {
mbed_official 4:52bffaff7f0b 170 /* In case of error, forward the error handling to onBleInitError */
mbed_official 4:52bffaff7f0b 171 onBleInitError(ble, error);
mbed_official 4:52bffaff7f0b 172 return;
mbed_official 4:52bffaff7f0b 173 }
mbed_official 4:52bffaff7f0b 174
mbed_official 4:52bffaff7f0b 175 /* Ensure that it is the default instance of BLE */
mbed_official 4:52bffaff7f0b 176 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
mbed_official 4:52bffaff7f0b 177 return;
mbed_official 4:52bffaff7f0b 178 }
mbed_official 4:52bffaff7f0b 179
mbed_official 4:52bffaff7f0b 180 ble.gap().onDisconnection(disconnectionCallback);
davidgsIoT 61:a5d14d0a94a1 181 ble.gap().onConnection(connectionCallback);
mbed_official 4:52bffaff7f0b 182
mbed_official 4:52bffaff7f0b 183 /* Setup primary service */
davidgsIoT 61:a5d14d0a94a1 184 k30ServicePtr = new K30Service(ble, co2Level);
mbed_official 4:52bffaff7f0b 185
mbed_official 4:52bffaff7f0b 186 /* Setup advertising */
mbed_official 4:52bffaff7f0b 187 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbed_official 4:52bffaff7f0b 188 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
mbed_official 4:52bffaff7f0b 189 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
mbed_official 4:52bffaff7f0b 190 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbed_official 4:52bffaff7f0b 191 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
mbed_official 4:52bffaff7f0b 192 ble.gap().startAdvertising();
mbed_official 46:6b66d08f304e 193
davidgsIoT 61:a5d14d0a94a1 194 //printMacAddress();
mbed_official 4:52bffaff7f0b 195 }
mbed_official 4:52bffaff7f0b 196
mbed_official 4:52bffaff7f0b 197 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 4:52bffaff7f0b 198 BLE &ble = BLE::Instance();
mbed_official 13:eaa1343657a8 199 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 4:52bffaff7f0b 200 }
mbed_official 4:52bffaff7f0b 201
mbed_official 4:52bffaff7f0b 202 int main()
mbed_official 4:52bffaff7f0b 203 {
davidgsIoT 61:a5d14d0a94a1 204 eventQueue.call_every(1000, blinkCallback);
mbed_official 4:52bffaff7f0b 205 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 206 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 4:52bffaff7f0b 207 ble.init(bleInitComplete);
mbed_official 13:eaa1343657a8 208 eventQueue.dispatch_forever();
mbed_official 4:52bffaff7f0b 209 return 0;
mbed_official 4:52bffaff7f0b 210 }