何したの?

加速度の大きさで信号を出力するものを試作する案件に、micro:bitが使えるかと思い、試作に用いてみました。HEXファイル、iOSアプリのソースコード、アプリの動いている動画などのリソースは https://github.com/reinforce-lab/microbit_accs_siwtch にあります。

マイコンというハードウェアへのファームウェア書き込みは、書き込み装置が必要で、書き込み手順を覚えなければならず、誰でもできるものではありません。このマイコンボードであれば、誰でもファームウェア更新ができます。これなら、ファームウェアを書き込んだハードウェアを送付しなくても、HEXファイルを送るだけですむかもしれません。

どんな情報があるの?

自分で作るiOSアプリケーションと、micro:bitとの間の、任意の情報のやり取りの実装方法があります。iOSアプリケーションの表示画面は、このようになっています:

micro:bitで、文字列に組み立てた加速度や内部設定値、そしてIOの情報を、BLEを経由してiOSアプリに伝えています。iOSアプリで、それをグラフ表示しています。
iOSアプリから、設定値をBLEでmicro:bitに伝えて、micro:bitのプログラムで、その値を該当する変数に格納しています。

micro:bitに最初からあるIOサービスを使い、BLE経由でセンサやスイッチの情報を読み取るサンプルはたくさんありますが、自分のプログラムで処理した内容を外部に伝えたいときのスタートポイントになるでしょう。また、外部からmicro:bitへ情報を伝える方法の解説が、なぜか、見かけませんが、BLE UARTを使った情報の渡し方の解説になっているでしょう。

micro:bitって?

micro:bit http://microbit.org/ja/ は、プログラミング教育の教材で、Nordic Semiconductor社のnRF51822を使ったマイコンボードです。

グラフィカルにブロックを並べてプログラムを組み立てられるビジュアル・プログラミング環境があります。またBluetooth low energy(BLE)でスマートホンと通信できるので、スマートホンやタブレットで作ったプログラムをBLEで書き込んだり、スマートホンとマイコンボードとで通信ができます。

nRF51822は、RAM容量が16kバイトと32kバイトの2品種がありますが、micro:bitに使われているマイコンボードは16kバイトのものです。BLEをまったく使わない場合は、16kバイトのRAMを全てユーザのアプリケーションに使えます。BLEを有効にすると、BLEのスタックが12kバイトのRAMを使うので、ユーザのアプリケーションに使えるRAM容量は4kバイトになります。スタックに最低2kバイトが必要ですから、実際に使える容量は2kバイトです。

プログラミング環境

micro:bitの開発環境は、TypeScriptを用いるものと、Pythonを用いるものの2つがあります。いずれもビジュアルプログラミング環境が提供されていますが、テキストでソースコードを書くこともできます。Pythonの開発環境では、BLEは使えません。その代わりに、Nordic Semiconductor社の独自プロトコルの無線通信機能のみが使えます https://lancaster-university.github.io/microbit-docs/ubit/radio/ 。この独自プロトコルの無線通信は、micro:bitのボード間の通信はできますが、BLEではないので、スマートホンとは通信できません。

TypeScriptを用いるものは、Microsoft社のmake:codeで提供されています。下層は、arm mbedとNordic nrf51を使ったC/C++開発ランタイム https://lancaster-university.github.io/microbit-docs/ です。TypeScriptで書いたソースコードが、このランタイムのAPIを呼び出す形になります。

TypeScriptは、Microsoft社が開発している、JavaScriptに静的型付けとクラスベースのオブジェクト指向を加えたJavaScriptのスーパーセットになるよう定義された言語です。make:codeのプロジェクトは、TypeScriptのサブセットでプログラミングができます。TypeScriptで書いたソースコードは、ウェブブラウザの内部で構文解析されて、Arm thumbコードに変換されて、HEXファイルが生成されます。ローカルで、機械語とHEXファイルの生成まで行い、ユーザのコンパイルがローカルで完結してサーバーを必要としない作りになっています。

Pythonを使うものは、省略します。Pythonのバイトコードを実行するために、ある程度のRAM容量が必要になりますが、BLEを有効にすると必要なRAM容量が確保できないみたいです。BLEを有効にすると実行に必要なRAM容量が取れないため、Pythonのmicro:bit環境では、Nordic Semi.社の独自プロトコルの無線通信は提供されていますが、BLEは使えません。

foreverブロック

アプリケーションはforeverが繰り返し呼び出されます。

foreverブロックは図の通りです。加速度を取得して、しきい値を超えればP0/P1のピンにHIGHを出力にする、また閾値や加速度の値をBLEでスマートホンに伝えるメインルーチンを書いてみました。加速度の大きさを変数”accs”に取得して、それを”plot”ブロックで、micro:bitのLEDアレイに表示させています。文字列は”join”で連結して作っています。最後にBLE UARTで、スマートホンに文字列を伝えます。また、ルーチン呼び出し頻度を確認するために、ルーチン呼び出しごとにmicro:bitのP2をトグルさせます。

この時のP2の波形を示します。

BLEでスマートホンと接続していない時の波形:

BLEでスマートホンと接続した時の波形:

です。

BLEと接続していない時は、foreverが30ミリ秒ごとに呼び出されます。micro:bitはプログラミング教材ですから、ブロック崩しなど、micro:bit背面のLEDアレイとタクトスイッチだけで入出力が完結した、見た目に動作がわかりやすいゲーム作りが、教材として使われます。メインルーチンが30ミリ秒ごとに呼びされるので、スイッチの状態を都度画面に反映する関数をforeverにべた書きするだけで、そのようなゲームが作れます。もしもforeverが、while文で永久ループで繰り返し実行されるものならば、sleep()か何か、適当な遅延時間を自分で入れないと、画面の表示速度が速すぎて、ゲームにならないでしょう。プログラミング教材として、時間を気にしなくても良いように、適当な周期でこのルーチンを呼び出しているのでしょう。

BLEと接続すると、foreverが55ミリ秒ごとに呼び出されています。BLEの接続の有無で、ルーチン呼び出し周期が変わってしまうのは、ちょっと、なにそれ?と思います。下層はmbedなので、mbedのイベント呼び出しの作りを見れば、どうしてこうなるのかがわかると思いますが、例えばforeverのルーチンを呼び出して、30ミリ秒して次の呼び出しでBLE関連の処理を呼び出して、また30ミリ秒後にforeverルーチンを呼び出す作りなら、そうなるかもしれませんが、普通、タイマーイベントに登録して、どのルーチンも30ミリ秒ごとに呼び出すように作る気がしますけど、mbedだし、気にしないことにしましょう。

スマートホンからデバイスへのデータ書き込み

make:codeのブロックは、例えばカンマで文字列を分割するような、文字列を解析する処理ブロックがありません。BLE UARTには、デリミタまで文字列を読みだして、読みだした文字列を返すブロックがあります。

この”bluetooth uart read until”の振る舞いは、BLEで1つのパケットで受信した文字列で、文字列にデリミタが含まれていたら、発見した最後のデリミタの前の文字列を返します。

例えば、read untilで”:”をデリミタに指定したとします。スマートホンから、BLEの1つのパケットで、”123:456:”を送信した場合、このブロックは”123:456”を返します。

シリアル通信だから、BLEのパケットを意識しない、文字列ストリームで、デリミタの検出で文字列を分割して結果を返してくると思い込むと、まず”123”が返ってきて、次の呼び出しで”456”を返すように思いますが、違います。BLEの1回のパケットで書き込まれた文字列で、デリミタが含まれていたら、そのデリミタの前の文字列を返す、という振る舞いをします。

渡したいパラメータが複数種類ある場合は、パラメータのスタートを示すデリミタを送ってから、1つつづパラメータにデリミタをつけてパケットを送ります。図では、念のため、パラメータの種類ごとに違うデリミタを指定して、もしもパケットを読み落としてパラメータの読み出し順番がずれても、誤ってパラメータとして受信処理をしないようにしています。

BLEの書き込みは、write with response、write without responseのいずれでも使えます。ただ、write without responseで書き込むと、パラメータに0が設定されていたりして、詳しく見てないですが、パケットをボロボロ落としているような気がします。

グラフ表示

senstickというBLEセンサーデバイスのiOSアプリを流用して、作ってみました。iPadがあればplaygroundを使えば、簡単にグラフ表示できるのかもしれませんが。

micro:bitは受託開発に使えるのか?

試作のための動作確認をやりとりする場面で、頻繁にファームを変更して動作を確認しなければならいが、相手が遠隔にいるため、相手にファーム更新をしてもらわなければならない場面では、利用できると思います。

USBのマスストレージで、ファーム更新ができることに価値を見出すなら、その書き込み回路だけを使えばよいことです。micro:bitの開発環境を使わねばならない理由はありません。

BLEの接続状態でforeverルーチンの呼び出し周期が異なる、BLEを切断するとファームが固まりリセットしなければならない、ファームウェアを更新するたびにiOSデバイスとのボンディングをやり直さなければならないなど、不要な手間がいっぱいありすぎます。

micro:bitは不用意に他人のmicro:bitにつながらないように、まずボンディングをしてから、BLEが使えるようになる作りになっています。教育教材としては正しいのですが、試作ではとりあえずデバイスに接続したいだけなので、ボンディングが必須なのは、めんどくさいです。

また、BLEの接続や切断でファームが固まる、BLEの接続状態でforeverのルーチン呼び出し周期が変化するなど、変なところがあります。デバッグ手段はUARTでprintfデバッグになり、めんどくさいです。

make:codeの開発環境は素晴らしいのですが、その下層にあるプラットホームが微妙すぎます。

Comments

2018-02-01