BLE_Health_Thermometer; based on todotani-san's mod. Libraries are now genuine.

Dependencies:   BLE_API TMP102 mbed nRF51822

Fork of BLE_HTM_HRM1017 by Yoshihiro TSUBOI

Committer:
mbed_tw_hoehoe
Date:
Fri Nov 27 12:31:49 2015 +0000
Revision:
9:554af3c63d0c
Parent:
8:f753b4b022a8
commit.

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