BLE_Health_Thermometer for mbed HRM1017 with new library
Dependencies: BLE_API TMP102 mbed nRF51822
main.cpp
00001 #include "mbed.h" 00002 #include "TMP102.h" 00003 #include "BLEDevice.h" 00004 #include "ble_hts.h" 00005 00006 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; 00007 * it will have an impact on code-size and power consumption. */ 00008 00009 #if NEED_CONSOLE_OUTPUT 00010 Serial pc(USBTX, USBRX); 00011 #define DEBUG(...) { pc.printf(__VA_ARGS__); } 00012 #else 00013 #define DEBUG(...) /* nothing */ 00014 #endif /* #if NEED_CONSOLE_OUTPUT */ 00015 00016 const static char DEVICE_NAME[] = "HRM1017_HTM"; 00017 00018 BLEDevice ble; 00019 TMP102 healthThemometer(p22, p20, 0x90); /* The TMP102 connected to our board */ 00020 00021 /* LEDs for indication: */ 00022 DigitalOut oneSecondLed(LED1); /* LED1 is toggled every second. */ 00023 DigitalOut advertisingStateLed(LED2); /* LED2 is on when we are advertising, otherwise off. */ 00024 00025 00026 /* Health Thermometer Service */ 00027 uint8_t thermTempPayload[5] = { 0, 0, 0, 0, 0 }; 00028 00029 GattCharacteristic tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, 00030 thermTempPayload, 5, 5, 00031 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE); 00032 /* Battery Level Service */ 00033 uint8_t batt = 100; /* Battery level */ 00034 uint8_t read_batt = 0; /* Variable to hold battery level reads */ 00035 GattCharacteristic battLevel ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 00036 (uint8_t *)batt, 1, 1, 00037 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); 00038 GattCharacteristic *htmChars[] = {&tempChar, }; 00039 GattCharacteristic *battChars[] = {&battLevel, }; 00040 GattService htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars, 00041 sizeof(htmChars) / sizeof(GattCharacteristic *)); 00042 GattService battService(GattService::UUID_BATTERY_SERVICE, battChars, 00043 sizeof(battChars) / sizeof(GattCharacteristic *)); 00044 00045 uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, 00046 GattService::UUID_BATTERY_SERVICE}; 00047 00048 uint32_t quick_ieee11073_from_float(float temperature); 00049 void updateServiceValues(void); 00050 00051 static Gap::ConnectionParams_t connectionParams; 00052 00053 void disconnectionCallback(Gap::Handle_t handle) 00054 { 00055 advertisingStateLed = 1; 00056 00057 DEBUG("Disconnected handle %u!\n\r", handle); 00058 DEBUG("Restarting the advertising process\n\r"); 00059 ble.startAdvertising(); 00060 } 00061 00062 void onConnectionCallback(Gap::Handle_t handle) 00063 { 00064 advertisingStateLed = 0; 00065 00066 DEBUG("connected. Got handle %u\r\n", handle); 00067 00068 connectionParams.slaveLatency = 1; 00069 if (ble.updateConnectionParams(handle, &connectionParams) != BLE_ERROR_NONE) { 00070 DEBUG("failed to update connection paramter\r\n"); 00071 } 00072 } 00073 00074 /**************************************************************************/ 00075 /*! 00076 @brief Program entry point 00077 */ 00078 /**************************************************************************/ 00079 int main(void) 00080 { 00081 00082 /* Setup blinky led */ 00083 oneSecondLed = 1; 00084 00085 DEBUG("Initialising the nRF51822\n\r"); 00086 ble.init(); 00087 ble.onDisconnection(disconnectionCallback); 00088 ble.onConnection(onConnectionCallback); 00089 00090 ble.getPreferredConnectionParams(&connectionParams); 00091 00092 /* setup advertising */ 00093 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00094 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); 00095 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); 00096 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00097 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00098 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ 00099 ble.startAdvertising(); 00100 advertisingStateLed = 1; 00101 00102 ble.addService(htmService); 00103 ble.addService(battService); 00104 00105 for (;;) 00106 { 00107 /* Now that we're live, update the battery level & temperature characteristics */ 00108 updateServiceValues(); 00109 wait(1); 00110 ble.waitForEvent(); 00111 } 00112 } 00113 00114 /**************************************************************************/ 00115 /*! 00116 @brief Ticker callback to switch advertisingStateLed state 00117 */ 00118 /**************************************************************************/ 00119 void updateServiceValues(void) 00120 { 00121 /* Toggle the one second LEDs */ 00122 oneSecondLed = !oneSecondLed; 00123 00124 /* Decrement the battery level. */ 00125 batt <=50 ? batt=100 : batt--; 00126 00127 /* Update the temperature. Note that we need to convert to an ieee11073 format float. */ 00128 float temperature = healthThemometer.read(); 00129 DEBUG("temp:%f\n", temperature); 00130 uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature); 00131 memcpy(thermTempPayload+1, &temp_ieee11073, 4); 00132 ble.updateCharacteristicValue(tempChar.getHandle(), thermTempPayload, sizeof(thermTempPayload)); 00133 ble.updateCharacteristicValue(battLevel.getHandle(), (uint8_t *)&batt, sizeof(batt)); 00134 } 00135 00136 /** 00137 * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type. 00138 * @param temperature The temperature as a float. 00139 * @return The temperature in 11073-20601 FLOAT-Type format. 00140 */ 00141 uint32_t quick_ieee11073_from_float(float temperature) 00142 { 00143 uint8_t exponent = 0xFF; //exponent is -1 00144 uint32_t mantissa = (uint32_t)(temperature*10); 00145 00146 return ( ((uint32_t)exponent) << 24) | mantissa; 00147 } 00148
Generated on Thu Jul 28 2022 11:26:41 by 1.7.2