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 をグローバル変数として宣言しておきます。
#include "neopixel.h"
neopixel_strip_t m_strip;
そして、main 関数の中で、NeoPixel の初期化コードを追加します。
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 しているコードを探します。
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 を制御するコードを追加します。
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 に制御信号を送る部分を作成していきます。
#include "ble_radio_notification.h"
void radio_callback_handler(bool radio_active)
{
if (radio_active == false)
{
neopixel_show(&m_strip);
}
}
// (中略)
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 さん、コメントありがとうございました!)