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 // } // } }