BLE

Dependencies:   ADT7410 BLE_API mbed nRF51822

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

Revision:
0:1dbfda43d8b4
Child:
1:6458709fb459
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jun 22 22:01:52 2015 +0000
@@ -0,0 +1,202 @@
+//**********************
+// BLE demo for mbed_HRM1017
+//
+// (C)Copyright 2015 All rights reserved by Y.Onodera
+// http://einstlab.web.fc2.com
+//**********************
+#if defined(TARGET_HRM1017)
+#include "mbed.h"
+#include "ADT7410.h"
+#include "BLEDevice.h"              // BLEライブラリのヘッダ
+#include "BatteryService.h"         // BatteryServiceのヘッダ
+#include "HeartRateService.h"       // HeartRateServiceのヘッダ
+#include "HealthThermometerService.h" // HealthThermometerServiceのヘッダ
+
+#define THERMO
+//#define HEART
+//#define BATTERY
+
+BLEDevice  ble;          // BLEのインスタンス生成
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut sw(P0_0);
+Ticker     tick;
+#ifdef THERMO
+I2C i2c(P0_22,P0_20);
+ADT7410 temperature(i2c);
+#endif
+
+#define DEVICE_NAME "mbed_BLE"
+// UUIDリスト
+#ifdef THERMO
+uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, GattService::UUID_BATTERY_SERVICE};
+#endif
+#ifdef HEART
+uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, GattService::UUID_BATTERY_SERVICE};
+#endif
+#ifdef BATTERY
+uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE};
+#endif
+bool tickFlag = false;
+
+
+// インターバルタイマー
+void tickerCallback(void)
+{
+    led1 = !led1;
+    tickFlag = true;
+}
+
+
+// BLE接続処理
+#define OLD
+#ifdef OLD
+// old version BLE_API until rev.341
+void connectionCallback(
+Gap::Handle_t handle, 
+Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, 
+const Gap::ConnectionParams_t *params) 
+#else
+// new version
+void connectionCallback(
+Gap::Handle_t handle,
+Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr,
+Gap::addr_type_t ownAddrType, const Gap::address_t ownAddr,
+const Gap::ConnectionParams_t *params)
+#endif
+{
+    led2 = 1;
+    ble.stopAdvertising();
+}
+
+
+// BLE切断処理
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) 
+{
+    led2 = 0;
+    ble.startAdvertising();
+}
+
+
+// BLE接続タイムアウト処理
+void connectTimeoutCallback(void)
+{
+    // to do
+//  Sleep
+//  __WFE();
+//  __SEV();
+//  __WFE();
+//  System-off
+//  NRF_POWER->SYSTEMOFF = 1;
+}
+
+
+void initAdvertising(void)
+{
+
+    // フラグを設定
+    //   LE_LIMITED_DISCOVERABLE = 期間限定で検出可能デバイス
+    //   LE_GENERAL_DISCOVERABLE = 検出可能デバイス
+    //   BREDR_NOT_SUPPORTED = Bluetooth Classicは未サポート, BLEオンリー
+    ble.accumulateAdvertisingPayload(
+        GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    // UUIDリストを設定
+    ble.accumulateAdvertisingPayload(
+        GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
+        (uint8_t *)uuid16_list,
+        sizeof(uuid16_list));
+    // デバイス名を設定(for GAP), default Device Name="nRF5x"
+//    ble.setDeviceName(DEVICE_NAME);
+    // デバイス名を設定(for Advertising)
+    ble.accumulateAdvertisingPayload(
+        GapAdvertisingData::COMPLETE_LOCAL_NAME,
+        (const uint8_t *)DEVICE_NAME, 
+//        strlen(DEVICE_NAME));
+      sizeof(DEVICE_NAME));
+
+    // ADV_CONNECTABLE_UNDIRECTED = 接続可能デバイスに設定
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+
+    // アドバタイジング間隔の設定=100ms, 0.625ms単位
+    ble.setAdvertisingInterval(160);  // 0.625ms * 160 = 100ms
+//    ble.setAdvertisingInterval(1600);   // 0.625ms * 1600 = 1000ms
+
+    // Appearance
+#ifdef THERMO
+      ble.accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR);
+#endif
+#ifdef HEART
+//    ble.setAppearance(ENERIC_HEART_RATE_SENSOR);
+      ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
+#endif
+    // アドバタイジングタイムアウト=180sec(デフォルトは0でタイムアウトなし)
+//    ble.setAdvertisingTimeout(180);
+    // アドバタイジング開始
+    ble.startAdvertising();
+
+}
+
+
+int main(void)
+{
+    led1 = 0;
+    led2 = 0;
+    sw = 1; // off
+
+    ble.init(); // BLE(nRF51822)の初期化
+    // Valid values are -40, -20, -16, -12, -8, -4, 0, 4)
+    if(ble.setTxPower(-40)!=BLE_ERROR_NONE)
+        led2 = 1;
+
+    // バッテリ残量のイベント関数を設定
+    tick.attach(&tickerCallback, 1);
+
+    // BLEのイベント関数を設定
+    ble.onConnection(connectionCallback);
+    ble.onDisconnection(disconnectionCallback);
+    ble.onTimeout(connectTimeoutCallback);
+
+    // BatteryServiceのインスタンス生成=サービスを登録
+    uint8_t batt=0;
+    BatteryService bs(ble);
+
+#ifdef THERMO
+    // HeathTermometerServiceのインスタンス生成=サービスを登録
+    float currentTemperature = 0.0;
+    HealthThermometerService ts(ble, currentTemperature, HealthThermometerService::LOCATION_EAR);
+#endif
+#ifdef HEART
+    // HeartRateServiceのインスタンス生成=サービスを登録
+    uint8_t hrmCounter = 100;
+    HeartRateService hr(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
+#endif
+
+    // アドバタイジングの設定
+    initAdvertising();
+
+    // イベント待ちループ
+    while(true) {
+        ble.waitForEvent();
+        if(tickFlag){
+            // バッテリ残量の取り込み
+            if(++batt>100)batt=0;
+            // バッテリ残量のデータ更新
+            bs.updateBatteryLevel(batt);
+#ifdef THERMO
+            sw = 0; // on
+//            currentTemperature-=0.1;
+            wait_ms(100);
+            currentTemperature=temperature.value()/128.0;
+            ts.updateTemperature(currentTemperature);
+            sw = 1; // off
+#endif
+#ifdef HEART
+            hr.updateHeartRate(hrmCounter);
+#endif
+            tickFlag = false;
+        }
+    }
+}
+
+#endif
+