mbed code for UberVest health monitoring

Dependencies:   BLE_API mbed nRF51822

main.cpp

Committer:
haydenball
Date:
2016-01-13
Revision:
7:7e1a474ca416
Parent:
6:808cfc0b9480

File content as of revision 7:7e1a474ca416:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#define TARGET_NRF_LFCLK_RC 1

#include "mbed.h"
#include "BLE.h"
#include "UberVestService.h"
#include <math.h>

// BEGIN IO
// Inputs and outputs need to be changed between the devkit and prospeckz

// Outputs
DigitalOut connectionLed(LED1);

// Inputs
AnalogIn ecg(p6);
AnalogIn temp(p2);

// N.B. The devkit and prospeckz are different - DK is active low, prospeckz is active high.
static const bool LED_ON = 1;
static const bool LED_OFF = 0;

// END IO

Serial pc(USBTX, USBRX);
BLE ble;

const static char     DEVICE_NAME[] = "UberVest";
static const uint16_t uuid16_list[] = {UberVestService::UBER_VEST_SERVICE_UUID};

static int8_t ecgValue;
static int8_t tempValue;

static volatile bool sampleEcg = false;
static volatile bool sampleTemp = false;

UberVestService *uberVestServicePtr;

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    connectionLed = LED_OFF;
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    ble.gap().startAdvertising();
    connectionLed = LED_ON;
}

void sampleEcgCallback(void)
{
    sampleEcg = true;
}

void sampleTempCallback(void)
{
    sampleTemp = true;
}

void flasherTimer(void)
{
    if (!ble.getGapState().connected) {
        connectionLed = !connectionLed;
    }
}

float getTemp(void)
{
    const int TEMP_RESISTOR_VALUE = 10900;
    float rawValue;
    float r; // Thermistor resistance
    double convertedTemp;
    
    rawValue = temp.read();
    // The thermistor is set up as a simple voltage divider. We can get the resistance as follows:
    r = ((TEMP_RESISTOR_VALUE * 5.0f) / (rawValue * 4.3f)) - TEMP_RESISTOR_VALUE;
    
    // Now calculate the temperature from the resistance
    // From the thermistor data sheet (http://www.farnell.com/datasheets/1784420.pdf):
    const float R_REF = 10000.0f;
    const double A = 3.354016e-03;
    const double B = 2.569850e-04;
    const double C = 2.620131e-06;
    const double D = 6.383091e-08;
    
    convertedTemp = A + B * (log(r / R_REF)) + C * pow(log(r / R_REF), 2.0f) + D * pow(log(r / R_REF), 3.0f);
    convertedTemp = 1.0f / convertedTemp;
    
    // convert to degrees celsius:
    convertedTemp = convertedTemp - 273.0f;
    
    pc.printf("Raw: %f, Resisance: %f, Temp: %f\r\n", rawValue, r, convertedTemp);
    
    return (float) convertedTemp;
}
    
int main(void)
{
    ble.init();
    ble.gap().onConnection(connectionCallback);
    ble.gap().onDisconnection(disconnectionCallback);
    
    ecgValue = 0;
    tempValue = 0;

    UberVestService uberVestService(ble, ecgValue, tempValue);
    uberVestServicePtr = &uberVestService;
    
    Ticker ecgSampler;
    ecgSampler.attach(sampleEcgCallback, 0.02);
    
    Ticker tempSampler;
    tempSampler.attach(sampleTempCallback, 1);
    
    Ticker flasher;
    flasher.attach(flasherTimer, 0.5);

    /* setup advertising */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
    ble.gap().startAdvertising();

    while (true) {
        if (ble.getGapState().connected) {
            if (sampleEcg) {
                sampleEcg = false;
                
                ecgValue = (ecg.read() * 512);
                uberVestServicePtr->updateEcg(ecgValue);
            }
            
            if (sampleTemp) {
                sampleTemp = false;
                
                tempValue = getTemp();
                uberVestServicePtr->updateTemp(tempValue);
            }
        } else {
            ble.waitForEvent();
        }
    }
}