Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
main.cpp@5:7635f81a8e09, 2013-12-12 (annotated)
- Committer:
- ktownsend
- Date:
- Thu Dec 12 02:43:22 2013 +0000
- Revision:
- 5:7635f81a8e09
- Parent:
- 3:46de446e82ed
- Child:
- 6:425638944835
Few changes and a build test for GAP advertising changes
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ktownsend | 0:ace2e8d3ce79 | 1 | #include "mbed.h" |
| ktownsend | 0:ace2e8d3ce79 | 2 | |
| ktownsend | 0:ace2e8d3ce79 | 3 | #include "uuid.h" |
| ktownsend | 2:ffc5216bd2cc | 4 | #include "GattService.h" |
| ktownsend | 2:ffc5216bd2cc | 5 | #include "GattCharacteristic.h" |
| ktownsend | 0:ace2e8d3ce79 | 6 | #include "hw/nrf51822.h" |
| ktownsend | 0:ace2e8d3ce79 | 7 | |
| ktownsend | 0:ace2e8d3ce79 | 8 | DigitalOut myled ( LED1 ); |
| ktownsend | 0:ace2e8d3ce79 | 9 | |
| ktownsend | 0:ace2e8d3ce79 | 10 | /* Radio HW abstraction layer */ |
| ktownsend | 0:ace2e8d3ce79 | 11 | nRF51822 radio; |
| ktownsend | 0:ace2e8d3ce79 | 12 | |
| ktownsend | 0:ace2e8d3ce79 | 13 | /* Battery Level Service */ |
| ktownsend | 0:ace2e8d3ce79 | 14 | /* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml */ |
| ktownsend | 2:ffc5216bd2cc | 15 | GattService battService ( 0x180F ); |
| ktownsend | 3:46de446e82ed | 16 | GattCharacteristic battLevel ( 0x2A19, 1, 1, BLE_GATT_CHAR_PROPERTIES_NOTIFY | BLE_GATT_CHAR_PROPERTIES_READ ); |
| ktownsend | 0:ace2e8d3ce79 | 17 | |
| ktownsend | 0:ace2e8d3ce79 | 18 | /* Heart Rate Monitor Service */ |
| ktownsend | 0:ace2e8d3ce79 | 19 | /* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */ |
| ktownsend | 2:ffc5216bd2cc | 20 | GattService hrmService ( 0x180D ); |
| ktownsend | 3:46de446e82ed | 21 | GattCharacteristic hrmRate ( 0x2A37, 2, 3, BLE_GATT_CHAR_PROPERTIES_NOTIFY ); |
| ktownsend | 3:46de446e82ed | 22 | GattCharacteristic hrmLocation ( 0x2A39, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ ); |
| ktownsend | 0:ace2e8d3ce79 | 23 | |
| ktownsend | 0:ace2e8d3ce79 | 24 | /* Health Thermometer Service */ |
| ktownsend | 0:ace2e8d3ce79 | 25 | /* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml */ |
| ktownsend | 2:ffc5216bd2cc | 26 | GattService thermService ( 0x1809 ); |
| ktownsend | 3:46de446e82ed | 27 | GattCharacteristic thermTemp ( 0x2A1C, 5, 13, BLE_GATT_CHAR_PROPERTIES_INDICATE ); |
| ktownsend | 3:46de446e82ed | 28 | GattCharacteristic thermType ( 0x2A1D, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ ); |
| ktownsend | 3:46de446e82ed | 29 | GattCharacteristic thermInterval ( 0x2A21, 2, 2, BLE_GATT_CHAR_PROPERTIES_READ ); |
| ktownsend | 0:ace2e8d3ce79 | 30 | |
| ktownsend | 0:ace2e8d3ce79 | 31 | /* Notify = device (server) sends data when it changes */ |
| ktownsend | 5:7635f81a8e09 | 32 | /* Indicate = device (server) sends data when it changes and client confirms reception */ |
| ktownsend | 5:7635f81a8e09 | 33 | |
| ktownsend | 5:7635f81a8e09 | 34 | /* GAP Advertising Example (iBeacon) */ |
| ktownsend | 5:7635f81a8e09 | 35 | GapAdvertisingParams advParams ( GapAdvertisingParams::NON_CONNECTABLE ); |
| ktownsend | 5:7635f81a8e09 | 36 | GapAdvertisingData advData; |
| ktownsend | 5:7635f81a8e09 | 37 | |
| ktownsend | 5:7635f81a8e09 | 38 | uint8_t iBeaconPayload[25] = { 0x4C, 0x00, 0x02, 0x15, 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61, 0x00, 0x00, 0x00, 0x00, 0xC8 }; |
| ktownsend | 5:7635f81a8e09 | 39 | |
| ktownsend | 5:7635f81a8e09 | 40 | void startBeacon(void) |
| ktownsend | 5:7635f81a8e09 | 41 | { |
| ktownsend | 5:7635f81a8e09 | 42 | /* iBeacon includes the FLAG and MSD fields */ |
| ktownsend | 5:7635f81a8e09 | 43 | advData.addFlags(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
| ktownsend | 5:7635f81a8e09 | 44 | advData.addData(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, iBeaconPayload, 25); |
| ktownsend | 5:7635f81a8e09 | 45 | |
| ktownsend | 5:7635f81a8e09 | 46 | wait(2); |
| ktownsend | 5:7635f81a8e09 | 47 | radio.reset(); |
| ktownsend | 5:7635f81a8e09 | 48 | radio.setAdvertising(advParams, advData); |
| ktownsend | 5:7635f81a8e09 | 49 | radio.start(); |
| ktownsend | 5:7635f81a8e09 | 50 | } |
| ktownsend | 5:7635f81a8e09 | 51 | |
| ktownsend | 0:ace2e8d3ce79 | 52 | int main() |
| ktownsend | 0:ace2e8d3ce79 | 53 | { |
| ktownsend | 3:46de446e82ed | 54 | wait(2); |
| ktownsend | 5:7635f81a8e09 | 55 | // radio.test(); |
| ktownsend | 5:7635f81a8e09 | 56 | startBeacon(); |
| ktownsend | 2:ffc5216bd2cc | 57 | while(1); |
| ktownsend | 2:ffc5216bd2cc | 58 | |
| ktownsend | 0:ace2e8d3ce79 | 59 | /* Add the battery level characteristic to the battery service */ |
| ktownsend | 0:ace2e8d3ce79 | 60 | /* Note: This will also update the characteristic's .index field */ |
| ktownsend | 0:ace2e8d3ce79 | 61 | /* so that we know where it's stored in the BLEService.characteristics */ |
| ktownsend | 0:ace2e8d3ce79 | 62 | /* array. */ |
| ktownsend | 0:ace2e8d3ce79 | 63 | battService.addCharacteristic(battLevel); |
| ktownsend | 0:ace2e8d3ce79 | 64 | |
| ktownsend | 0:ace2e8d3ce79 | 65 | /* Add the heart rate and sensor location chars to the HRM service */ |
| ktownsend | 0:ace2e8d3ce79 | 66 | hrmService.addCharacteristic(hrmRate); |
| ktownsend | 0:ace2e8d3ce79 | 67 | hrmService.addCharacteristic(hrmLocation); |
| ktownsend | 0:ace2e8d3ce79 | 68 | |
| ktownsend | 0:ace2e8d3ce79 | 69 | /* Add the Health Thermometer server characteristics */ |
| ktownsend | 0:ace2e8d3ce79 | 70 | thermService.addCharacteristic(thermTemp); |
| ktownsend | 0:ace2e8d3ce79 | 71 | thermService.addCharacteristic(thermType); |
| ktownsend | 0:ace2e8d3ce79 | 72 | thermService.addCharacteristic(thermInterval); |
| ktownsend | 0:ace2e8d3ce79 | 73 | |
| ktownsend | 0:ace2e8d3ce79 | 74 | /* Reset the BLE hardware to make sure we get a clean start */ |
| ktownsend | 0:ace2e8d3ce79 | 75 | wait(2); |
| ktownsend | 0:ace2e8d3ce79 | 76 | radio.reset(); |
| ktownsend | 0:ace2e8d3ce79 | 77 | |
| ktownsend | 0:ace2e8d3ce79 | 78 | /* Add the services to the radio HAL */ |
| ktownsend | 0:ace2e8d3ce79 | 79 | radio.addService(battService); |
| ktownsend | 0:ace2e8d3ce79 | 80 | radio.addService(hrmService); |
| ktownsend | 0:ace2e8d3ce79 | 81 | radio.addService(thermService); |
| ktownsend | 0:ace2e8d3ce79 | 82 | |
| ktownsend | 0:ace2e8d3ce79 | 83 | /* Start the services so that we can start pushing data out */ |
| ktownsend | 0:ace2e8d3ce79 | 84 | radio.start(); |
| ktownsend | 0:ace2e8d3ce79 | 85 | |
| ktownsend | 0:ace2e8d3ce79 | 86 | /* Set the heart rate monitor location (one time only) */ |
| ktownsend | 0:ace2e8d3ce79 | 87 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */ |
| ktownsend | 0:ace2e8d3ce79 | 88 | uint8_t location = 0x01; /* Chest */ |
| ktownsend | 2:ffc5216bd2cc | 89 | radio.writeCharacteristic(hrmService, hrmLocation, (uint8_t*)&location, sizeof(location)); |
| ktownsend | 0:ace2e8d3ce79 | 90 | |
| ktownsend | 0:ace2e8d3ce79 | 91 | /* Update the battery level */ |
| ktownsend | 0:ace2e8d3ce79 | 92 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */ |
| ktownsend | 0:ace2e8d3ce79 | 93 | uint8_t batt = 72; /* Percentage (0..100) */ |
| ktownsend | 2:ffc5216bd2cc | 94 | radio.writeCharacteristic(battService, battLevel, (uint8_t*)&batt, sizeof(batt)); |
| ktownsend | 0:ace2e8d3ce79 | 95 | |
| ktownsend | 0:ace2e8d3ce79 | 96 | /* Update the fixed health thermometer characteristics */ |
| ktownsend | 0:ace2e8d3ce79 | 97 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */ |
| ktownsend | 0:ace2e8d3ce79 | 98 | uint8_t thermLocation = 6; /* Location = mouth */ |
| ktownsend | 2:ffc5216bd2cc | 99 | radio.writeCharacteristic(thermService, thermType, (uint8_t*)&thermLocation, sizeof(thermLocation)); |
| ktownsend | 0:ace2e8d3ce79 | 100 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.measurement_interval.xml */ |
| ktownsend | 0:ace2e8d3ce79 | 101 | uint16_t thermDelay = 5; |
| ktownsend | 2:ffc5216bd2cc | 102 | radio.writeCharacteristic(thermService, thermInterval, (uint8_t*)&thermDelay, sizeof(thermDelay)); |
| ktownsend | 0:ace2e8d3ce79 | 103 | |
| ktownsend | 0:ace2e8d3ce79 | 104 | /* Blinky + value updates */ |
| ktownsend | 0:ace2e8d3ce79 | 105 | uint8_t hrmCounter = 100; |
| ktownsend | 0:ace2e8d3ce79 | 106 | |
| ktownsend | 0:ace2e8d3ce79 | 107 | while(1) |
| ktownsend | 0:ace2e8d3ce79 | 108 | { |
| ktownsend | 0:ace2e8d3ce79 | 109 | myled = 1; |
| ktownsend | 0:ace2e8d3ce79 | 110 | wait(0.1); |
| ktownsend | 0:ace2e8d3ce79 | 111 | myled = 0; |
| ktownsend | 0:ace2e8d3ce79 | 112 | wait(0.1); |
| ktownsend | 0:ace2e8d3ce79 | 113 | |
| ktownsend | 0:ace2e8d3ce79 | 114 | /* Update the HRM measurement */ |
| ktownsend | 0:ace2e8d3ce79 | 115 | /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ |
| ktownsend | 0:ace2e8d3ce79 | 116 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ |
| ktownsend | 0:ace2e8d3ce79 | 117 | hrmCounter++; |
| ktownsend | 0:ace2e8d3ce79 | 118 | if (hrmCounter == 175) hrmCounter = 100; |
| ktownsend | 0:ace2e8d3ce79 | 119 | uint8_t bpm[2] = { 0x00, hrmCounter }; |
| ktownsend | 2:ffc5216bd2cc | 120 | radio.writeCharacteristic(hrmService, hrmRate, bpm, 2); |
| ktownsend | 0:ace2e8d3ce79 | 121 | |
| ktownsend | 0:ace2e8d3ce79 | 122 | /* Update the Health Thermometer measurement */ |
| ktownsend | 0:ace2e8d3ce79 | 123 | |
| ktownsend | 0:ace2e8d3ce79 | 124 | // NOTE: This is an IEEE-11073 32-bit float NOT a IEEE-754 float (standard single precision float type) !!! |
| ktownsend | 0:ace2e8d3ce79 | 125 | // See: Section 2.2 of https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961 |
| ktownsend | 0:ace2e8d3ce79 | 126 | // Example: |
| ktownsend | 0:ace2e8d3ce79 | 127 | // Consider a temperature measurement of 36.4 degrees Celsius with precision of 0.1 degrees Celsius. |
| ktownsend | 0:ace2e8d3ce79 | 128 | // The FLOAT-Type representation is a 32-bit value consisting of an exponent of an 8-bit signed integer |
| ktownsend | 0:ace2e8d3ce79 | 129 | // followed by a mantissa of a 24-bit signed integer; here, the exponent is -1 (0xFF) and the mantissa |
| ktownsend | 0:ace2e8d3ce79 | 130 | // is 364 (0x00016C). Therefore, the FLOAT-Type representation of 36.4 is 0xFF00016C. |
| ktownsend | 0:ace2e8d3ce79 | 131 | |
| ktownsend | 0:ace2e8d3ce79 | 132 | uint8_t temperature[5] = { 0x00, 0x00, 0x00, 0x00, 0xFF }; |
| ktownsend | 0:ace2e8d3ce79 | 133 | // Use the hrm counter to provide a shifting temperature value (175 = 17.5C, etc.) |
| ktownsend | 0:ace2e8d3ce79 | 134 | memcpy (temperature+1, &hrmCounter, 1); |
| ktownsend | 2:ffc5216bd2cc | 135 | radio.writeCharacteristic(thermService, thermTemp, temperature, 5); |
| ktownsend | 0:ace2e8d3ce79 | 136 | } |
| ktownsend | 0:ace2e8d3ce79 | 137 | } |
