High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
main.cpp@3:46de446e82ed, 2013-12-11 (annotated)
- Committer:
- ktownsend
- Date:
- Wed Dec 11 22:15:59 2013 +0000
- Revision:
- 3:46de446e82ed
- Parent:
- 2:ffc5216bd2cc
- Child:
- 5:7635f81a8e09
Incremental changes for GAP Advertising API
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 | 0:ace2e8d3ce79 | 32 | /* Indicate = device (server) sends data when it changes and client confirms reception */ |
ktownsend | 0:ace2e8d3ce79 | 33 | |
ktownsend | 0:ace2e8d3ce79 | 34 | int main() |
ktownsend | 0:ace2e8d3ce79 | 35 | { |
ktownsend | 3:46de446e82ed | 36 | wait(2); |
ktownsend | 2:ffc5216bd2cc | 37 | radio.test(); |
ktownsend | 2:ffc5216bd2cc | 38 | while(1); |
ktownsend | 2:ffc5216bd2cc | 39 | |
ktownsend | 0:ace2e8d3ce79 | 40 | /* Add the battery level characteristic to the battery service */ |
ktownsend | 0:ace2e8d3ce79 | 41 | /* Note: This will also update the characteristic's .index field */ |
ktownsend | 0:ace2e8d3ce79 | 42 | /* so that we know where it's stored in the BLEService.characteristics */ |
ktownsend | 0:ace2e8d3ce79 | 43 | /* array. */ |
ktownsend | 0:ace2e8d3ce79 | 44 | battService.addCharacteristic(battLevel); |
ktownsend | 0:ace2e8d3ce79 | 45 | |
ktownsend | 0:ace2e8d3ce79 | 46 | /* Add the heart rate and sensor location chars to the HRM service */ |
ktownsend | 0:ace2e8d3ce79 | 47 | hrmService.addCharacteristic(hrmRate); |
ktownsend | 0:ace2e8d3ce79 | 48 | hrmService.addCharacteristic(hrmLocation); |
ktownsend | 0:ace2e8d3ce79 | 49 | |
ktownsend | 0:ace2e8d3ce79 | 50 | /* Add the Health Thermometer server characteristics */ |
ktownsend | 0:ace2e8d3ce79 | 51 | thermService.addCharacteristic(thermTemp); |
ktownsend | 0:ace2e8d3ce79 | 52 | thermService.addCharacteristic(thermType); |
ktownsend | 0:ace2e8d3ce79 | 53 | thermService.addCharacteristic(thermInterval); |
ktownsend | 0:ace2e8d3ce79 | 54 | |
ktownsend | 0:ace2e8d3ce79 | 55 | /* Reset the BLE hardware to make sure we get a clean start */ |
ktownsend | 0:ace2e8d3ce79 | 56 | wait(2); |
ktownsend | 0:ace2e8d3ce79 | 57 | radio.reset(); |
ktownsend | 0:ace2e8d3ce79 | 58 | |
ktownsend | 0:ace2e8d3ce79 | 59 | /* Add the services to the radio HAL */ |
ktownsend | 0:ace2e8d3ce79 | 60 | radio.addService(battService); |
ktownsend | 0:ace2e8d3ce79 | 61 | radio.addService(hrmService); |
ktownsend | 0:ace2e8d3ce79 | 62 | radio.addService(thermService); |
ktownsend | 0:ace2e8d3ce79 | 63 | |
ktownsend | 0:ace2e8d3ce79 | 64 | /* Start the services so that we can start pushing data out */ |
ktownsend | 0:ace2e8d3ce79 | 65 | radio.start(); |
ktownsend | 0:ace2e8d3ce79 | 66 | |
ktownsend | 0:ace2e8d3ce79 | 67 | /* Set the heart rate monitor location (one time only) */ |
ktownsend | 0:ace2e8d3ce79 | 68 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */ |
ktownsend | 0:ace2e8d3ce79 | 69 | uint8_t location = 0x01; /* Chest */ |
ktownsend | 2:ffc5216bd2cc | 70 | radio.writeCharacteristic(hrmService, hrmLocation, (uint8_t*)&location, sizeof(location)); |
ktownsend | 0:ace2e8d3ce79 | 71 | |
ktownsend | 0:ace2e8d3ce79 | 72 | /* Update the battery level */ |
ktownsend | 0:ace2e8d3ce79 | 73 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */ |
ktownsend | 0:ace2e8d3ce79 | 74 | uint8_t batt = 72; /* Percentage (0..100) */ |
ktownsend | 2:ffc5216bd2cc | 75 | radio.writeCharacteristic(battService, battLevel, (uint8_t*)&batt, sizeof(batt)); |
ktownsend | 0:ace2e8d3ce79 | 76 | |
ktownsend | 0:ace2e8d3ce79 | 77 | /* Update the fixed health thermometer characteristics */ |
ktownsend | 0:ace2e8d3ce79 | 78 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */ |
ktownsend | 0:ace2e8d3ce79 | 79 | uint8_t thermLocation = 6; /* Location = mouth */ |
ktownsend | 2:ffc5216bd2cc | 80 | radio.writeCharacteristic(thermService, thermType, (uint8_t*)&thermLocation, sizeof(thermLocation)); |
ktownsend | 0:ace2e8d3ce79 | 81 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.measurement_interval.xml */ |
ktownsend | 0:ace2e8d3ce79 | 82 | uint16_t thermDelay = 5; |
ktownsend | 2:ffc5216bd2cc | 83 | radio.writeCharacteristic(thermService, thermInterval, (uint8_t*)&thermDelay, sizeof(thermDelay)); |
ktownsend | 0:ace2e8d3ce79 | 84 | |
ktownsend | 0:ace2e8d3ce79 | 85 | /* Blinky + value updates */ |
ktownsend | 0:ace2e8d3ce79 | 86 | uint8_t hrmCounter = 100; |
ktownsend | 0:ace2e8d3ce79 | 87 | |
ktownsend | 0:ace2e8d3ce79 | 88 | while(1) |
ktownsend | 0:ace2e8d3ce79 | 89 | { |
ktownsend | 0:ace2e8d3ce79 | 90 | myled = 1; |
ktownsend | 0:ace2e8d3ce79 | 91 | wait(0.1); |
ktownsend | 0:ace2e8d3ce79 | 92 | myled = 0; |
ktownsend | 0:ace2e8d3ce79 | 93 | wait(0.1); |
ktownsend | 0:ace2e8d3ce79 | 94 | |
ktownsend | 0:ace2e8d3ce79 | 95 | /* Update the HRM measurement */ |
ktownsend | 0:ace2e8d3ce79 | 96 | /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ |
ktownsend | 0:ace2e8d3ce79 | 97 | /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ |
ktownsend | 0:ace2e8d3ce79 | 98 | hrmCounter++; |
ktownsend | 0:ace2e8d3ce79 | 99 | if (hrmCounter == 175) hrmCounter = 100; |
ktownsend | 0:ace2e8d3ce79 | 100 | uint8_t bpm[2] = { 0x00, hrmCounter }; |
ktownsend | 2:ffc5216bd2cc | 101 | radio.writeCharacteristic(hrmService, hrmRate, bpm, 2); |
ktownsend | 0:ace2e8d3ce79 | 102 | |
ktownsend | 0:ace2e8d3ce79 | 103 | /* Update the Health Thermometer measurement */ |
ktownsend | 0:ace2e8d3ce79 | 104 | |
ktownsend | 0:ace2e8d3ce79 | 105 | // NOTE: This is an IEEE-11073 32-bit float NOT a IEEE-754 float (standard single precision float type) !!! |
ktownsend | 0:ace2e8d3ce79 | 106 | // See: Section 2.2 of https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961 |
ktownsend | 0:ace2e8d3ce79 | 107 | // Example: |
ktownsend | 0:ace2e8d3ce79 | 108 | // Consider a temperature measurement of 36.4 degrees Celsius with precision of 0.1 degrees Celsius. |
ktownsend | 0:ace2e8d3ce79 | 109 | // The FLOAT-Type representation is a 32-bit value consisting of an exponent of an 8-bit signed integer |
ktownsend | 0:ace2e8d3ce79 | 110 | // followed by a mantissa of a 24-bit signed integer; here, the exponent is -1 (0xFF) and the mantissa |
ktownsend | 0:ace2e8d3ce79 | 111 | // is 364 (0x00016C). Therefore, the FLOAT-Type representation of 36.4 is 0xFF00016C. |
ktownsend | 0:ace2e8d3ce79 | 112 | |
ktownsend | 0:ace2e8d3ce79 | 113 | uint8_t temperature[5] = { 0x00, 0x00, 0x00, 0x00, 0xFF }; |
ktownsend | 0:ace2e8d3ce79 | 114 | // Use the hrm counter to provide a shifting temperature value (175 = 17.5C, etc.) |
ktownsend | 0:ace2e8d3ce79 | 115 | memcpy (temperature+1, &hrmCounter, 1); |
ktownsend | 2:ffc5216bd2cc | 116 | radio.writeCharacteristic(thermService, thermTemp, temperature, 5); |
ktownsend | 0:ace2e8d3ce79 | 117 | } |
ktownsend | 0:ace2e8d3ce79 | 118 | } |