Simple HRM
Dependencies: BLE_API mbed nRF51822
main.cpp@0:aa3968526b8c, 2016-06-02 (annotated)
- Committer:
- FranKP2138
- Date:
- Thu Jun 02 17:21:07 2016 +0000
- Revision:
- 0:aa3968526b8c
Simple Heart HRM
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
FranKP2138 | 0:aa3968526b8c | 1 | /* |
FranKP2138 | 0:aa3968526b8c | 2 | * |
FranKP2138 | 0:aa3968526b8c | 3 | * Copyright (c) 2016 RedBear |
FranKP2138 | 0:aa3968526b8c | 4 | * |
FranKP2138 | 0:aa3968526b8c | 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), |
FranKP2138 | 0:aa3968526b8c | 6 | * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, |
FranKP2138 | 0:aa3968526b8c | 7 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
FranKP2138 | 0:aa3968526b8c | 8 | * |
FranKP2138 | 0:aa3968526b8c | 9 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
FranKP2138 | 0:aa3968526b8c | 10 | * |
FranKP2138 | 0:aa3968526b8c | 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
FranKP2138 | 0:aa3968526b8c | 12 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
FranKP2138 | 0:aa3968526b8c | 13 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
FranKP2138 | 0:aa3968526b8c | 14 | * IN THE SOFTWARE. |
FranKP2138 | 0:aa3968526b8c | 15 | */ |
FranKP2138 | 0:aa3968526b8c | 16 | |
FranKP2138 | 0:aa3968526b8c | 17 | /** |
FranKP2138 | 0:aa3968526b8c | 18 | * @note This demo is Nordic HRM example. |
FranKP2138 | 0:aa3968526b8c | 19 | * You could use nRF toolbox tool to test it. |
FranKP2138 | 0:aa3968526b8c | 20 | */ |
FranKP2138 | 0:aa3968526b8c | 21 | |
FranKP2138 | 0:aa3968526b8c | 22 | #include "mbed.h" |
FranKP2138 | 0:aa3968526b8c | 23 | #include "ble/BLE.h" |
FranKP2138 | 0:aa3968526b8c | 24 | #include "GattCallbackParamTypes.h" |
FranKP2138 | 0:aa3968526b8c | 25 | |
FranKP2138 | 0:aa3968526b8c | 26 | //#include "ble/DiscoveredCharacteristic.h" |
FranKP2138 | 0:aa3968526b8c | 27 | //#include "ble/DiscoveredService.h" |
FranKP2138 | 0:aa3968526b8c | 28 | //#include "ble/GapScanningParams.h" |
FranKP2138 | 0:aa3968526b8c | 29 | //#include "ble_radio_notification.h" |
FranKP2138 | 0:aa3968526b8c | 30 | //#include "ble_gap.h" |
FranKP2138 | 0:aa3968526b8c | 31 | |
FranKP2138 | 0:aa3968526b8c | 32 | |
FranKP2138 | 0:aa3968526b8c | 33 | |
FranKP2138 | 0:aa3968526b8c | 34 | #define DEVICE_NAME "Nordic_HRM" |
FranKP2138 | 0:aa3968526b8c | 35 | |
FranKP2138 | 0:aa3968526b8c | 36 | BLE ble; |
FranKP2138 | 0:aa3968526b8c | 37 | Ticker ticker_task1; |
FranKP2138 | 0:aa3968526b8c | 38 | |
FranKP2138 | 0:aa3968526b8c | 39 | |
FranKP2138 | 0:aa3968526b8c | 40 | |
FranKP2138 | 0:aa3968526b8c | 41 | Serial pc(USBTX, USBRX); |
FranKP2138 | 0:aa3968526b8c | 42 | |
FranKP2138 | 0:aa3968526b8c | 43 | |
FranKP2138 | 0:aa3968526b8c | 44 | |
FranKP2138 | 0:aa3968526b8c | 45 | |
FranKP2138 | 0:aa3968526b8c | 46 | |
FranKP2138 | 0:aa3968526b8c | 47 | static uint8_t hrmCounter = 100; |
FranKP2138 | 0:aa3968526b8c | 48 | static uint8_t bpm[2] = {0x00, hrmCounter}; |
FranKP2138 | 0:aa3968526b8c | 49 | static const uint8_t location = 0x03; |
FranKP2138 | 0:aa3968526b8c | 50 | static uint32_t cnt; |
FranKP2138 | 0:aa3968526b8c | 51 | |
FranKP2138 | 0:aa3968526b8c | 52 | static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; |
FranKP2138 | 0:aa3968526b8c | 53 | |
FranKP2138 | 0:aa3968526b8c | 54 | // Create characteristic and service |
FranKP2138 | 0:aa3968526b8c | 55 | GattCharacteristic hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, bpm, sizeof(bpm), sizeof(bpm), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
FranKP2138 | 0:aa3968526b8c | 56 | GattCharacteristic hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR,(uint8_t *)&location, sizeof(location), sizeof(location),GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
FranKP2138 | 0:aa3968526b8c | 57 | GattCharacteristic *hrmChars[] = {&hrmRate, &hrmLocation, }; |
FranKP2138 | 0:aa3968526b8c | 58 | GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); |
FranKP2138 | 0:aa3968526b8c | 59 | |
FranKP2138 | 0:aa3968526b8c | 60 | |
FranKP2138 | 0:aa3968526b8c | 61 | |
FranKP2138 | 0:aa3968526b8c | 62 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
FranKP2138 | 0:aa3968526b8c | 63 | { |
FranKP2138 | 0:aa3968526b8c | 64 | pc.printf("Disconnected ! \r\n"); |
FranKP2138 | 0:aa3968526b8c | 65 | pc.printf("Restart advertising progress \r\n"); |
FranKP2138 | 0:aa3968526b8c | 66 | ble.startAdvertising(); |
FranKP2138 | 0:aa3968526b8c | 67 | } |
FranKP2138 | 0:aa3968526b8c | 68 | |
FranKP2138 | 0:aa3968526b8c | 69 | |
FranKP2138 | 0:aa3968526b8c | 70 | void periodicCallback() { |
FranKP2138 | 0:aa3968526b8c | 71 | pc.printf("periodicCallback ! \r\n"); |
FranKP2138 | 0:aa3968526b8c | 72 | |
FranKP2138 | 0:aa3968526b8c | 73 | if (ble.getGapState().connected) { |
FranKP2138 | 0:aa3968526b8c | 74 | // Update the HRM measurement |
FranKP2138 | 0:aa3968526b8c | 75 | // First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value |
FranKP2138 | 0:aa3968526b8c | 76 | // See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml |
FranKP2138 | 0:aa3968526b8c | 77 | hrmCounter++; |
FranKP2138 | 0:aa3968526b8c | 78 | if (hrmCounter == 175) |
FranKP2138 | 0:aa3968526b8c | 79 | hrmCounter = 100; |
FranKP2138 | 0:aa3968526b8c | 80 | |
FranKP2138 | 0:aa3968526b8c | 81 | bpm[1] = hrmCounter; |
FranKP2138 | 0:aa3968526b8c | 82 | ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), bpm, sizeof(bpm)); |
FranKP2138 | 0:aa3968526b8c | 83 | } |
FranKP2138 | 0:aa3968526b8c | 84 | } |
FranKP2138 | 0:aa3968526b8c | 85 | |
FranKP2138 | 0:aa3968526b8c | 86 | |
FranKP2138 | 0:aa3968526b8c | 87 | |
FranKP2138 | 0:aa3968526b8c | 88 | int main(void) |
FranKP2138 | 0:aa3968526b8c | 89 | { |
FranKP2138 | 0:aa3968526b8c | 90 | // DElete |
FranKP2138 | 0:aa3968526b8c | 91 | //Ticker ticker; |
FranKP2138 | 0:aa3968526b8c | 92 | //ticker.attach_us(m_status_check_handle, 200000); |
FranKP2138 | 0:aa3968526b8c | 93 | |
FranKP2138 | 0:aa3968526b8c | 94 | pc.baud(9600); |
FranKP2138 | 0:aa3968526b8c | 95 | //wait(8.0); |
FranKP2138 | 0:aa3968526b8c | 96 | pc.printf("start\r\n"); |
FranKP2138 | 0:aa3968526b8c | 97 | pc.printf("Nordic_HRM Demo \r\n"); |
FranKP2138 | 0:aa3968526b8c | 98 | |
FranKP2138 | 0:aa3968526b8c | 99 | // Init timer task |
FranKP2138 | 0:aa3968526b8c | 100 | ticker_task1.attach(periodicCallback, 1); |
FranKP2138 | 0:aa3968526b8c | 101 | |
FranKP2138 | 0:aa3968526b8c | 102 | ble.init(); |
FranKP2138 | 0:aa3968526b8c | 103 | ble.onDisconnection(disconnectionCallback); |
FranKP2138 | 0:aa3968526b8c | 104 | |
FranKP2138 | 0:aa3968526b8c | 105 | |
FranKP2138 | 0:aa3968526b8c | 106 | // setup adv_data and srp_data |
FranKP2138 | 0:aa3968526b8c | 107 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
FranKP2138 | 0:aa3968526b8c | 108 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); |
FranKP2138 | 0:aa3968526b8c | 109 | ble.accumulateAdvertisingPayload(GapAdvertisingData::HEART_RATE_SENSOR_HEART_RATE_BELT); |
FranKP2138 | 0:aa3968526b8c | 110 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
FranKP2138 | 0:aa3968526b8c | 111 | // set adv_type |
FranKP2138 | 0:aa3968526b8c | 112 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
FranKP2138 | 0:aa3968526b8c | 113 | // add service |
FranKP2138 | 0:aa3968526b8c | 114 | ble.addService(hrmService); |
FranKP2138 | 0:aa3968526b8c | 115 | // set device name |
FranKP2138 | 0:aa3968526b8c | 116 | ble.setDeviceName((const uint8_t *)DEVICE_NAME); |
FranKP2138 | 0:aa3968526b8c | 117 | // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4 |
FranKP2138 | 0:aa3968526b8c | 118 | ble.setTxPower(4); |
FranKP2138 | 0:aa3968526b8c | 119 | |
FranKP2138 | 0:aa3968526b8c | 120 | |
FranKP2138 | 0:aa3968526b8c | 121 | // 100ms; in multiples of 0.625ms. |
FranKP2138 | 0:aa3968526b8c | 122 | ble.setAdvertisingInterval(160); |
FranKP2138 | 0:aa3968526b8c | 123 | |
FranKP2138 | 0:aa3968526b8c | 124 | //ble.addService(uartService); |
FranKP2138 | 0:aa3968526b8c | 125 | |
FranKP2138 | 0:aa3968526b8c | 126 | // set adv_timeout, in seconds |
FranKP2138 | 0:aa3968526b8c | 127 | ble.setAdvertisingTimeout(0); |
FranKP2138 | 0:aa3968526b8c | 128 | |
FranKP2138 | 0:aa3968526b8c | 129 | ble.startAdvertising(); |
FranKP2138 | 0:aa3968526b8c | 130 | |
FranKP2138 | 0:aa3968526b8c | 131 | pc.printf("Advertising Start \r\n"); |
FranKP2138 | 0:aa3968526b8c | 132 | |
FranKP2138 | 0:aa3968526b8c | 133 | /*while(1) |
FranKP2138 | 0:aa3968526b8c | 134 | { |
FranKP2138 | 0:aa3968526b8c | 135 | pc.printf("wait for event \r\n"); |
FranKP2138 | 0:aa3968526b8c | 136 | ble.waitForEvent(); |
FranKP2138 | 0:aa3968526b8c | 137 | }*/ |
FranKP2138 | 0:aa3968526b8c | 138 | } |