mbed code for UberVest health monitoring

Dependencies:   BLE_API mbed nRF51822

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?

UserRevisionLine numberNew 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 }