HTM Demo of BLE with Microbit
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 #include "MicroBit.h" 00027 00028 const static char DEVICE_NAME[] = "MY_MICROBIT"; 00029 static volatile bool triggerSensorPolling = false; 00030 00031 MicroBit uBit; 00032 Ticker ticker; 00033 Serial pc(USBTX, USBRX); 00034 00035 bool isConnect = false; 00036 00037 /* Health Thermometer Service */ 00038 float temperature = 25.0; 00039 uint8_t thermTempPayload[5] = { 0, 0, 0, 0, 0 }; 00040 00041 GattCharacteristic tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, 00042 thermTempPayload, 5, 5, 00043 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE); 00044 00045 /* Battery Level Service */ 00046 uint8_t batt = 100; /* Battery level */ 00047 GattCharacteristic battLevel ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 00048 (uint8_t *)batt, 1, 1, 00049 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); 00050 00051 GattCharacteristic *htmChars[] = {&tempChar, }; 00052 GattCharacteristic *battChars[] = {&battLevel, }; 00053 00054 GattService htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars, 00055 sizeof(htmChars) / sizeof(GattCharacteristic *)); 00056 GattService battService(GattService::UUID_BATTERY_SERVICE, battChars, 00057 sizeof(battChars) / sizeof(GattCharacteristic *)); 00058 uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, 00059 GattService::UUID_BATTERY_SERVICE}; 00060 00061 static Gap::ConnectionParams_t connectionParams; 00062 00063 uint32_t quick_ieee11073_from_float(float temperature); 00064 void updateServiceValues(void); 00065 00066 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params) 00067 { 00068 isConnect = true; 00069 pc.printf("connected. Got handle %u\r\n", params->handle); 00070 00071 connectionParams.slaveLatency = 1; 00072 if (uBit.ble->gap().updateConnectionParams(params->handle, &connectionParams) != BLE_ERROR_NONE) { 00073 pc.printf("failed to update connection paramter\r\n"); 00074 } 00075 } 00076 00077 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00078 { 00079 isConnect = false; 00080 pc.printf("Disconnected handle %u, reason %u\r\n", params->handle, params->reason); 00081 pc.printf("Restarting the advertising process\r\n"); 00082 00083 pc.printf("Start Advertising\r\n"); 00084 uBit.ble->gap().startAdvertising(); 00085 } 00086 00087 void periodicCallback(void) 00088 { 00089 triggerSensorPolling = true; 00090 } 00091 00092 int main() 00093 { 00094 // Initialise the micro:bit runtime. 00095 pc.printf("Initialising MicroBit\r\n"); 00096 uBit.ble = new BLEDevice(); 00097 uBit.init(); 00098 uBit.ble->init(); 00099 pc.printf("Init done\r\n"); 00100 00101 uBit.ble->gap().onConnection(onConnectionCallback); 00102 uBit.ble->gap().onDisconnection(disconnectionCallback); 00103 00104 /* setup advertising */ 00105 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00106 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); 00107 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); 00108 uBit.ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00109 uBit.ble->gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00110 uBit.ble->setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ 00111 uBit.ble->startAdvertising(); 00112 pc.printf("Start Advertising\r\n"); 00113 00114 uBit.ble->gattServer().addService(htmService); 00115 uBit.ble->gattServer().addService(battService); 00116 pc.printf("Add Service\r\n"); 00117 00118 ticker.attach(periodicCallback, 1); 00119 00120 // Insert your code here! 00121 while(1) 00122 { 00123 if(isConnect) 00124 { 00125 uBit.display.printChar('C'); 00126 } 00127 else 00128 { 00129 uBit.display.printChar('A'); 00130 } 00131 00132 //uBit.display.scroll("ADV"); 00133 if (triggerSensorPolling) { 00134 triggerSensorPolling = false; 00135 updateServiceValues(); 00136 } else { 00137 uBit.ble->waitForEvent(); 00138 } 00139 } 00140 00141 // If main exits, there may still be other fibers running or registered event handlers etc. 00142 // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then 00143 // sit in the idle task forever, in a power efficient sleep. 00144 //release_fiber(); 00145 } 00146 00147 /**************************************************************************/ 00148 /*! 00149 @brief Ticker callback to switch advertisingStateLed state 00150 */ 00151 /**************************************************************************/ 00152 void updateServiceValues(void) 00153 { 00154 // Decrement the battery level. 00155 batt <=50 ? batt=100 : batt--; 00156 pc.printf("Batt is %u\r\n", batt); 00157 00158 /* Update the temperature. Note that we need to convert to an ieee11073 format float. */ 00159 temperature >= 30.0 ? temperature = 20.0 : temperature+=0.2; 00160 pc.printf("temp:%f\r\n", temperature); 00161 uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature); 00162 memcpy(thermTempPayload+1, &temp_ieee11073, 4); 00163 uBit.ble->gattServer().write(tempChar.getValueAttribute().getHandle(), thermTempPayload, sizeof(thermTempPayload)); //Mod 00164 uBit.ble->gattServer().write(battLevel.getValueAttribute().getHandle(), (uint8_t *)&batt, sizeof(batt)); //Mod 00165 } 00166 00167 /** 00168 * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type. 00169 * @param temperature The temperature as a float. 00170 * @return The temperature in 11073-20601 FLOAT-Type format. 00171 */ 00172 uint32_t quick_ieee11073_from_float(float temperature) 00173 { 00174 uint8_t exponent = 0xFF; //exponent is -1 00175 uint32_t mantissa = (uint32_t)(temperature*10); 00176 00177 return ( ((uint32_t)exponent) << 24) | mantissa; 00178 }
Generated on Mon Jul 18 2022 18:07:17 by 1.7.2