0

BLE NanoをArduino IDEで開発する

BlendMicro npmが自動再接続・複数接続できるようになった
で、BLE Nanoにも接続できるっぽいと書いた。今やってる

BLENano実機の開発環境が手に入ったのでセットアップしたメモを書いておく。

BLE Nano

写真の上の部分がBLE Nanoで、下はそれにUSBインタフェースを追加するMK20 USBボード。プログラムを書き込む時だけ下が必要で、デプロイする時は上の部分だけで良い。
なおBLE Nanoは12ピンでMK20は14ピン、1ピンずつ余るけど差し間違えると死ぬ可能性があるので注意。写真のようにUSBコネクタ側を余らせ、USBコネクタと反対側に白いアンテナとRedBearLabのクママークが来るようにする

BlendMicroとの違い

BLE Nanoと似たものにBlendMicroがあるが、これは普通のAVRマイコンを使ったArduinoにnRF8001というBLEチップを外付けして、その間の通信が簡単にできるArduinoライブラリとセットにしたボード。

それに対してBLE NanoはBLEの機能が内蔵されたnRF51822というARM CPUと、電源のレギュレータや無線アンテナなどを1枚の基板に載せたマイコンボード。

ワンチップに全て入っているので、外付けBLEモジュールと通信してるBlendMicroよりもBLEのより細かい機能を扱える。サンプルコードを見るとBLEのCentral(スマホやPC側の動作)として動かす例なんかもあって、だいたい何でもできそう。
またICが1つだけなので消費電力も低いらしく、ボタン電池で動く。

買う

スイッチサイエンスで売ってる

Amazonにもある
RedBearLab BLE Nanoキット
RedBearLab BLE Nanoキット
posted with amazlet at 15.12.03
スイッチサイエンス


開発方法

開発方法は2通りあって、mbedのオンラインコンパイラを使うか、Arduino IDE用のプラグインを入れてArduino風のAPIで開発もできる。

Arduino風に開発する方は、digitalWriteやanalogRead等のIO操作やdelay(msec)などのArduino互換の関数があるだけで、BLE操作の部分はふつうにmbedのC++のライブラリをincludeして行うのであまり関係ない気もする。
そして何より、ひとたびBLEを動かし始めたらmainループの中でble.waitForEvent()を呼んで、あとは全てイベント駆動で書かなければならないのでどれだけ既存のArduinoライブラリが動くかわからない。
イベント駆動についてはIntroduction to mbed BLEに書いてあるが、ようするに基本的にTickerという定期的に関数を呼び出してくれるタイマーか、BLEのデータ受信イベント等にコールバック関数を登録してアプリケーションを書く事になり、mainループは使わない。

そう考えるとArduino風に書けるメリットはあんまり無いような??気がしてきたけど、オンラインコンパイラなしで、ネットワークの無い所でも開発できるのでArduino IDE拡張の方が個人的には好きかも。(mbedオンラインコンパイラよりemacsで書いて+GitHubで管理したいし)


mbedオンラインコンパイラで開発する

web上にあるIDEで開発して、コンパイルするとhexバイナリをダウンロードできる。
BLENanoをMacにUSB接続すると /Volumes/MBED にマウントされるので、そこにhexファイルをコピーする。BLE Nanoが自動的に再起動して、hexが読み込まれ実行される。

たとえばURI BeaconのチュートリアルにあるBLE_URIBeaconというプログラムを書き込むと、PhysicalWebのURI Beaconが作れる。Androidアプリから見れるはず。
mbedオンラインコンパイラで公開されているプロジェクトは自分のアカウントにforkして読み込んで自由に編集できるので、試してみるとよい。


BLE NanoのArduino風開発環境セットアップ

2ステップ必要
  1. BLE NanoをArduino化して
  2. Arduino IDEにプラグインをインストールする
Getting Started – nRF51822 — RedBearLabの下の方にある説明よりも、
https://github.com/RedBearLab/nRF51822-Arduino
の説明の方が新しくて正しい。
とくに最近ArduinoはパッケージマネージャがついてBLENanoもそれに乗せて配布されるようになっているので、最新のインストール方法はgithubのREADMEを見たほうが良さそう。


BLE NanoにArduinoファームウェアをインストールする


https://github.com/RedBearLab/nRF51822-Arduino
をgit cloneしてきて、bootloaderをインストールする

% cp ./bootloader/bootloader.hex /Volumes/MBED/

Arduino IDEにプラグインをインストールする

https://github.com/RedBearLab/nRF51822-Arduinoに書いてあるバージョンのArduino IDEをダウンロードする。
現在は1.6.5が指定されている。最初1.6.6でやっていたんだけどExamplesが読み込めなかったので1.6.5に戻した。マイナーバージョンが違うだけで動かないなんて…

[Arduino]->[Preferences]から[Boards Manager URLs]にRedBearLabのjsonを追加してから、
[Tools]->[Board]->[Boards Manager]で「RedBearLab nRF51822 Boards」を追加する。

この手のArduino IDEをいじる系はBlendMicroやDigiSparkなど色々あるけど皆違うバージョンを指定しているので、俺は.appの名前を変えて複数保存している。


Arduino IDEでBLENanoを開発する

ToolsのBoardとPortをBLENanoに設定してから、とりあえずExamplesの[Basic]->[Blink]をそのまま書き込んだら、動いた。
基板裏面のLEDが13番ピンに接続されているらしい。


BLEの例は、SimpleChatを書き込んでからblendmicro npm付属のblendmicroコマンドで探したら見つかった。「TXRX」というのがそれ。


これでとりあえずプログラムが書き込める事が確認できた。

0

BlendMicro npmが自動再接続・複数接続できるようになった

BLE接続のArduinoマイコンボードBlendMicroと簡単に通信できるnodeライブラリをアップデートした。

https://www.npmjs.com/package/blendmicro
v0.2.3になった。

普通BLEで通信しようとすると、PeripheralをScanしてServiceを探してTXとRXを探して……とかなり面倒な実装をしなければならないのだが、このライブラリを使うとマイコン側のble_set_name関数で指定した名前で探して接続まで全部やってくれるのでとても簡単に通信ができる。


自動再接続

BlendMicroと距離が離れて電波が通らなくなったり、太陽電池で動かしていて電源が落ちたりした時に、自動的に再scanしてちゃんと再接続できるようになった。
この機能はデフォルトで有効になっている。

というかもともと再接続は実装していたんだけどバグがあったのでちゃんと直した。3日ぐらい動かしっぱなしにしていて調子が良かったのでリリースした。

blendmicro.reconnect = false;
を指定すると無効にできる。

複数のBlendMicroへの同時接続


今までは1つのNodeプロセスから1つのBlendMicroにしか接続できなかったんだけど、うまくイベント管理したら複数同時接続できるようになった。

これはblendmicro npmを内部で使っているble-firmataでも使えるので、例えばこういう風に複数のBlendMicroに接続してそれぞれアナログ入出力させたりが簡単に書ける。

var BLEFirmata = require('ble-firmata');

var devices = [ "BlendMicro", "device2", "device3" ];

devices.map(function(device_name){
return new BLEFirmata().connect(device_name);
}).forEach(function(arduino){

arduino.on('connect', function(){
console.log("connect!!" + arduino.peripheralName);
console.log("board version: "+arduino.boardVersion);
});

arduino.once('connect', function(){
setInterval(function(){
var an = Math.random()*255;
arduino.analogWrite(13, an);
console.log(arduino.peripheralName + " -> " + arduino.analogRead(0));
}, 100);
});

});

もちろん複数台でも切断時再接続される。

BLENanoと通信できるようになった

BlendMicroと同じRedBearLabが作っているBLENanoという、もうひと回り小さいボードと通信できた。

俺はBLENanoを持っていないんだけど、hiraku君がBLENanoのサンプルコードの一つであるSimpleChatを書き込んだBLENanoを持っていてそれと通信させてもらったら通った。
SimpleChatの上の方に書いてあるService/TX/RXのUUIDがBlendMicroと同じなので、特に何も変更せずに動くことが確認できた。

なおBLENanoが手元にないのでble-firmataのBLENano版ファームウェアが書けないのだが、たぶんBLEFirmataSketch.inoを少し修正すれば動くと思うので誰か作って欲しい

add BLENano Firmata firmware · Issue #6 · shokai/node-ble-firmata
add BLENano sample code · Issue #7 · shokai/blendmicro-node

0

太陽電池でBlendMicro動いた

秋月の外のレジの下の棚にある350円のソーラーパネル2枚でBlendMicroが起動し、BLEが動いた。




Macからble-firmataでanalogReadとかもできた。
何しよう。

0

blendmicro用 BLE terminal作った

今周囲にどんなBLEデバイスがあるか確認したり、ちょっと通信したりするのにシリアル通信みたいに使えるターミナルがあったら便利なので作った
BlendMicro/Arduino BLE Shield用なので他のデバイスでは使えない。汎用的にできる方法があったら教えて欲しい。


インストール

blendmicro npmに付いている

% npm install blendmicro -g

グローバルにインストールするとblendmicroというコマンドにパスが通る


使う


-listでデバイスリストを表示、-terminalで接続
% blendmicro --help
% blendmicro --list
% blendmicro --term [DEVICE_NAME]

echo.inoを書き込んだBlendMicroと喋っているところ

なお0x4c 0x00 0x02 0x15で始まるデバイスはiBeaconである

0

ble-firmata npmにBLEの自動再接続機能を付けた

node.jsからBluetooth Low EnergyでArduinoをリモートコントロールできるble-firmata npmに、v0.1.1から自動再接続機能がついた。

BLEは有線のシリアル通信よりも接続切断は頻繁におこる。
見通し20メートルぐらいまで問題なく通信できるけど、家のドアなど金属製の遮蔽物があると切断される。そういう場合でも自動再接続されて、回線を意識せずロジックのプログラミングに集中できるようにした。


https://www.npmjs.org/package/ble-firmata

インストール

% npm install ble-firmata


注意


on ‘connect’イベントはデバイスが再接続される毎に呼ばれるので、その中でsetIntervalとかすると良くない。

once ‘connect’を使うとかすると良い。


BLEの切断


切断を検知するとarduino.on ‘disconnect’をemitするようにしておいた。

切断は色々な要因で起こる。

  • BlendMicroの電源が落ちる
  • BlendMicroが遠く離れて、電波が届かなくなる
  • BlendMicro側からnRF8001を切断する
  • node側でarduino.close()する
  • Macのbluetoothメニューで、[デバイス名]→[接続解除]を選択する
  • Macのbluetoothメニューで、bluetoothを「切」にする

いずれの場合も自動再接続が働く。


自動再接続を無効にする


reconnect = falseすれば自動再接続しない。一瞬接続して、切断して、しばらくしたらまた接続するような用途の場合は無効にすればいい。

arduino = new BLEFirmata().connect()
arduino.reconnect = false