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