BLE
Dependencies: ADT7410 BLE_API mbed nRF51822
See https://developer.mbed.org/users/yasuyuki/notebook/BLE/
main.cpp
- Committer:
- yasuyuki
- Date:
- 2015-09-09
- Revision:
- 2:d5bdd080d451
- Parent:
- 1:6458709fb459
File content as of revision 2:d5bdd080d451:
//**********************
// BLE demo for mbed_HRM1017
//
// successful combination
//#define REV1 // mbed=rev.97/BLE_API=rev.341/nRF51822=rev.111
//#define REV2 // mbed=rev.101/BLE_API=rev.738/nRF51822=rev.385
#define REV3 // mbed=rev.106/BLE_API=rev.798/nRF51822=rev.428
//
// (C)Copyright 2015 All rights reserved by Y.Onodera
// http://einstlab.web.fc2.com
//**********************
#if defined(TARGET_HRM1017)
#include "mbed.h"
#include "ADT7410.h"
#ifdef REV1
#include "BLEDevice.h" // BLEライブラリのヘッダ BLE_API=rev.341
#include "BatteryService.h" // BatteryServiceのヘッダ
#include "HeartRateService.h" // HeartRateServiceのヘッダ
#include "HealthThermometerService.h" // HealthThermometerServiceのヘッダ
#endif
#ifdef REV2
#include "BLE.h" // BLEライブラリのヘッダ BLE_API=rev.738
#include "BatteryService.h" // BatteryServiceのヘッダ
#include "HeartRateService.h" // HeartRateServiceのヘッダ
#include "HealthThermometerService.h" // HealthThermometerServiceのヘッダ
#endif
#ifdef REV3
#include "ble/BLE.h" // BLEライブラリのヘッダ BLE_API=rev.798
#include "ble/services/BatteryService.h" // BatteryServiceのヘッダ
#include "ble/services/HeartRateService.h" // HeartRateServiceのヘッダ
#include "ble/services/HealthThermometerService.h" // HealthThermometerServiceのヘッダ
#endif
#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接続処理
#ifdef REV1
// BLE_API=rev.341
void connectionCallback(
Gap::Handle_t handle,
Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr,
const Gap::ConnectionParams_t *params)
#else
// BLE_API=rev.738
void connectionCallback(
const Gap::ConnectionCallbackParams_t *params)
#endif
{
led2 = 1;
#ifdef REV3
ble.gap().stopAdvertising();
#else
ble.stopAdvertising();
#endif
}
// BLE切断処理
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
led2 = 0;
ble.gap().startAdvertising();
}
// BLE接続タイムアウト処理
#ifdef REV1
// BLE_API=rev.341
void connectTimeoutCallback(void)
{
// to do
// Sleep
// __WFE();
// __SEV();
// __WFE();
// System-off
// NRF_POWER->SYSTEMOFF = 1;
}
#else
// BLE_API rev.738
void connectTimeoutCallback(Gap::TimeoutSource_t source)
{
}
#endif
void initAdvertising(void)
{
// フラグを設定
// LE_LIMITED_DISCOVERABLE = 期間限定で検出可能デバイス
// LE_GENERAL_DISCOVERABLE = 検出可能デバイス
// BREDR_NOT_SUPPORTED = Bluetooth Classicは未サポート, BLEオンリー
#ifdef REV3
ble.gap().accumulateAdvertisingPayload(
GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED);
#else
ble.accumulateAdvertisingPayload(
GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED);
#endif
// UUIDリストを設定
#ifdef REV3
ble.gap().accumulateAdvertisingPayload(
GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
(uint8_t *)uuid16_list,
sizeof(uuid16_list));
#else
ble.accumulateAdvertisingPayload(
GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
(uint8_t *)uuid16_list,
sizeof(uuid16_list));
#endif
// デバイス名を設定(for GAP), default Device Name="nRF5x"
// ble.setDeviceName(DEVICE_NAME);
// デバイス名を設定(for Advertising)
#ifdef REV3
ble.gap().accumulateAdvertisingPayload(
GapAdvertisingData::COMPLETE_LOCAL_NAME,
(const uint8_t *)DEVICE_NAME,
// strlen(DEVICE_NAME));
sizeof(DEVICE_NAME));
#else
ble.accumulateAdvertisingPayload(
GapAdvertisingData::COMPLETE_LOCAL_NAME,
(const uint8_t *)DEVICE_NAME,
// strlen(DEVICE_NAME));
sizeof(DEVICE_NAME));
#endif
// ADV_CONNECTABLE_UNDIRECTED = 接続可能デバイスに設定
#ifdef REV3
ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
#else
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
#endif
// アドバタイジング間隔の設定=100ms, 0.625ms単位
#ifdef REV3
ble.gap().setAdvertisingInterval(160); // 0.625ms * 160 = 100ms
// ble.gap().setAdvertisingInterval(1600); // 0.625ms * 1600 = 1000ms
#else
ble.setAdvertisingInterval(160); // 0.625ms * 160 = 100ms
// ble.setAdvertisingInterval(1600); // 0.625ms * 1600 = 1000ms
#endif
// Appearance
#ifdef THERMO
#ifdef REV3
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR);
#else
ble.accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR);
#endif
#endif
#ifdef HEART
#ifdef REV3
// ble.gap().setAppearance(ENERIC_HEART_RATE_SENSOR);
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
#else
// ble.setAppearance(ENERIC_HEART_RATE_SENSOR);
ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
#endif
#endif
// アドバタイジングタイムアウト=180sec(デフォルトは0でタイムアウトなし)
// ble.setAdvertisingTimeout(180);
// アドバタイジング開始
#ifdef REV3
ble.gap().startAdvertising();
#else
ble.startAdvertising();
#endif
}
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のイベント関数を設定
#ifdef REV3
ble.gap().onConnection(connectionCallback);
ble.gap().onDisconnection(disconnectionCallback);
ble.gap().onTimeout(connectTimeoutCallback);
#else
ble.onConnection(connectionCallback);
ble.onDisconnection(disconnectionCallback);
ble.onTimeout(connectTimeoutCallback);
#endif
// 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