スマホのアプリで温度を表示するプログラム

Dependencies:   BLE_API mbed nRF51822

スマホのアプリで温度を表示するプログラムです。

Android や iOS で、nRF Toolbox というアプリをインストールします。


Android アプリ
iOS アプリ

  • アプリを立ち上げて、HTMのアイコンをえらびます
  • CONNECT ボタンをおして、リストから自分のデバイスを選びます
  • 少し待つと、温度が表示されます
Committer:
MACRUM
Date:
Thu Aug 18 02:26:20 2016 +0000
Revision:
1:1bb2969a0f65
Parent:
0:8a3c9e181611
update libraries

Who changed what in which revision?

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