HTM Demo of BLE with Microbit

Dependencies:   microbit

Revision:
1:7623f55dd990
Parent:
0:d44120452d31
Child:
2:7c86dc4b74a8
--- a/main.cpp	Tue Aug 06 15:16:48 2019 +0000
+++ b/main.cpp	Sat Aug 10 06:53:10 2019 +0000
@@ -32,17 +32,33 @@
 Ticker ticker;
 Serial  pc(USBTX, USBRX);
 
-static Gap::ConnectionParams_t connectionParams;
+/* Health Thermometer Service */ 
+float temperature = 25.0;
+uint8_t             thermTempPayload[5] = { 0, 0, 0, 0, 0 };
+
+GattCharacteristic  tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
+                                thermTempPayload, 5, 5,
+                                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
 
 /* Battery Level Service */
 uint8_t            batt = 100;     /* Battery level */
 GattCharacteristic battLevel ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 
                                  (uint8_t *)batt, 1, 1,
-                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+
+GattCharacteristic *htmChars[] = {&tempChar, };
 GattCharacteristic *battChars[] = {&battLevel, };
+
+GattService        htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars, 
+                                sizeof(htmChars) / sizeof(GattCharacteristic *));
 GattService        battService(GattService::UUID_BATTERY_SERVICE, battChars,
                                 sizeof(battChars) / sizeof(GattCharacteristic *));
-uint16_t             uuid16_list[] = {GattService::UUID_BATTERY_SERVICE};
+uint16_t             uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE,
+                                      GattService::UUID_BATTERY_SERVICE};
+
+static Gap::ConnectionParams_t connectionParams;
+
+uint32_t quick_ieee11073_from_float(float temperature);
 
 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
 {
@@ -82,14 +98,16 @@
     /* setup advertising */
     uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
     uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list));
-    uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_REMOTE_CONTROL);
+    uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
     uBit.ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
     uBit.ble->gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     uBit.ble->setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
     uBit.ble->startAdvertising();
     pc.printf("Start Advertising\r\n");
     
+    uBit.ble->gattServer().addService(htmService);
     uBit.ble->gattServer().addService(battService);
+    pc.printf("Add Service\r\n");
 
     ticker.attach(periodicCallback, 1);
 
@@ -103,7 +121,13 @@
             // Decrement the battery level.
             batt <=50 ? batt=100 : batt--;
             pc.printf("Batt is %u\r\n", batt);
-      
+            
+          /* Update the temperature. Note that we need to convert to an ieee11073 format float. */
+            temperature >= 30.0 ? temperature = 20.0 : temperature+=0.2;
+            pc.printf("temp:%f\r\n", temperature);
+            uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
+            memcpy(thermTempPayload+1, &temp_ieee11073, 4);
+            uBit.ble->gattServer().write(tempChar.getValueAttribute().getHandle(), thermTempPayload, sizeof(thermTempPayload));  //Mod
             uBit.ble->gattServer().write(battLevel.getValueAttribute().getHandle(), (uint8_t *)&batt, sizeof(batt));             //Mod
         } else {
             uBit.ble->waitForEvent();
@@ -116,3 +140,15 @@
     //release_fiber();
 }
 
+/**
+ * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
+ * @param temperature The temperature as a float.
+ * @return The temperature in 11073-20601 FLOAT-Type format.
+ */
+uint32_t quick_ieee11073_from_float(float temperature)
+{
+    uint8_t  exponent = 0xFF; //exponent is -1
+    uint32_t mantissa = (uint32_t)(temperature*10);
+    
+    return ( ((uint32_t)exponent) << 24) | mantissa;
+}