mbed code for UberVest health monitoring
Dependencies: BLE_API mbed nRF51822
main.cpp@7:7e1a474ca416, 2016-01-13 (annotated)
- Committer:
- haydenball
- Date:
- Wed Jan 13 21:36:17 2016 +0000
- Revision:
- 7:7e1a474ca416
- Parent:
- 6:808cfc0b9480
Final Changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
haydenball | 0:b6fae6eb2bfe | 1 | /* mbed Microcontroller Library |
haydenball | 0:b6fae6eb2bfe | 2 | * Copyright (c) 2006-2013 ARM Limited |
haydenball | 0:b6fae6eb2bfe | 3 | * |
haydenball | 0:b6fae6eb2bfe | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
haydenball | 0:b6fae6eb2bfe | 5 | * you may not use this file except in compliance with the License. |
haydenball | 0:b6fae6eb2bfe | 6 | * You may obtain a copy of the License at |
haydenball | 0:b6fae6eb2bfe | 7 | * |
haydenball | 0:b6fae6eb2bfe | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
haydenball | 0:b6fae6eb2bfe | 9 | * |
haydenball | 0:b6fae6eb2bfe | 10 | * Unless required by applicable law or agreed to in writing, software |
haydenball | 0:b6fae6eb2bfe | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
haydenball | 0:b6fae6eb2bfe | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
haydenball | 0:b6fae6eb2bfe | 13 | * See the License for the specific language governing permissions and |
haydenball | 0:b6fae6eb2bfe | 14 | * limitations under the License. |
haydenball | 0:b6fae6eb2bfe | 15 | */ |
haydenball | 6:808cfc0b9480 | 16 | |
haydenball | 6:808cfc0b9480 | 17 | #define TARGET_NRF_LFCLK_RC 1 |
haydenball | 0:b6fae6eb2bfe | 18 | |
haydenball | 0:b6fae6eb2bfe | 19 | #include "mbed.h" |
haydenball | 0:b6fae6eb2bfe | 20 | #include "BLE.h" |
haydenball | 0:b6fae6eb2bfe | 21 | #include "UberVestService.h" |
haydenball | 6:808cfc0b9480 | 22 | #include <math.h> |
haydenball | 6:808cfc0b9480 | 23 | |
haydenball | 6:808cfc0b9480 | 24 | // BEGIN IO |
haydenball | 6:808cfc0b9480 | 25 | // Inputs and outputs need to be changed between the devkit and prospeckz |
haydenball | 0:b6fae6eb2bfe | 26 | |
haydenball | 4:851d3f52c344 | 27 | // Outputs |
haydenball | 4:851d3f52c344 | 28 | DigitalOut connectionLed(LED1); |
haydenball | 4:851d3f52c344 | 29 | |
haydenball | 4:851d3f52c344 | 30 | // Inputs |
haydenball | 6:808cfc0b9480 | 31 | AnalogIn ecg(p6); |
haydenball | 6:808cfc0b9480 | 32 | AnalogIn temp(p2); |
haydenball | 4:851d3f52c344 | 33 | |
haydenball | 6:808cfc0b9480 | 34 | // N.B. The devkit and prospeckz are different - DK is active low, prospeckz is active high. |
haydenball | 6:808cfc0b9480 | 35 | static const bool LED_ON = 1; |
haydenball | 6:808cfc0b9480 | 36 | static const bool LED_OFF = 0; |
haydenball | 6:808cfc0b9480 | 37 | |
haydenball | 6:808cfc0b9480 | 38 | // END IO |
haydenball | 6:808cfc0b9480 | 39 | |
haydenball | 7:7e1a474ca416 | 40 | Serial pc(USBTX, USBRX); |
haydenball | 6:808cfc0b9480 | 41 | BLE ble; |
haydenball | 0:b6fae6eb2bfe | 42 | |
haydenball | 0:b6fae6eb2bfe | 43 | const static char DEVICE_NAME[] = "UberVest"; |
haydenball | 0:b6fae6eb2bfe | 44 | static const uint16_t uuid16_list[] = {UberVestService::UBER_VEST_SERVICE_UUID}; |
haydenball | 0:b6fae6eb2bfe | 45 | |
haydenball | 6:808cfc0b9480 | 46 | static int8_t ecgValue; |
haydenball | 6:808cfc0b9480 | 47 | static int8_t tempValue; |
haydenball | 4:851d3f52c344 | 48 | |
haydenball | 6:808cfc0b9480 | 49 | static volatile bool sampleEcg = false; |
haydenball | 6:808cfc0b9480 | 50 | static volatile bool sampleTemp = false; |
haydenball | 0:b6fae6eb2bfe | 51 | |
haydenball | 0:b6fae6eb2bfe | 52 | UberVestService *uberVestServicePtr; |
haydenball | 0:b6fae6eb2bfe | 53 | |
haydenball | 2:9b977e86e2d5 | 54 | void connectionCallback(const Gap::ConnectionCallbackParams_t *params) |
haydenball | 2:9b977e86e2d5 | 55 | { |
haydenball | 6:808cfc0b9480 | 56 | connectionLed = LED_OFF; |
haydenball | 2:9b977e86e2d5 | 57 | } |
haydenball | 2:9b977e86e2d5 | 58 | |
haydenball | 0:b6fae6eb2bfe | 59 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
haydenball | 0:b6fae6eb2bfe | 60 | { |
haydenball | 0:b6fae6eb2bfe | 61 | ble.gap().startAdvertising(); |
haydenball | 6:808cfc0b9480 | 62 | connectionLed = LED_ON; |
haydenball | 6:808cfc0b9480 | 63 | } |
haydenball | 6:808cfc0b9480 | 64 | |
haydenball | 6:808cfc0b9480 | 65 | void sampleEcgCallback(void) |
haydenball | 6:808cfc0b9480 | 66 | { |
haydenball | 6:808cfc0b9480 | 67 | sampleEcg = true; |
haydenball | 6:808cfc0b9480 | 68 | } |
haydenball | 6:808cfc0b9480 | 69 | |
haydenball | 6:808cfc0b9480 | 70 | void sampleTempCallback(void) |
haydenball | 6:808cfc0b9480 | 71 | { |
haydenball | 6:808cfc0b9480 | 72 | sampleTemp = true; |
haydenball | 6:808cfc0b9480 | 73 | } |
haydenball | 6:808cfc0b9480 | 74 | |
haydenball | 6:808cfc0b9480 | 75 | void flasherTimer(void) |
haydenball | 6:808cfc0b9480 | 76 | { |
haydenball | 6:808cfc0b9480 | 77 | if (!ble.getGapState().connected) { |
haydenball | 6:808cfc0b9480 | 78 | connectionLed = !connectionLed; |
haydenball | 6:808cfc0b9480 | 79 | } |
haydenball | 0:b6fae6eb2bfe | 80 | } |
haydenball | 0:b6fae6eb2bfe | 81 | |
haydenball | 6:808cfc0b9480 | 82 | float getTemp(void) |
haydenball | 4:851d3f52c344 | 83 | { |
haydenball | 7:7e1a474ca416 | 84 | const int TEMP_RESISTOR_VALUE = 10900; |
haydenball | 6:808cfc0b9480 | 85 | float rawValue; |
haydenball | 6:808cfc0b9480 | 86 | float r; // Thermistor resistance |
haydenball | 6:808cfc0b9480 | 87 | double convertedTemp; |
haydenball | 6:808cfc0b9480 | 88 | |
haydenball | 6:808cfc0b9480 | 89 | rawValue = temp.read(); |
haydenball | 6:808cfc0b9480 | 90 | // The thermistor is set up as a simple voltage divider. We can get the resistance as follows: |
haydenball | 7:7e1a474ca416 | 91 | r = ((TEMP_RESISTOR_VALUE * 5.0f) / (rawValue * 4.3f)) - TEMP_RESISTOR_VALUE; |
haydenball | 6:808cfc0b9480 | 92 | |
haydenball | 6:808cfc0b9480 | 93 | // Now calculate the temperature from the resistance |
haydenball | 6:808cfc0b9480 | 94 | // From the thermistor data sheet (http://www.farnell.com/datasheets/1784420.pdf): |
haydenball | 7:7e1a474ca416 | 95 | const float R_REF = 10000.0f; |
haydenball | 6:808cfc0b9480 | 96 | const double A = 3.354016e-03; |
haydenball | 6:808cfc0b9480 | 97 | const double B = 2.569850e-04; |
haydenball | 6:808cfc0b9480 | 98 | const double C = 2.620131e-06; |
haydenball | 6:808cfc0b9480 | 99 | const double D = 6.383091e-08; |
haydenball | 6:808cfc0b9480 | 100 | |
haydenball | 6:808cfc0b9480 | 101 | convertedTemp = A + B * (log(r / R_REF)) + C * pow(log(r / R_REF), 2.0f) + D * pow(log(r / R_REF), 3.0f); |
haydenball | 7:7e1a474ca416 | 102 | convertedTemp = 1.0f / convertedTemp; |
haydenball | 6:808cfc0b9480 | 103 | |
haydenball | 6:808cfc0b9480 | 104 | // convert to degrees celsius: |
haydenball | 7:7e1a474ca416 | 105 | convertedTemp = convertedTemp - 273.0f; |
haydenball | 6:808cfc0b9480 | 106 | |
haydenball | 6:808cfc0b9480 | 107 | pc.printf("Raw: %f, Resisance: %f, Temp: %f\r\n", rawValue, r, convertedTemp); |
haydenball | 6:808cfc0b9480 | 108 | |
haydenball | 6:808cfc0b9480 | 109 | return (float) convertedTemp; |
haydenball | 4:851d3f52c344 | 110 | } |
haydenball | 4:851d3f52c344 | 111 | |
haydenball | 0:b6fae6eb2bfe | 112 | int main(void) |
haydenball | 0:b6fae6eb2bfe | 113 | { |
haydenball | 0:b6fae6eb2bfe | 114 | ble.init(); |
haydenball | 2:9b977e86e2d5 | 115 | ble.gap().onConnection(connectionCallback); |
haydenball | 0:b6fae6eb2bfe | 116 | ble.gap().onDisconnection(disconnectionCallback); |
haydenball | 6:808cfc0b9480 | 117 | |
haydenball | 6:808cfc0b9480 | 118 | ecgValue = 0; |
haydenball | 6:808cfc0b9480 | 119 | tempValue = 0; |
haydenball | 0:b6fae6eb2bfe | 120 | |
haydenball | 6:808cfc0b9480 | 121 | UberVestService uberVestService(ble, ecgValue, tempValue); |
haydenball | 0:b6fae6eb2bfe | 122 | uberVestServicePtr = &uberVestService; |
haydenball | 4:851d3f52c344 | 123 | |
haydenball | 6:808cfc0b9480 | 124 | Ticker ecgSampler; |
haydenball | 6:808cfc0b9480 | 125 | ecgSampler.attach(sampleEcgCallback, 0.02); |
haydenball | 6:808cfc0b9480 | 126 | |
haydenball | 6:808cfc0b9480 | 127 | Ticker tempSampler; |
haydenball | 6:808cfc0b9480 | 128 | tempSampler.attach(sampleTempCallback, 1); |
haydenball | 6:808cfc0b9480 | 129 | |
haydenball | 6:808cfc0b9480 | 130 | Ticker flasher; |
haydenball | 6:808cfc0b9480 | 131 | flasher.attach(flasherTimer, 0.5); |
haydenball | 0:b6fae6eb2bfe | 132 | |
haydenball | 0:b6fae6eb2bfe | 133 | /* setup advertising */ |
haydenball | 0:b6fae6eb2bfe | 134 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
haydenball | 0:b6fae6eb2bfe | 135 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
haydenball | 0:b6fae6eb2bfe | 136 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
haydenball | 0:b6fae6eb2bfe | 137 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
haydenball | 0:b6fae6eb2bfe | 138 | ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ |
haydenball | 0:b6fae6eb2bfe | 139 | ble.gap().startAdvertising(); |
haydenball | 0:b6fae6eb2bfe | 140 | |
haydenball | 0:b6fae6eb2bfe | 141 | while (true) { |
haydenball | 6:808cfc0b9480 | 142 | if (ble.getGapState().connected) { |
haydenball | 6:808cfc0b9480 | 143 | if (sampleEcg) { |
haydenball | 6:808cfc0b9480 | 144 | sampleEcg = false; |
haydenball | 6:808cfc0b9480 | 145 | |
haydenball | 7:7e1a474ca416 | 146 | ecgValue = (ecg.read() * 512); |
haydenball | 6:808cfc0b9480 | 147 | uberVestServicePtr->updateEcg(ecgValue); |
haydenball | 6:808cfc0b9480 | 148 | } |
haydenball | 6:808cfc0b9480 | 149 | |
haydenball | 6:808cfc0b9480 | 150 | if (sampleTemp) { |
haydenball | 6:808cfc0b9480 | 151 | sampleTemp = false; |
haydenball | 6:808cfc0b9480 | 152 | |
haydenball | 6:808cfc0b9480 | 153 | tempValue = getTemp(); |
haydenball | 6:808cfc0b9480 | 154 | uberVestServicePtr->updateTemp(tempValue); |
haydenball | 6:808cfc0b9480 | 155 | } |
haydenball | 4:851d3f52c344 | 156 | } else { |
haydenball | 4:851d3f52c344 | 157 | ble.waitForEvent(); |
haydenball | 4:851d3f52c344 | 158 | } |
haydenball | 0:b6fae6eb2bfe | 159 | } |
haydenball | 0:b6fae6eb2bfe | 160 | } |