BLE

Dependencies:   ADT7410 BLE_API mbed nRF51822

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

main.cpp

Committer:
yasuyuki
Date:
2015-06-22
Revision:
0:1dbfda43d8b4
Child:
1:6458709fb459

File content as of revision 0:1dbfda43d8b4:

//**********************
// 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