Version working with both Nucleo-F411RE and Nucleo-F404RE
Dependencies: BLE_API X_NUCLEO_IDB0XA1 mbed
Fork of BLE_HeartRate_IDB0XA1 by
main.cpp
- Committer:
- leonardoaraujosantos
- Date:
- 2015-11-03
- Revision:
- 4:821e9af5e750
- Parent:
- 3:a51ca6313ad2
File content as of revision 4:821e9af5e750:
/* BLE Example Heart rate tutorial, just pay attention that the
* X-Nucleo-BLE board driver is not compatible to the new mbed BLE_API
* so don't update the newest version of BLE_API, also on this example
* we added a custom service (LED-ON/OFF) with 2 characteristics (Read and Write)
* to turn on/off the led
*/
#include "mbed.h"
#include "ble/BLE.h"
#include "ble/services/HeartRateService.h"
#include "ble/services/BatteryService.h"
#include "ble/services/DeviceInformationService.h"
BLE ble;
// If you apply the D13 pin patch you cannot use this led anymore
DigitalOut led1(LED1);
const static char DEVICE_NAME[] = "LeoBoard";
// Has the heart service, device information,
// and a custom service (for controllign the leds)
static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
GattService::UUID_DEVICE_INFORMATION_SERVICE, 0xFFFF
}; //Custom UUID, FFFF is reserved for development
static volatile bool triggerSensorPolling = false;
// Custom service and characteristics UUIDS
uint16_t customServiceUUID = 0xA000;
uint16_t readCharUUID = 0xA001;
uint16_t writeCharUUID = 0xA002;
// Set Up custom Characteristics (Package max size is 20bytes)
static uint8_t readValue[20] = {0};
ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue);
static uint8_t writeValue[20] = {0};
WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
// Set up custom service
GattCharacteristic *characteristics[] = {&readChar, &writeChar};
GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
printf("Start advertising\r\n");
ble.gap().startAdvertising(); // restart advertising
}
// Handle writes to writeCharacteristic
void writeCharCallback(const GattWriteCallbackParams *params) {
// check to see what characteristic was written, by handle
if(params->handle == writeChar.getValueHandle()) {
// toggle LED if only 1 byte is written
if(params->len == 1) {
led1 = params->data[0];
(params->data[0] == 0x00) ? printf("led off\n\r") : printf("led on\n\r"); // print led toggle
}
else {
printf("Data received: length = %d, data = 0x",params->len);
for(int x=0; x < params->len; x++) {
printf("%x", params->data[x]);
}
printf("\n\r");
}
// update the readChar with the value of writeChar
ble.updateCharacteristicValue(readChar.getValueHandle(), params->data,params->len);
}
}
void periodicCallback(void)
{
/* Note that the periodicCallback() executes in interrupt context, so it is safer to do
* heavy-weight sensor polling from the main thread. */
triggerSensorPolling = true;
}
int main(void){
Ticker ticker;
ticker.attach(periodicCallback, 1); // blink LED every second
printf("Initialize BLE\r\n");
ble.init();
ble.gap().onDisconnection(disconnectionCallback);
ble.gattServer().onDataWritten(writeCharCallback);
/* Setup primary service. */
uint8_t hrmCounter = 100; // init HRM to 100bps
HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
// Device Information
DeviceInformationService deviceInfo(ble, "StarkIndustires", "Quadcopter", "SN1", "hw-rev1", "fw-rev1", "BetaVer");
// add our custom service
ble.addService(customService);
// Setup advertising. Indicate that we only support bluetooth low energy
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_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();
while (1) {
// check for trigger from periodicCallback()
if (triggerSensorPolling && ble.getGapState().connected) {
triggerSensorPolling = false;
// Do blocking calls or whatever is necessary for sensor polling.
// In our case, we simply update the HRM measurement.
hrmCounter++;
// 100 <= HRM bps <=175
if (hrmCounter == 175) {
hrmCounter = 100;
}
// update bps
hrService.updateHeartRate(hrmCounter);
} else {
ble.waitForEvent(); // low power wait for event
}
}
}
