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
Diff: main.cpp
- Revision:
- 1:c3d7e673cdd2
- Parent:
- 0:0d5ac2fd4620
- Child:
- 2:9090120e2656
--- a/main.cpp Tue Mar 10 15:29:07 2015 +0000 +++ b/main.cpp Tue Mar 10 16:50:59 2015 +0000 @@ -11,107 +11,59 @@ 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; +// Device name +const static char DEVICE_NAME[] = "JOESALARM"; + +// UUID for CurTimeService & TimeBlockCharacteristic +const uint16_t UUID_CUR_TIME_SERVICE = 0xA000; +const uint16_t UUID_TIME_BLOCK_CHARACTERISTIC = 0xA001; + +// List of supported service UUIDs +static const uint16_t uuid16_list[] = {UUID_CUR_TIME_SERVICE}; +// Time is packed in an array of bytes +const int SIZE_OF_TIME_BLOCK = 7; +uint8_t timeBlockInitValue[SIZE_OF_TIME_BLOCK]; +uint8_t curTimeBlock[SIZE_OF_TIME_BLOCK]; + +// GATT Characteristic for time block +ReadWriteGattCharacteristic<uint8_t> timeBlockCharacteristic(UUID_TIME_BLOCK_CHARACTERISTIC, timeBlockInitValue); + +// Callback when connection lost void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { ble.startAdvertising(); // restart advertising } +// Callback for ticker +int tickCount = 0; +bool showInfo = false; +int writeSinceLast = 0; void periodicCallback(void) { ledIndicator = !ledIndicator; /* Do blinky on LED1 while we're waiting for BLE events */ testOut = !testOut; + tickCount++; + if (tickCount > 100) + { + showInfo = true; + tickCount = 0; + } } +// Data written callback +void onDataWrittenCallback(const GattCharacteristicWriteCBParams *params) +{ + if ((params->charHandle == timeBlockCharacteristic.getValueHandle())) + { +// && (params->len == SIZE_OF_TIME_BLOCK) + writeSinceLast = params->len; + memcpy(curTimeBlock, params->data, SIZE_OF_TIME_BLOCK); + } + writeSinceLast = true; +} + +// Main int main(void) { ledIndicator = 0; @@ -121,9 +73,18 @@ Ticker ticker; ticker.attach_us(periodicCallback, 100000); - // Init BLE + // Initial value for the time block characteristic + memset(timeBlockInitValue, 0, sizeof(timeBlockInitValue)); + + // Init BLE and register callbacks ble.init(); ble.onDisconnection(disconnectionCallback); + ble.onDataWritten(onDataWrittenCallback); + + // Add the time setting service + GattCharacteristic *charTable[] = {&timeBlockCharacteristic}; + GattService timeBlockService(UUID_CUR_TIME_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.addService(timeBlockService); // Setup advertising /* BREDR_NOT_SUPPORTED means classic bluetooth not supported; @@ -131,6 +92,9 @@ * discovered by any BLE scanner--i.e. any phone. */ ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + // Add services to payload + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + /* 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)); @@ -150,6 +114,18 @@ while (true) { ble.waitForEvent(); + + if (showInfo) + { + printf("Time info: "); + for (int i = 0; i < SIZE_OF_TIME_BLOCK; i++) + { + printf("%02d", curTimeBlock[i]); + } + printf(" - writeSinceLast %d\r\n", writeSinceLast); + showInfo = false; + writeSinceLast = 0; + } } // /* Setup primary service. */ // uint8_t hrmCounter = 100; // init HRM to 100bps