Duy tran / Mbed OS HealthCare_Graduation

Dependencies:   PulseSensor GSM Thermometer KalmanFilter

Application/main.cpp

Committer:
DuyLionTran
Date:
2018-03-09
Revision:
10:4e0f5173269e
Parent:
9:be09a9bf2e2e
Child:
11:5a4313edf10d

File content as of revision 10:4e0f5173269e:

/** 
  * This is the project for "BLE HealthCare". The device is attached on any patient's body at will.
  
  * Revision:
  * version 0.8     02-12-2018
  * version 0.8.5   02-14-2018
  * version 0.9     02-15-2018  Pulse sensor and thermometer added 
  * version 0.9.5   02-16-2018  Calculation for pulse sensor and thermometer. GSM library added 
  * version 0.9.6   02-21-2018  Update mbed-os
  * version 0.9.6   02-21-2018  Some modification for LM35
  * version 0.9.8   03-04-2018  Data receiving from client device added
  * version 1.0     03-09-2018  Some minor bugs fixed
  * version 1.0.5   03-09-2018  Some minor bugs fixed

/* ======================== INCLUDES ========================= */
#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
#include "ble_healthcare_service.h"
#include "GSM.h"
#include "LM35.h"
#include "PulseSensor.h"



/* ======================== DEFINES ========================== */
#define THERM_FINGER_LOCATION   3
#define HRM_FINGER_LOCATION     3

#define PULSE_SENSOR_PIN        A0
#define THERM_SENSOR_PIN        A1

/* ======================= VARIABLES ========================= */
/* GLOBAL VARIABLES */
static float          currentTemperature   = 39.6;
static uint8_t        currentHRMCounter    = 80;

/* PRIVATE VARIABLES */
uint8_t HRM_increasement = 1;
uint8_t cnt;

/* No need to display the device name */
//const static char     DEVICE_NAME[] = "BODY SENSOR";

static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, 
                                       GattService::UUID_HEALTH_THERMOMETER_SERVICE, 
                                       HealthCareService::USER_DATA_SERVICE_UUID,
                                       HealthCareService::DEVICE_INFO_SERVICE_UUID
                                       };

/* STRUCTS/CLASSESS */
static EventQueue        eventQueue(EVENTS_EVENT_SIZE * 20);
HealthCareService       *HealthCareServicePtr;
//PulseSensor              PulseSensor();

Serial                   serial(USBTX, USBRX);

/* ================== FUNCTION PROTOTYPES ==================== */
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *);
void onBleInitError(BLE &ble, ble_error_t error);
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params);
void onDataWrittenCallback(const GattWriteCallbackParams *params);
void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context);

void updatePayload(void);
void main_event(void);
void periodicCallback(void);

/* ==================== FUNCTION DETAILS ===================== */
/* Restart Advertising on disconnection*/
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) {
    BLE::Instance().gap().startAdvertising();
    printf("Device disconnected with mobile/table\r\n");
}

void updatePayload(void) {
    // Update the count in the SERVICE_DATA field of the advertising payload
    cnt++;
    uint8_t service_data[8];
    /* first 2 bytes are for service UUID */
    service_data[0] = HealthCareService::USER_DATA_SERVICE_UUID & 0xFF;
    service_data[1] = HealthCareService::USER_DATA_SERVICE_UUID >> 8;
    /* next 4 bytes are for client ID */
    service_data[2] = 0x07;
    service_data[3] = 0x09;
    service_data[4] = 0x9A;
    service_data[5] = 0xAC;
    /* last 2 bytes are sensor data */
    service_data[6] = cnt;
    service_data[7] = cnt;
    ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));

}

void main_event(void) {
    /* Do blocking calls or whatever is necessary for sensor polling.
       In our case, we simply update the Temperature measurement. */
    currentTemperature = (currentTemperature + 0.1 > 43.0) ? 39.6 : currentTemperature + 0.1;
    currentHRMCounter  = (currentHRMCounter + 1 > 120) ? 80 : (currentHRMCounter + HRM_increasement);
    updatePayload();
    if (BLE::Instance().gap().getState().connected) {
        HealthCareServicePtr->updateTemperature(currentTemperature);
        HealthCareServicePtr->updateHeartRate(currentHRMCounter);        
    }

}

void periodicCallback(void) {
    /* call main_event immediately */
    eventQueue.call(main_event);
}

void printMacAddress() {
    /* Print out device MAC address to the console*/
    Gap::AddressType_t addr_type;
    Gap::Address_t address;
    BLE::Instance().gap().getAddress(&addr_type, address);
    printf("DEVICE MAC ADDRESS: ");
    for (int i = 5; i >= 1; i--) {
        printf("%02x:", address[i]);
    }
    printf("%02x\r\n", address[0]);
}

void onBleInitError(BLE &ble, ble_error_t error) {
   /* Initialization error handling should go here */
   printf("BLE init error!\r\n");
}

/**
 * This callback allows the HealthCareService to receive updates to the controlState Characteristic.
 *
 * @param[in] params
 *     Information about the characterisitc being updated.
 */
void onDataWrittenCallback(const GattWriteCallbackParams *params) {
    if ((params->handle == HealthCareServicePtr->getValueHandle()) && (params->len == 1)) {
        uint8_t old_HRM_increasement = HRM_increasement;
        HRM_increasement = *(params->data);
        printf("Old data: %d\r\n, New data %d\r\n", old_HRM_increasement, HRM_increasement);
    }
}

/** 
  * @brief Callback triggered when the ble initialization process has finished
  */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }
    uint8_t initial_HRMIncreasement = 1;
    ble.gap().onDisconnection(disconnectionCallback);
    ble.gattServer().onDataWritten(onDataWrittenCallback);
    
    HealthCareServicePtr = new HealthCareService(ble, currentTemperature, THERM_FINGER_LOCATION, 
                                                      currentHRMCounter, HRM_FINGER_LOCATION,
                                                      initial_HRMIncreasement);

    /* 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::GENERIC_THERMOMETER );
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
    
    /* No need to display the device name */
    // ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME , (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    uint8_t service_data[8];
    /* first 2 bytes are for service UUID */
    service_data[0] = HealthCareService::USER_DATA_SERVICE_UUID & 0xFF;
    service_data[1] = HealthCareService::USER_DATA_SERVICE_UUID >> 8;
    /* next 4 bytes are for client ID */
    service_data[2] = 0x07;
    service_data[3] = 0x09;
    service_data[4] = 0x9A;
    service_data[5] = 0xAC;
    /* last 2 bytes are sensor data */
    service_data[6] = cnt;
    service_data[7] = cnt;

    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA , (uint8_t *)service_data, sizeof(service_data));
    
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(300); /* 1000ms. */
    ble.gap().startAdvertising();
    
    printMacAddress();
    printf("BLE init successfully\r\n");
}

void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
    BLE &ble = BLE::Instance();
    eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
}

/* MAIN FUNCTION */
int main() {
    
    serial.baud(115200);
    printf("\r\n BODY WIRELESS SENSOR NETWORK\r\n");
    /* call periodicCallback every 500ms */
    eventQueue.call_every(500, periodicCallback);
    
    /* init BLE */
    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(scheduleBleEventsProcessing);
    ble.init(bleInitComplete);
    
    /* dispatch the event queue */
    eventQueue.dispatch_forever();

    return 0;
}