BLE

Dependencies:   ADT7410 BLE_API mbed nRF51822

See https://developer.mbed.org/users/yasuyuki/notebook/BLE/

Committer:
yasuyuki
Date:
Wed Sep 09 17:26:34 2015 +0000
Revision:
2:d5bdd080d451
Parent:
1:6458709fb459
update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yasuyuki 0:1dbfda43d8b4 1 //**********************
yasuyuki 0:1dbfda43d8b4 2 // BLE demo for mbed_HRM1017
yasuyuki 0:1dbfda43d8b4 3 //
yasuyuki 1:6458709fb459 4 // successful combination
yasuyuki 2:d5bdd080d451 5 //#define REV1 // mbed=rev.97/BLE_API=rev.341/nRF51822=rev.111
yasuyuki 2:d5bdd080d451 6 //#define REV2 // mbed=rev.101/BLE_API=rev.738/nRF51822=rev.385
yasuyuki 2:d5bdd080d451 7 #define REV3 // mbed=rev.106/BLE_API=rev.798/nRF51822=rev.428
yasuyuki 1:6458709fb459 8 //
yasuyuki 0:1dbfda43d8b4 9 // (C)Copyright 2015 All rights reserved by Y.Onodera
yasuyuki 0:1dbfda43d8b4 10 // http://einstlab.web.fc2.com
yasuyuki 0:1dbfda43d8b4 11 //**********************
yasuyuki 0:1dbfda43d8b4 12 #if defined(TARGET_HRM1017)
yasuyuki 0:1dbfda43d8b4 13 #include "mbed.h"
yasuyuki 0:1dbfda43d8b4 14 #include "ADT7410.h"
yasuyuki 2:d5bdd080d451 15 #ifdef REV1
yasuyuki 2:d5bdd080d451 16 #include "BLEDevice.h" // BLEライブラリのヘッダ BLE_API=rev.341
yasuyuki 2:d5bdd080d451 17 #include "BatteryService.h" // BatteryServiceのヘッダ
yasuyuki 2:d5bdd080d451 18 #include "HeartRateService.h" // HeartRateServiceのヘッダ
yasuyuki 2:d5bdd080d451 19 #include "HealthThermometerService.h" // HealthThermometerServiceのヘッダ
yasuyuki 2:d5bdd080d451 20 #endif
yasuyuki 2:d5bdd080d451 21 #ifdef REV2
yasuyuki 2:d5bdd080d451 22 #include "BLE.h" // BLEライブラリのヘッダ BLE_API=rev.738
yasuyuki 2:d5bdd080d451 23 #include "BatteryService.h" // BatteryServiceのヘッダ
yasuyuki 2:d5bdd080d451 24 #include "HeartRateService.h" // HeartRateServiceのヘッダ
yasuyuki 2:d5bdd080d451 25 #include "HealthThermometerService.h" // HealthThermometerServiceのヘッダ
yasuyuki 2:d5bdd080d451 26 #endif
yasuyuki 2:d5bdd080d451 27 #ifdef REV3
yasuyuki 2:d5bdd080d451 28 #include "ble/BLE.h" // BLEライブラリのヘッダ BLE_API=rev.798
yasuyuki 2:d5bdd080d451 29 #include "ble/services/BatteryService.h" // BatteryServiceのヘッダ
yasuyuki 2:d5bdd080d451 30 #include "ble/services/HeartRateService.h" // HeartRateServiceのヘッダ
yasuyuki 2:d5bdd080d451 31 #include "ble/services/HealthThermometerService.h" // HealthThermometerServiceのヘッダ
yasuyuki 2:d5bdd080d451 32 #endif
yasuyuki 0:1dbfda43d8b4 33
yasuyuki 0:1dbfda43d8b4 34 #define THERMO
yasuyuki 0:1dbfda43d8b4 35 //#define HEART
yasuyuki 0:1dbfda43d8b4 36 //#define BATTERY
yasuyuki 0:1dbfda43d8b4 37
yasuyuki 0:1dbfda43d8b4 38 BLEDevice ble; // BLEのインスタンス生成
yasuyuki 0:1dbfda43d8b4 39 DigitalOut led1(LED1);
yasuyuki 0:1dbfda43d8b4 40 DigitalOut led2(LED2);
yasuyuki 0:1dbfda43d8b4 41 DigitalOut sw(P0_0);
yasuyuki 0:1dbfda43d8b4 42 Ticker tick;
yasuyuki 0:1dbfda43d8b4 43 #ifdef THERMO
yasuyuki 0:1dbfda43d8b4 44 I2C i2c(P0_22,P0_20);
yasuyuki 0:1dbfda43d8b4 45 ADT7410 temperature(i2c);
yasuyuki 0:1dbfda43d8b4 46 #endif
yasuyuki 0:1dbfda43d8b4 47
yasuyuki 0:1dbfda43d8b4 48 #define DEVICE_NAME "mbed_BLE"
yasuyuki 0:1dbfda43d8b4 49 // UUIDリスト
yasuyuki 0:1dbfda43d8b4 50 #ifdef THERMO
yasuyuki 0:1dbfda43d8b4 51 uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, GattService::UUID_BATTERY_SERVICE};
yasuyuki 0:1dbfda43d8b4 52 #endif
yasuyuki 0:1dbfda43d8b4 53 #ifdef HEART
yasuyuki 0:1dbfda43d8b4 54 uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, GattService::UUID_BATTERY_SERVICE};
yasuyuki 0:1dbfda43d8b4 55 #endif
yasuyuki 0:1dbfda43d8b4 56 #ifdef BATTERY
yasuyuki 0:1dbfda43d8b4 57 uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE};
yasuyuki 0:1dbfda43d8b4 58 #endif
yasuyuki 0:1dbfda43d8b4 59 bool tickFlag = false;
yasuyuki 0:1dbfda43d8b4 60
yasuyuki 0:1dbfda43d8b4 61
yasuyuki 0:1dbfda43d8b4 62 // インターバルタイマー
yasuyuki 0:1dbfda43d8b4 63 void tickerCallback(void)
yasuyuki 0:1dbfda43d8b4 64 {
yasuyuki 0:1dbfda43d8b4 65 led1 = !led1;
yasuyuki 0:1dbfda43d8b4 66 tickFlag = true;
yasuyuki 0:1dbfda43d8b4 67 }
yasuyuki 0:1dbfda43d8b4 68
yasuyuki 0:1dbfda43d8b4 69
yasuyuki 0:1dbfda43d8b4 70 // BLE接続処理
yasuyuki 2:d5bdd080d451 71 #ifdef REV1
yasuyuki 1:6458709fb459 72 // BLE_API=rev.341
yasuyuki 0:1dbfda43d8b4 73 void connectionCallback(
yasuyuki 0:1dbfda43d8b4 74 Gap::Handle_t handle,
yasuyuki 0:1dbfda43d8b4 75 Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr,
yasuyuki 2:d5bdd080d451 76 const Gap::ConnectionParams_t *params)
yasuyuki 0:1dbfda43d8b4 77 #else
yasuyuki 1:6458709fb459 78 // BLE_API=rev.738
yasuyuki 0:1dbfda43d8b4 79 void connectionCallback(
yasuyuki 1:6458709fb459 80 const Gap::ConnectionCallbackParams_t *params)
yasuyuki 0:1dbfda43d8b4 81 #endif
yasuyuki 0:1dbfda43d8b4 82 {
yasuyuki 0:1dbfda43d8b4 83 led2 = 1;
yasuyuki 2:d5bdd080d451 84 #ifdef REV3
yasuyuki 2:d5bdd080d451 85 ble.gap().stopAdvertising();
yasuyuki 2:d5bdd080d451 86 #else
yasuyuki 0:1dbfda43d8b4 87 ble.stopAdvertising();
yasuyuki 2:d5bdd080d451 88 #endif
yasuyuki 0:1dbfda43d8b4 89 }
yasuyuki 0:1dbfda43d8b4 90
yasuyuki 0:1dbfda43d8b4 91
yasuyuki 0:1dbfda43d8b4 92 // BLE切断処理
yasuyuki 0:1dbfda43d8b4 93 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
yasuyuki 0:1dbfda43d8b4 94 {
yasuyuki 0:1dbfda43d8b4 95 led2 = 0;
yasuyuki 2:d5bdd080d451 96 ble.gap().startAdvertising();
yasuyuki 0:1dbfda43d8b4 97 }
yasuyuki 0:1dbfda43d8b4 98
yasuyuki 0:1dbfda43d8b4 99
yasuyuki 0:1dbfda43d8b4 100 // BLE接続タイムアウト処理
yasuyuki 2:d5bdd080d451 101 #ifdef REV1
yasuyuki 1:6458709fb459 102 // BLE_API=rev.341
yasuyuki 0:1dbfda43d8b4 103 void connectTimeoutCallback(void)
yasuyuki 0:1dbfda43d8b4 104 {
yasuyuki 0:1dbfda43d8b4 105 // to do
yasuyuki 0:1dbfda43d8b4 106 // Sleep
yasuyuki 0:1dbfda43d8b4 107 // __WFE();
yasuyuki 0:1dbfda43d8b4 108 // __SEV();
yasuyuki 0:1dbfda43d8b4 109 // __WFE();
yasuyuki 0:1dbfda43d8b4 110 // System-off
yasuyuki 0:1dbfda43d8b4 111 // NRF_POWER->SYSTEMOFF = 1;
yasuyuki 0:1dbfda43d8b4 112 }
yasuyuki 1:6458709fb459 113 #else
yasuyuki 1:6458709fb459 114 // BLE_API rev.738
yasuyuki 1:6458709fb459 115 void connectTimeoutCallback(Gap::TimeoutSource_t source)
yasuyuki 1:6458709fb459 116 {
yasuyuki 1:6458709fb459 117 }
yasuyuki 1:6458709fb459 118 #endif
yasuyuki 0:1dbfda43d8b4 119
yasuyuki 0:1dbfda43d8b4 120
yasuyuki 0:1dbfda43d8b4 121 void initAdvertising(void)
yasuyuki 0:1dbfda43d8b4 122 {
yasuyuki 0:1dbfda43d8b4 123
yasuyuki 0:1dbfda43d8b4 124 // フラグを設定
yasuyuki 0:1dbfda43d8b4 125 // LE_LIMITED_DISCOVERABLE = 期間限定で検出可能デバイス
yasuyuki 0:1dbfda43d8b4 126 // LE_GENERAL_DISCOVERABLE = 検出可能デバイス
yasuyuki 0:1dbfda43d8b4 127 // BREDR_NOT_SUPPORTED = Bluetooth Classicは未サポート, BLEオンリー
yasuyuki 2:d5bdd080d451 128 #ifdef REV3
yasuyuki 2:d5bdd080d451 129 ble.gap().accumulateAdvertisingPayload(
yasuyuki 2:d5bdd080d451 130 GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED);
yasuyuki 2:d5bdd080d451 131 #else
yasuyuki 0:1dbfda43d8b4 132 ble.accumulateAdvertisingPayload(
yasuyuki 0:1dbfda43d8b4 133 GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED);
yasuyuki 2:d5bdd080d451 134 #endif
yasuyuki 0:1dbfda43d8b4 135 // UUIDリストを設定
yasuyuki 2:d5bdd080d451 136 #ifdef REV3
yasuyuki 2:d5bdd080d451 137 ble.gap().accumulateAdvertisingPayload(
yasuyuki 2:d5bdd080d451 138 GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
yasuyuki 2:d5bdd080d451 139 (uint8_t *)uuid16_list,
yasuyuki 2:d5bdd080d451 140 sizeof(uuid16_list));
yasuyuki 2:d5bdd080d451 141 #else
yasuyuki 0:1dbfda43d8b4 142 ble.accumulateAdvertisingPayload(
yasuyuki 0:1dbfda43d8b4 143 GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
yasuyuki 0:1dbfda43d8b4 144 (uint8_t *)uuid16_list,
yasuyuki 0:1dbfda43d8b4 145 sizeof(uuid16_list));
yasuyuki 2:d5bdd080d451 146 #endif
yasuyuki 0:1dbfda43d8b4 147 // デバイス名を設定(for GAP), default Device Name="nRF5x"
yasuyuki 0:1dbfda43d8b4 148 // ble.setDeviceName(DEVICE_NAME);
yasuyuki 0:1dbfda43d8b4 149 // デバイス名を設定(for Advertising)
yasuyuki 2:d5bdd080d451 150 #ifdef REV3
yasuyuki 2:d5bdd080d451 151 ble.gap().accumulateAdvertisingPayload(
yasuyuki 2:d5bdd080d451 152 GapAdvertisingData::COMPLETE_LOCAL_NAME,
yasuyuki 2:d5bdd080d451 153 (const uint8_t *)DEVICE_NAME,
yasuyuki 2:d5bdd080d451 154 // strlen(DEVICE_NAME));
yasuyuki 2:d5bdd080d451 155 sizeof(DEVICE_NAME));
yasuyuki 2:d5bdd080d451 156 #else
yasuyuki 0:1dbfda43d8b4 157 ble.accumulateAdvertisingPayload(
yasuyuki 0:1dbfda43d8b4 158 GapAdvertisingData::COMPLETE_LOCAL_NAME,
yasuyuki 0:1dbfda43d8b4 159 (const uint8_t *)DEVICE_NAME,
yasuyuki 0:1dbfda43d8b4 160 // strlen(DEVICE_NAME));
yasuyuki 0:1dbfda43d8b4 161 sizeof(DEVICE_NAME));
yasuyuki 2:d5bdd080d451 162 #endif
yasuyuki 0:1dbfda43d8b4 163
yasuyuki 0:1dbfda43d8b4 164 // ADV_CONNECTABLE_UNDIRECTED = 接続可能デバイスに設定
yasuyuki 2:d5bdd080d451 165 #ifdef REV3
yasuyuki 2:d5bdd080d451 166 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
yasuyuki 2:d5bdd080d451 167 #else
yasuyuki 0:1dbfda43d8b4 168 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
yasuyuki 2:d5bdd080d451 169 #endif
yasuyuki 0:1dbfda43d8b4 170
yasuyuki 0:1dbfda43d8b4 171 // アドバタイジング間隔の設定=100ms, 0.625ms単位
yasuyuki 2:d5bdd080d451 172 #ifdef REV3
yasuyuki 2:d5bdd080d451 173 ble.gap().setAdvertisingInterval(160); // 0.625ms * 160 = 100ms
yasuyuki 2:d5bdd080d451 174 // ble.gap().setAdvertisingInterval(1600); // 0.625ms * 1600 = 1000ms
yasuyuki 2:d5bdd080d451 175 #else
yasuyuki 0:1dbfda43d8b4 176 ble.setAdvertisingInterval(160); // 0.625ms * 160 = 100ms
yasuyuki 0:1dbfda43d8b4 177 // ble.setAdvertisingInterval(1600); // 0.625ms * 1600 = 1000ms
yasuyuki 2:d5bdd080d451 178 #endif
yasuyuki 0:1dbfda43d8b4 179
yasuyuki 0:1dbfda43d8b4 180 // Appearance
yasuyuki 0:1dbfda43d8b4 181 #ifdef THERMO
yasuyuki 2:d5bdd080d451 182 #ifdef REV3
yasuyuki 2:d5bdd080d451 183 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR);
yasuyuki 2:d5bdd080d451 184 #else
yasuyuki 0:1dbfda43d8b4 185 ble.accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR);
yasuyuki 0:1dbfda43d8b4 186 #endif
yasuyuki 2:d5bdd080d451 187 #endif
yasuyuki 0:1dbfda43d8b4 188 #ifdef HEART
yasuyuki 2:d5bdd080d451 189 #ifdef REV3
yasuyuki 2:d5bdd080d451 190 // ble.gap().setAppearance(ENERIC_HEART_RATE_SENSOR);
yasuyuki 2:d5bdd080d451 191 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
yasuyuki 2:d5bdd080d451 192 #else
yasuyuki 0:1dbfda43d8b4 193 // ble.setAppearance(ENERIC_HEART_RATE_SENSOR);
yasuyuki 0:1dbfda43d8b4 194 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
yasuyuki 0:1dbfda43d8b4 195 #endif
yasuyuki 2:d5bdd080d451 196 #endif
yasuyuki 0:1dbfda43d8b4 197 // アドバタイジングタイムアウト=180sec(デフォルトは0でタイムアウトなし)
yasuyuki 0:1dbfda43d8b4 198 // ble.setAdvertisingTimeout(180);
yasuyuki 2:d5bdd080d451 199
yasuyuki 0:1dbfda43d8b4 200 // アドバタイジング開始
yasuyuki 2:d5bdd080d451 201 #ifdef REV3
yasuyuki 2:d5bdd080d451 202 ble.gap().startAdvertising();
yasuyuki 2:d5bdd080d451 203 #else
yasuyuki 0:1dbfda43d8b4 204 ble.startAdvertising();
yasuyuki 2:d5bdd080d451 205 #endif
yasuyuki 0:1dbfda43d8b4 206 }
yasuyuki 0:1dbfda43d8b4 207
yasuyuki 0:1dbfda43d8b4 208
yasuyuki 0:1dbfda43d8b4 209 int main(void)
yasuyuki 0:1dbfda43d8b4 210 {
yasuyuki 0:1dbfda43d8b4 211 led1 = 0;
yasuyuki 0:1dbfda43d8b4 212 led2 = 0;
yasuyuki 0:1dbfda43d8b4 213 sw = 1; // off
yasuyuki 0:1dbfda43d8b4 214
yasuyuki 0:1dbfda43d8b4 215 ble.init(); // BLE(nRF51822)の初期化
yasuyuki 0:1dbfda43d8b4 216 // Valid values are -40, -20, -16, -12, -8, -4, 0, 4)
yasuyuki 0:1dbfda43d8b4 217 if(ble.setTxPower(-40)!=BLE_ERROR_NONE)
yasuyuki 0:1dbfda43d8b4 218 led2 = 1;
yasuyuki 0:1dbfda43d8b4 219
yasuyuki 0:1dbfda43d8b4 220 // バッテリ残量のイベント関数を設定
yasuyuki 0:1dbfda43d8b4 221 tick.attach(&tickerCallback, 1);
yasuyuki 0:1dbfda43d8b4 222
yasuyuki 0:1dbfda43d8b4 223 // BLEのイベント関数を設定
yasuyuki 2:d5bdd080d451 224 #ifdef REV3
yasuyuki 2:d5bdd080d451 225 ble.gap().onConnection(connectionCallback);
yasuyuki 2:d5bdd080d451 226 ble.gap().onDisconnection(disconnectionCallback);
yasuyuki 2:d5bdd080d451 227 ble.gap().onTimeout(connectTimeoutCallback);
yasuyuki 2:d5bdd080d451 228 #else
yasuyuki 0:1dbfda43d8b4 229 ble.onConnection(connectionCallback);
yasuyuki 0:1dbfda43d8b4 230 ble.onDisconnection(disconnectionCallback);
yasuyuki 0:1dbfda43d8b4 231 ble.onTimeout(connectTimeoutCallback);
yasuyuki 2:d5bdd080d451 232 #endif
yasuyuki 0:1dbfda43d8b4 233
yasuyuki 0:1dbfda43d8b4 234 // BatteryServiceのインスタンス生成=サービスを登録
yasuyuki 0:1dbfda43d8b4 235 uint8_t batt=0;
yasuyuki 0:1dbfda43d8b4 236 BatteryService bs(ble);
yasuyuki 0:1dbfda43d8b4 237
yasuyuki 0:1dbfda43d8b4 238 #ifdef THERMO
yasuyuki 0:1dbfda43d8b4 239 // HeathTermometerServiceのインスタンス生成=サービスを登録
yasuyuki 0:1dbfda43d8b4 240 float currentTemperature = 0.0;
yasuyuki 0:1dbfda43d8b4 241 HealthThermometerService ts(ble, currentTemperature, HealthThermometerService::LOCATION_EAR);
yasuyuki 0:1dbfda43d8b4 242 #endif
yasuyuki 0:1dbfda43d8b4 243 #ifdef HEART
yasuyuki 0:1dbfda43d8b4 244 // HeartRateServiceのインスタンス生成=サービスを登録
yasuyuki 0:1dbfda43d8b4 245 uint8_t hrmCounter = 100;
yasuyuki 0:1dbfda43d8b4 246 HeartRateService hr(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
yasuyuki 0:1dbfda43d8b4 247 #endif
yasuyuki 0:1dbfda43d8b4 248
yasuyuki 0:1dbfda43d8b4 249 // アドバタイジングの設定
yasuyuki 0:1dbfda43d8b4 250 initAdvertising();
yasuyuki 0:1dbfda43d8b4 251
yasuyuki 0:1dbfda43d8b4 252 // イベント待ちループ
yasuyuki 0:1dbfda43d8b4 253 while(true) {
yasuyuki 0:1dbfda43d8b4 254 ble.waitForEvent();
yasuyuki 0:1dbfda43d8b4 255 if(tickFlag){
yasuyuki 0:1dbfda43d8b4 256 // バッテリ残量の取り込み
yasuyuki 0:1dbfda43d8b4 257 if(++batt>100)batt=0;
yasuyuki 0:1dbfda43d8b4 258 // バッテリ残量のデータ更新
yasuyuki 0:1dbfda43d8b4 259 bs.updateBatteryLevel(batt);
yasuyuki 0:1dbfda43d8b4 260 #ifdef THERMO
yasuyuki 0:1dbfda43d8b4 261 sw = 0; // on
yasuyuki 0:1dbfda43d8b4 262 // currentTemperature-=0.1;
yasuyuki 0:1dbfda43d8b4 263 wait_ms(100);
yasuyuki 0:1dbfda43d8b4 264 currentTemperature=temperature.value()/128.0;
yasuyuki 0:1dbfda43d8b4 265 ts.updateTemperature(currentTemperature);
yasuyuki 0:1dbfda43d8b4 266 sw = 1; // off
yasuyuki 0:1dbfda43d8b4 267 #endif
yasuyuki 0:1dbfda43d8b4 268 #ifdef HEART
yasuyuki 0:1dbfda43d8b4 269 hr.updateHeartRate(hrmCounter);
yasuyuki 0:1dbfda43d8b4 270 #endif
yasuyuki 0:1dbfda43d8b4 271 tickFlag = false;
yasuyuki 0:1dbfda43d8b4 272 }
yasuyuki 0:1dbfda43d8b4 273 }
yasuyuki 0:1dbfda43d8b4 274 }
yasuyuki 0:1dbfda43d8b4 275
yasuyuki 0:1dbfda43d8b4 276 #endif
yasuyuki 0:1dbfda43d8b4 277