BLE Nano でLED制御 ~BLE Nano + NeoPixel + Android~


BLE Nano で NeoPixel の LED 制御と、BLE GATT 通信を確認したので、今度は、この2つを合わせていきます。

BLE Nano のバイナリ作成

まず、BLE Nano の制御プログラムを作っています。

NeoPixel のライブラリの組み込み

BLE GATT 通信のサンプルコードに、NeoPixel の制御用ライブラリ組み込んでいきます。

前の記事 で利用した RedBearNano_NeoPixels_Example の中から、次の2つのソースを BLE_GATT_Example にコピーします。

  • neopixel.cpp
  • neopixel.h

そして、main.cpp で neopixel.h を読み込み、m_strip をグローバル変数として宣言しておきます。

main.cpp
#include "neopixel.h"
neopixel_strip_t m_strip;

そして、main 関数の中で、NeoPixel の初期化コードを追加します。

main()
    uint8_t dig_pin_num = P0_15;
    uint8_t leds_per_strip = 8;
    // (中略)
    neopixel_init(&m_strip, dig_pin_num, leds_per_strip);
    neopixel_clear(&m_strip);

なお、NeoPixel への制御信号を出力するピンを P0_15 に変更しています。

GATT 通信に応じた LED の表示内容の変更を追加

GATT の writeCharacteristics への書き込みがあった際に呼び出される writeCharCallback 関数に手を加えていきます。

サンプルコードで BLE Nano 上の LED on/off しているコードを探します。

writeCharCallback()
        if(params->len == 1) {
            led = params->data[0];
            (params->data[0] == 0x00) ? printf("led on\n\r") : printf("led off\n\r"); // print led toggle
        }

ここに、NeoPixel のLED を制御するコードを追加します。

writeCharCallback()
    uint8_t error;
    uint8_t led_to_enable = 1;
    uint8_t red = 255;
    uint8_t green = 0;
    uint8_t blue = 159;
    // (中略)
        if(params->len == 1) {
            led = params->data[0];

            if (params->data[0] == 0x00) {
                printf("led on\n\r");
                error = neopixel_set_color(&m_strip, led_to_enable, red, green, blue);
            } else {
                printf("led off\n\r");
                error = neopixel_set_color(&m_strip, led_to_enable, 0, 0, 0);
            }
        }

組み込んだ NeoPixel のライブラリでは、LED を ON にするには、neopixel_set_color_and_show を使います。
ただし、BLE スタックと同時に使う場合には、neopixel_set_color と neopixel_show に分けるように注意書きがあります。
(https://github.com/lavallc/nrf51-neopixel/blob/master/neopixel.c)

そこで、GATT通信受信時の callback 関数では、neopixel_set_color で色を指定します。
そして、無線非 active 時に、NeoPixel に制御信号を送ります(後述)。

ここでは、"00" を受信した場合は、led_to_enable(=1)番目のLEDにRGB(255,0,159)の色を表示するように値をセットします。
また、"00"以外の場合は、RGB(0,0,0)の値ををセットします。

BLE radio notification の設定

次に、無線が非 active 時に、NeoPixel に制御信号を送る部分を作成していきます。

main.cpp
#include "ble_radio_notification.h"

void radio_callback_handler(bool radio_active)
{
    if (radio_active == false)
    {
        neopixel_show(&m_strip);
    }
}
main()
    // (中略)
    ble.init(bleInitComplete);
    ble_radio_notification_init(NRF_APP_PRIORITY_LOW,
                                  NRF_RADIO_NOTIFICATION_DISTANCE_800US,
                                  radio_callback_handler);

ble_radio_notification_init で、無線が active / 非active に切り替わる際の event handler を登録します。
1番目の引数は割込みの優先順位、2番目は event 発生までの時間差になるようです。
3番目の引数で handler として radio_callback_handler を指定します。

そして、radio_callback_handler の中で、無線が非active のときに neopixel_show を呼び出します。
これで、NeoPixel に制御信号が送られます。

動作を確認する

LED の制御ピンを P0_8 から P0_15 に変更したので、LED への配線を変更しています。

前記事 のように Android のアプリ(nRF Master Control Panel) を使って、"00" の値を書き込むと、無事点灯しました。

なお、制御ピンですが、P0_8 のままでは動作しませんでした。
原因はちゃんと追求していませんが、P0_8 は STDIO や SPI の制御ピンでもあるので、その影響かもしれません。

(BLE Nano のピンレイアウトは http://redbearlab.com/blenano/ にあります)

とりあえず、空いている P0_15 に変更してみると無事動作しました。
ただ、この P0_15 ピンは横に出るので配線が難しくなります。
そこで、P0_5 ピンに変更してみたところ、P0_5 でも無事動きました。

(2016年7月21日 修正 mt08 さん、コメントありがとうございました!)