BLE Heart Rate Sample Program for HRM1017 which is using Nordic nRF51822 confirmed the connection of nRFToolbox on Android.

Dependencies:   BLE_API mbed nRF51822 color_pixels

Fork of BLE_HTM_HRM1017 by Switch Science

Committer:
todotani
Date:
Fri Aug 22 11:27:32 2014 +0000
Revision:
0:5e4210d108ac
Child:
2:daf2344afc28
BLE_Health_Thermometer for mbed HRM1017 with new library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
todotani 0:5e4210d108ac 1 #include "mbed.h"
todotani 0:5e4210d108ac 2 #include "TMP102.h"
todotani 0:5e4210d108ac 3 #include "BLEDevice.h"
todotani 0:5e4210d108ac 4 #include "ble_hts.h"
todotani 0:5e4210d108ac 5
todotani 0:5e4210d108ac 6 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
todotani 0:5e4210d108ac 7 * it will have an impact on code-size and power consumption. */
todotani 0:5e4210d108ac 8
todotani 0:5e4210d108ac 9 #if NEED_CONSOLE_OUTPUT
todotani 0:5e4210d108ac 10 Serial pc(USBTX, USBRX);
todotani 0:5e4210d108ac 11 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
todotani 0:5e4210d108ac 12 #else
todotani 0:5e4210d108ac 13 #define DEBUG(...) /* nothing */
todotani 0:5e4210d108ac 14 #endif /* #if NEED_CONSOLE_OUTPUT */
todotani 0:5e4210d108ac 15
todotani 0:5e4210d108ac 16 const static char DEVICE_NAME[] = "HRM1017_HTM";
todotani 0:5e4210d108ac 17
todotani 0:5e4210d108ac 18 BLEDevice ble;
todotani 0:5e4210d108ac 19 TMP102 healthThemometer(p22, p20, 0x90); /* The TMP102 connected to our board */
todotani 0:5e4210d108ac 20
todotani 0:5e4210d108ac 21 /* LEDs for indication: */
todotani 0:5e4210d108ac 22 DigitalOut oneSecondLed(LED1); /* LED1 is toggled every second. */
todotani 0:5e4210d108ac 23 DigitalOut advertisingStateLed(LED2); /* LED2 is on when we are advertising, otherwise off. */
todotani 0:5e4210d108ac 24
todotani 0:5e4210d108ac 25
todotani 0:5e4210d108ac 26 /* Health Thermometer Service */
todotani 0:5e4210d108ac 27 uint8_t thermTempPayload[5] = { 0, 0, 0, 0, 0 };
todotani 0:5e4210d108ac 28
todotani 0:5e4210d108ac 29 GattCharacteristic tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
todotani 0:5e4210d108ac 30 thermTempPayload, 5, 5,
todotani 0:5e4210d108ac 31 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
todotani 0:5e4210d108ac 32 /* Battery Level Service */
todotani 0:5e4210d108ac 33 uint8_t batt = 100; /* Battery level */
todotani 0:5e4210d108ac 34 uint8_t read_batt = 0; /* Variable to hold battery level reads */
todotani 0:5e4210d108ac 35 GattCharacteristic battLevel ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR,
todotani 0:5e4210d108ac 36 (uint8_t *)batt, 1, 1,
todotani 0:5e4210d108ac 37 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
todotani 0:5e4210d108ac 38 GattCharacteristic *htmChars[] = {&tempChar, };
todotani 0:5e4210d108ac 39 GattCharacteristic *battChars[] = {&battLevel, };
todotani 0:5e4210d108ac 40 GattService htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars,
todotani 0:5e4210d108ac 41 sizeof(htmChars) / sizeof(GattCharacteristic *));
todotani 0:5e4210d108ac 42 GattService battService(GattService::UUID_BATTERY_SERVICE, battChars,
todotani 0:5e4210d108ac 43 sizeof(battChars) / sizeof(GattCharacteristic *));
todotani 0:5e4210d108ac 44
todotani 0:5e4210d108ac 45 uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE,
todotani 0:5e4210d108ac 46 GattService::UUID_BATTERY_SERVICE};
todotani 0:5e4210d108ac 47
todotani 0:5e4210d108ac 48 uint32_t quick_ieee11073_from_float(float temperature);
todotani 0:5e4210d108ac 49 void updateServiceValues(void);
todotani 0:5e4210d108ac 50
todotani 0:5e4210d108ac 51 static Gap::ConnectionParams_t connectionParams;
todotani 0:5e4210d108ac 52
todotani 0:5e4210d108ac 53 void disconnectionCallback(Gap::Handle_t handle)
todotani 0:5e4210d108ac 54 {
todotani 0:5e4210d108ac 55 advertisingStateLed = 1;
todotani 0:5e4210d108ac 56
todotani 0:5e4210d108ac 57 DEBUG("Disconnected handle %u!\n\r", handle);
todotani 0:5e4210d108ac 58 DEBUG("Restarting the advertising process\n\r");
todotani 0:5e4210d108ac 59 ble.startAdvertising();
todotani 0:5e4210d108ac 60 }
todotani 0:5e4210d108ac 61
todotani 0:5e4210d108ac 62 void onConnectionCallback(Gap::Handle_t handle)
todotani 0:5e4210d108ac 63 {
todotani 0:5e4210d108ac 64 advertisingStateLed = 0;
todotani 0:5e4210d108ac 65
todotani 0:5e4210d108ac 66 DEBUG("connected. Got handle %u\r\n", handle);
todotani 0:5e4210d108ac 67
todotani 0:5e4210d108ac 68 connectionParams.slaveLatency = 1;
todotani 0:5e4210d108ac 69 if (ble.updateConnectionParams(handle, &connectionParams) != BLE_ERROR_NONE) {
todotani 0:5e4210d108ac 70 DEBUG("failed to update connection paramter\r\n");
todotani 0:5e4210d108ac 71 }
todotani 0:5e4210d108ac 72 }
todotani 0:5e4210d108ac 73
todotani 0:5e4210d108ac 74 /**************************************************************************/
todotani 0:5e4210d108ac 75 /*!
todotani 0:5e4210d108ac 76 @brief Program entry point
todotani 0:5e4210d108ac 77 */
todotani 0:5e4210d108ac 78 /**************************************************************************/
todotani 0:5e4210d108ac 79 int main(void)
todotani 0:5e4210d108ac 80 {
todotani 0:5e4210d108ac 81
todotani 0:5e4210d108ac 82 /* Setup blinky led */
todotani 0:5e4210d108ac 83 oneSecondLed = 1;
todotani 0:5e4210d108ac 84
todotani 0:5e4210d108ac 85 DEBUG("Initialising the nRF51822\n\r");
todotani 0:5e4210d108ac 86 ble.init();
todotani 0:5e4210d108ac 87 ble.onDisconnection(disconnectionCallback);
todotani 0:5e4210d108ac 88 ble.onConnection(onConnectionCallback);
todotani 0:5e4210d108ac 89
todotani 0:5e4210d108ac 90 ble.getPreferredConnectionParams(&connectionParams);
todotani 0:5e4210d108ac 91
todotani 0:5e4210d108ac 92 /* setup advertising */
todotani 0:5e4210d108ac 93 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
todotani 0:5e4210d108ac 94 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list));
todotani 0:5e4210d108ac 95 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
todotani 0:5e4210d108ac 96 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
todotani 0:5e4210d108ac 97 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
todotani 0:5e4210d108ac 98 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
todotani 0:5e4210d108ac 99 ble.startAdvertising();
todotani 0:5e4210d108ac 100 advertisingStateLed = 1;
todotani 0:5e4210d108ac 101
todotani 0:5e4210d108ac 102 ble.addService(htmService);
todotani 0:5e4210d108ac 103 ble.addService(battService);
todotani 0:5e4210d108ac 104
todotani 0:5e4210d108ac 105 for (;;)
todotani 0:5e4210d108ac 106 {
todotani 0:5e4210d108ac 107 /* Now that we're live, update the battery level & temperature characteristics */
todotani 0:5e4210d108ac 108 updateServiceValues();
todotani 0:5e4210d108ac 109 wait(1);
todotani 0:5e4210d108ac 110 ble.waitForEvent();
todotani 0:5e4210d108ac 111 }
todotani 0:5e4210d108ac 112 }
todotani 0:5e4210d108ac 113
todotani 0:5e4210d108ac 114 /**************************************************************************/
todotani 0:5e4210d108ac 115 /*!
todotani 0:5e4210d108ac 116 @brief Ticker callback to switch advertisingStateLed state
todotani 0:5e4210d108ac 117 */
todotani 0:5e4210d108ac 118 /**************************************************************************/
todotani 0:5e4210d108ac 119 void updateServiceValues(void)
todotani 0:5e4210d108ac 120 {
todotani 0:5e4210d108ac 121 /* Toggle the one second LEDs */
todotani 0:5e4210d108ac 122 oneSecondLed = !oneSecondLed;
todotani 0:5e4210d108ac 123
todotani 0:5e4210d108ac 124 /* Decrement the battery level. */
todotani 0:5e4210d108ac 125 batt <=50 ? batt=100 : batt--;
todotani 0:5e4210d108ac 126
todotani 0:5e4210d108ac 127 /* Update the temperature. Note that we need to convert to an ieee11073 format float. */
todotani 0:5e4210d108ac 128 float temperature = healthThemometer.read();
todotani 0:5e4210d108ac 129 DEBUG("temp:%f\n", temperature);
todotani 0:5e4210d108ac 130 uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
todotani 0:5e4210d108ac 131 memcpy(thermTempPayload+1, &temp_ieee11073, 4);
todotani 0:5e4210d108ac 132 ble.updateCharacteristicValue(tempChar.getHandle(), thermTempPayload, sizeof(thermTempPayload));
todotani 0:5e4210d108ac 133 ble.updateCharacteristicValue(battLevel.getHandle(), (uint8_t *)&batt, sizeof(batt));
todotani 0:5e4210d108ac 134 }
todotani 0:5e4210d108ac 135
todotani 0:5e4210d108ac 136 /**
todotani 0:5e4210d108ac 137 * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
todotani 0:5e4210d108ac 138 * @param temperature The temperature as a float.
todotani 0:5e4210d108ac 139 * @return The temperature in 11073-20601 FLOAT-Type format.
todotani 0:5e4210d108ac 140 */
todotani 0:5e4210d108ac 141 uint32_t quick_ieee11073_from_float(float temperature)
todotani 0:5e4210d108ac 142 {
todotani 0:5e4210d108ac 143 uint8_t exponent = 0xFF; //exponent is -1
todotani 0:5e4210d108ac 144 uint32_t mantissa = (uint32_t)(temperature*10);
todotani 0:5e4210d108ac 145
todotani 0:5e4210d108ac 146 return ( ((uint32_t)exponent) << 24) | mantissa;
todotani 0:5e4210d108ac 147 }
todotani 0:5e4210d108ac 148