BLE_Health_Thermometer for mbed HRM1017 with BLE library 0.1.0

Dependencies:   BLE_API TMP102 mbed nRF51822

Fork of BLE_Health_Thermometer2 by Ken Todotani

BLE_Health_Thermometer2 010

<2014/9/7更新:BLEライブラリを0.1.0から0.1.1に更新しました> <2014/9/13更新:mbed標準ライブラリ89版に対応しました> mbed HRM1017をはじめように掲載されている、https://mbed.org/users/ytsuboi/code/BLE_Health_Thermometer_IRC/をBLE ライブラリ0.1.1に移植しました。 前回公開したhttp://mbed.org/users/todotani/code/BLE_Health_Thermometer2/からさらに新ライブラリ0.1.1に対応するための各種修正を加えています。0.1.1では、0.1.0の問題点が修正されました。修正点は以下の通りです。

  • ライブラリ0.1.1を使うためには、mbedライブラリをDevelopment版である、mbed-srcに変更します。<追記>標準ライブラリ89版からBLEライブラリ 0.1.1を含むコードがコンパイル出来るようになりました。
  • mbed-srcのクロッククロック設定が外部クロックになっているため、HRM1017で使用する内部クロック設定に変更します。mbed-src/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51822.cを以下のように修正します。<追記>mbed 89版では、以下の変更が盛り込まれているため修正は不要です。

system_nrf51822.cの変更

#ifdef TARGET_HRM1017
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
#else
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
#endif
  • nRF51822/btle/btle.cpp を以下のように変更し、内部クロックを選択するようにします(この変更は以前から必要なものでした)。<追記>この変更はnRF51822 library 0.1.3で盛り込まれましたので、修正は不要です。

btle.cppの変更1

#ifdef TARGET_HRM1017
    SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, false);
#else
    SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, useScheduler);
#endif
  • btle.cppのbtle_handler関数を以下のように修正します。この変更は、disconnected.reasonが1種類しか定義されていないために、disconnectionCallback関数が呼ばれない問題を回避するためです。<追記> nRF51822 library 0.1.3では以下の変更が盛り込まれたため、修正は不要です。

btle.cppの変更2

        case BLE_GAP_EVT_DISCONNECTED: {
            Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
            // Since we are not in a connection and have not started advertising,
            // store bonds
            nRF51Gap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
#if NEED_BOND_MANAGER /* disabled by default */
            ASSERT_STATUS_RET_VOID ( ble_bondmngr_bonded_centrals_store());
#endif

            Gap::DisconnectionReason_t reason;
            switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
                case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
                    reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
                    break;
                case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
                    reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
                    break;
                case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
                    reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
                    break;
                default:
                    /* Please refer to the underlying transport library for an
                     * interpretion of this reason's value. */
                    reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
                    break;
            }
            nRF51Gap::getInstance().processDisconnectionEvent(handle, reason);
            break;
        }
  • main.cppにTickerを設定して以下のような処理を周期的に実行するようにします。こうすることで、waitForEvent()関数から抜けるようにします。0.1.0以降では、waitForEvent()の呼び出しでCPUがスリープするようで、CPUを起床させるために割り込みかける以下の方法が正しい使い方と言えます。

Tickerの使用

void periodicCallback(void)
{
    oneSecondLed = !oneSecondLed; /* Do blinky on LED1 while we're waiting for BLE events */

    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
     * heavy-weight sensor polling from the main thread. */
    triggerSensorPolling = true;
}
  • main.cppで定義するイベントハンドラ関数の引数が以下のように追加されています。新ライブラリのAPI変更に対応したコード変更になります。

EventHandler

void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
void onConnectionCallback(Gap::Handle_t handle, const Gap::ConnectionParams_t *params)
  • main.cppで呼び出すupdateCharacteristicValueの引数が、以前のtempChar.getHandle()から変更されています。こちらも、新ライブラリのAPI変更に対応したコード変更になります。

updateCharacteristicValue

ble.updateCharacteristicValue(tempChar.getValueAttribute().getHandle(), thermTempPayload, sizeof(thermTempPayload));
ble.updateCharacteristicValue(battLevel.getValueAttribute().getHandle(), (uint8_t *)&batt, sizeof(batt));
  • @robo8080 さんの情報で、nRF51822/projectconfig.hを書き換えなくても以下のコードで、Device名が設定出来ることが分かりました。

DeviceName

ble.setDeviceName(unit8_t *DEVICE_NAME);
  • あと、iOSを使っている方で、mbedのBLEソフトを入れ替えてGATTの内容がが変わるような場合は、iOSデバイスのBluetoothをoff/onしないと変更が反映されず、接続しても情報が表示されないような状態になることがあります。この点も、ご注意を。

プログラム全体は以下の通りです。

Import programBLE_Health_Thermometer2-010

BLE_Health_Thermometer for mbed HRM1017 with BLE library 0.1.0


All wikipages