Graduation Thesis, use Nucleo and X-Nucleo BLE

Dependencies:   PulseSensor GSM Thermometer KalmanFilter

application/main.cpp

Committer:
DuyLionTran
Date:
2018-02-14
Revision:
1:9eadd2dc4b6e
Parent:
0:64ca984b3efd
Child:
2:16f6cfcd7505

File content as of revision 1:9eadd2dc4b6e:

/** 
  * This is the code for "BLE Device for motorbike". The device is attached on any bike at will.
  * User can control 2 switches and these switches can control anything that user wants ie: turn on
  * the bike, turn on the alarm system of the bike, turn on the light...
  * Temperature sensor is also included in the device. User can view the temperature when he/she gets
  * near the bike.
  
  * Revision:
  * version 0.8 02-12-2018

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

/* ======================== DEFINES ========================== */

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

/* PRIVATE VARIABLES */
const static char     DEVICE_NAME[] = "HEALTH STATE";
static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE};


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

/* ================== FUNCTION PROTOTYPES ==================== */

/* ==================== FUNCTION DETAILS ===================== */
/* Restart Advertising on disconnection*/
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) {
    BLE::Instance().gap().startAdvertising();
}


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 + 1;
    HealthCareServicePtr->updateTemperature(currentTemperature);
    HealthCareServicePtr->updateHeartRate(currentHRMCounter);
}

void periodicCallback(void) {
    if (BLE::Instance().gap().getState().connected) {
        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 */
}

/** 
  * @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;
    }

    ble.gap().onDisconnection(disconnectionCallback);
    HealthCareServicePtr = new HealthCareService(ble, currentTemperature, 3, 
                                                      currentHRMCounter, 3);

    /* 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::THERMOMETER_EAR);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
    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();
    
    printMacAddress();
}

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

/* MAIN FUNCTION */
int main() {
    eventQueue.call_every(500, periodicCallback);

    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(scheduleBleEventsProcessing);
    ble.init(bleInitComplete);

    eventQueue.dispatch_forever();

    return 0;
}