Auto updating alarm watch - accepts alarm settings from a BLE device like a Raspberry Pi and buzzes at the appropriate time - also displays binary time
Dependencies: BLE_API mbed-src nRF51822 nrf51_rtc
main.cpp
- Committer:
- Bobty
- Date:
- 2015-03-10
- Revision:
- 0:0d5ac2fd4620
- Child:
- 1:c3d7e673cdd2
File content as of revision 0:0d5ac2fd4620:
// BLE Alarm Watch
// Based on BLE heart-rate-monitor from MBED team
// Rob Dobson, 2015
#include "mbed.h"
#include "BLEDevice.h"
#include "DeviceInformationService.h"
// BLE Device etc
BLEDevice ble;
DigitalOut ledIndicator(LED1);
DigitalOut testOut(p1);
const static char DEVICE_NAME[] = "ALMW";
//static const uint16_t uuid16_list[] = {GattService::UUID_ALARM_WATCH_SERVICE,
// GattService::UUID_DEVICE_INFORMATION_SERVICE};
//
///*
//* Define a custom UUID, first as an array of uint8_t and then convert to
//* a proper UUID later. The UUID must be 16 bytes (128-bits, 16 letters)
//* long - here we have padded out to 16 bytes by adding an extra '0' at
//* the end. Make sure you fill more than 4 bytes otherwise it will count
//* as a 'short' code and you could end up using a predefined value from
//* the BLE spec.
//*/
//uint8_t raw_characteristic_uuid[16] = {
// 'M', 'Y', '_', 'T',
// 'E', 'S', 'T', '_',
// 'C', 'H', 'A', 'R',
// 0, 0, 0, 0
//};
//// Create a proper UUID - use the built in function to do this correctly
//UUID characteristic_uuid = UUID(raw_characteristic_uuid);
//// Setup some dummy properties for our characteristic
//static uint8_t my_char_values[2] = { 15, 10 };
///*
//* Here we create our Characteristic adding in the dummy parameter values
//* we just setup, we also make it readable and writeable meaning that a
//* central can read and update the parameters we have stored.
//*/
//GattCharacteristic pattern(
// characteristic_uuid,
// my_char_values,
// sizeof(my_char_values),
// sizeof(my_char_values),
// GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE
//);
///*
//* List the Characteristics of our custom Service, can have one or more
//* of these each with a custom UUID and parameter values.
//*/
//GattCharacteristic *my_service_chars[] = {
// &new_alert,
//};
//// Now setup a custom Service UUID, in the same fashion as for the Characteristic
//uint8_t raw_service_uuid[16] = {
// 'M', 'Y', '_', 'T',
// 'E', 'S', 'T', '_',
// 'S', 'E', 'R', 'V',
// 'I', 'C', 'E', 0
//};
//UUID service_uuid = UUID(raw_service_uuid);
//// Setup the Service with the UUID and all of the Characteristics
//GattService my_service(
// service_uuid,
// my_service_chars,
// sizeof(my_service_chars) / sizeof(GattCharacteristic *)
//);
///*
//* Now list the long UUIDs of the services we offer, these will be bundled into the
//* advertisement. It may look like repetition of 'raw_service_uuid' but here you can
//* list multiple UUIDs one after another.
//*/
//static const uint8_t uuid128_list[] = {
// 'M', 'Y', '_', 'T', 'E', 'S', 'T', '_', 'S', 'E', 'R', 'V', 'I', 'C', 'E', 0
// // List more long UUIDs below...
//};
//
//...
//
///*
//* Now we change from using short (16-bit) UUIDs to long (128-bit) UUIDs, comment out
//* the old section of the payload and add the new 128-bit section.
//*/
///*bluetooth->accumulateAdvertisingPayload(
// GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
// (uint8_t *)uuid16_list,
// sizeof(uuid16_list)
//);*/
//bluetooth->accumulateAdvertisingPayload(
// GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS,
// (uint8_t *)uuid128_list,
// sizeof(uuid128_list)
//);
//
//
//
//
//
static volatile bool triggerSensorPolling = false;
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
ble.startAdvertising(); // restart advertising
}
void periodicCallback(void)
{
ledIndicator = !ledIndicator; /* Do blinky on LED1 while we're waiting for BLE events */
testOut = !testOut;
}
int main(void)
{
ledIndicator = 0;
testOut = 0;
// Ticker is interrupt driven
Ticker ticker;
ticker.attach_us(periodicCallback, 100000);
// Init BLE
ble.init();
ble.onDisconnection(disconnectionCallback);
// Setup advertising
/* BREDR_NOT_SUPPORTED means classic bluetooth not supported;
* LE_GENERAL_DISCOVERABLE means that this peripheral can be
* discovered by any BLE scanner--i.e. any phone. */
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
/* This is where we're collecting the device name into the advertisement payload. */
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
/* We'd like for this BLE peripheral to be connectable. */
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
/* set the interval at which advertisements are sent out; this has
* an implication power consumption--radio activity being a
* biggest draw on average power. The other software controllable
* parameter which influences power is the radio's TX power
* level--there's an API to adjust that. */
ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); /* 1000ms. */
/* we're finally good to go with advertisements. */
ble.startAdvertising();
while (true)
{
ble.waitForEvent();
}
// /* Setup primary service. */
// uint8_t hrmCounter = 100; // init HRM to 100bps
// HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
//
// /* Setup auxiliary service. */
// DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
//
// /* Setup advertising. */
// ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
// ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
// ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
// ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
// ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
// ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));
// ble.startAdvertising();
//
// // infinite loop
// 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
// }
// }
}