micro:bit MakecodeでBluetooth LEの動作テスト

2021.7.25 Coskx Lab  

1 はじめに

micro:bitではBluetooth LE(Low Energy)というBluetoothを使った通信手段があります。
通信相手はスマホやタブレット,PCなどです。
この通信を使うと,micro:bitの内部状態(例えば,センサの取得値やモータ指令値など) をスマホなどの画面に表示できます。
またスマホなどからコマンド文字列をmicro:bitに送りmicro:bitロボットのリモート操縦などができます。
動き回るロボットなどを開発するときには,有線での通信よりも無線での通信の方が便利です。
ここではmicro:bitで使用されているBluetoothLEの「Nrdic UART Service」を使って通信することにします。
micro:bitの通信相手はAndroidスマホ(タブレット)とします。



BluetoothLE通信はランタイムライブラリが大きくて,プログラムサイズオーバーになりやすいです。
プログラムサイズオーバーになると,プログラムをHexファイルに保存するときあるいはmicro:bitに書き込む時に「program too big by xxxx bytes」という警告が出て,ファイル保存やmicro:bitへの書き込みが失敗します。
その場合は,無線通信(LowLevelRadio)を検討します。
無線通信のランタイムライブラリはそれほど大きくないので,プログラムサイズには余裕ができます。
しかし,無線通信(LowLevelRadio)では中継micro:bitが必要になります。また1回に送信できる文字列が19文字までという制限がありますが,これは工夫して対処できます。
Bluetooth LEとLowLevelRadioのどちらを使うかは,状況により判断する必要があります。

2 使用環境

3 接続

Bluetooth通信機能は最初からmicro:bitが持っているので,本体以外は何も必要なものはありません。

4 通信テストプログラム

MakeCodeを使います。
プログラムでは,通信体制が確立したら。次の2つのことをできるようにします。
(1)スマホから任意の文字列を受信したら,micro:bit側はコンソールに受信文字列を表示し, LED画面にもスクロール表示します。
(2)逆に,micro:bitのAボタンが押されたら,何らかの文字列をスマホに送信します。

拡張機能Bluetoothを使います。MakeCode画面で「高度なブロック」を開いて「拡張機能」を開き,拡張機能の一覧の見えているところの検索ボックスで「Bluetooth」で検索すると「Bluetooth」がありますので,これを組み込みます。
「無線(LowLevelRadio)」はBluetoothと同時に使えないので,「無線」機能を消してよいかと聞かれるのでOKと答えます。



使える拡張機能が取得出来たら,あとは,組み立てるだけです。

  Bluetooth通信テスト用プログラム



プログラムができたら,MakeCodeの画面の右上の歯車マークメニューから,「プロジェクトの設定」に進み,「JustWorks pairing ・・・・」を選択して,「保存」します。(後で行うペアリング手順の設定です)

コピペする場合は,拡張機能で「Bluetooth」で検索し「Bluetooth」を取り込んでから,次のソースコードをPythonソースとして貼り付ければ完了です。

def on_bluetooth_connected():
    basic.show_icon(IconNames.SMALL_SQUARE)
bluetooth.on_bluetooth_connected(on_bluetooth_connected)

def on_bluetooth_disconnected():
    basic.show_icon(IconNames.SQUARE)
bluetooth.on_bluetooth_disconnected(on_bluetooth_disconnected)

def on_button_pressed_a():
    bluetooth.uart_write_line("Hello from Micro:bit")
input.on_button_pressed(Button.A, on_button_pressed_a)

def on_uart_data_received():
    global mystring
    mystring = bluetooth.uart_read_until(serial.delimiters(Delimiters.NEW_LINE))
    serial.write_line(mystring)
    basic.show_string(mystring)
bluetooth.on_uart_data_received(serial.delimiters(Delimiters.NEW_LINE),
    on_uart_data_received)

mystring = ""
serial.write_line("Bluetooth Communication Test")
bluetooth.start_uart_service()
basic.show_icon(IconNames.SQUARE)

5 通信手順

ここではスマホはAndroidデバイスを使い,通信アプリ「Serial Bluetooth Terminal」を使うことを想定します。


通信にはAndroidデバイスとmicro:bitのペアリングをしておく必要があります。
ペアリングが済んでしまえば,その後の接続は簡単な操作で何回でもできます。

A. ペアリング(ボンディングともいう)手順
(1)スマホ側ではシステムの設定でBluetoothを有効にします。
(2)micro:bit側で,ボタンA,Bを同時に押しながら,裏側のリセットボタンを押します。

(3)ボタンA,Bを同時に押し続けながら,リセットボタンを離します。LED表示が順に点灯し,全LED点灯状態になったら,ボタンA,Bを離します。LEDはBluetoothマークになり,次に漢字の「山」のような表示になります。これでmicro:bitがペアリングモードになりました。
(4)スマホ側では設定でbluetoothの設定画面まで進み,新たなBluetoothデバイスを検索します。
(5)スマホ画面で新規BluetoothデバイスとしてBBC micro:bitが見つかります。
(6)「BBC micro:bit」という名前以外の情報も見えるので,メモしておきましょう。複数のmicro:bitがBluetoothLEの電波を飛ばしていても,今後接続するのは今作業しているmicro:bitで,それを識別するのに必要です。
(7)見つかったら(タップして?)BBC micro:bitをペアリングします。ペアリングが完了します。このとき,micro:bitのLED表示はチェックマークになります。

B.「Serial Bluetooth Terminal」での通信
(1)Androidスマホで「Serial Bluetooth Terminal」を立ち上げて,左上3本線メニューから「Device」を選び,通信方法を「Bluetooth LE」にし,右上のSCANをタップします。
(2)BBC micro:bitが見つかるので,それを長押しします。現れたポップアップから「Edit」を選びます。
(3)「predefined」を選びます。すでに選ばれている場合でもタップします。右上のチェックマークをタップします。
(4)再びBBC micro:bitが見えるので,タップします。(あるいはBBC micro:bitを長押し,Connect)これで接続が完了するはずです。

うまくいかなかったら「9 接続時のトラブル」を参照してください。

6 通信時の様子

相互にメッセージを送りあっているところです。



micro:bitが「Hello from Android」を受け取ってLEDに表示しているところです。ちょうどrを表示しています。



7 スマホからのコマンド送信の例(方位測定値観察プログラム)

スマホからのgo指令コマンドで,micro:bitが方位測定し,測定結果をスマホに送信し続けます。
スマホからのquit指令コマンドで,micro:bitは測定と測定結果送信を中止します。
測定の前には磁気センサの較正のため,micro:bitを様々な向きに回して,LEDを全点灯にする操作が求められます。
測定中はmicro:bitは水平置きです。

  方位測定値観察プログラム



コピペする場合は,拡張機能で「Bluetooth」で検索し「Bluetooth」を取り込んでから,次のソースコードをPythonソースとして貼り付ければ完了です。

def on_bluetooth_connected():
    basic.show_icon(IconNames.HAPPY)
bluetooth.on_bluetooth_connected(on_bluetooth_connected)

def on_bluetooth_disconnected():
    basic.show_icon(IconNames.SQUARE)
bluetooth.on_bluetooth_disconnected(on_bluetooth_disconnected)

def on_uart_data_received():
    global command, compusswork
    command = bluetooth.uart_read_until(serial.delimiters(Delimiters.NEW_LINE))
    if command.includes("go"):
        compusswork = 1
    else:
        compusswork = 0
bluetooth.on_uart_data_received(serial.delimiters(Delimiters.NEW_LINE),
    on_uart_data_received)

command = ""
compusswork = 0
bluetooth.start_uart_service()
input.calibrate_compass()
basic.show_icon(IconNames.SQUARE)
compusswork = 0

def on_forever():
    if compusswork == 1:
        bluetooth.uart_write_line(convert_to_text(input.compass_heading()))
basic.forever(on_forever)

8 通信時の様子

スマホから接続し,goコマンドでmicro:bitに方位測定させ,測定データを送信させます。
この作業が連続して行われます。
quitコマンドで,micro:bit側の作業は中止されます。



9 接続時のトラブル

「Serial Bluetooth Terminal」が接続を試みても失敗し続けることがあります。
その場合は,スマホの設定でペアリング済みのmicro:bitの[i]をタップし,ペアリングを一度解除し,再度ペアリング手順でやり直してください。
なお,スマホ複数台で1つのmicro:bitとペアリングしても,アプリが接続できるのは一度に1台だけです。
スマホAがmicro:bitとペアリングしアプリで接続して作業した後,スマホBがmicro:bitとペアリングしアプリで接続して作業したとき,もう一度スマホAのアプリでmicro:bitと接続しようとすると失敗する場合が多いです。その際はペアリングを解除して再度ペアリングから試みてください。


10 まとめ

BluetoothLEを使った通信で,相互にメッセージを送りあうことができました。
また,コマンドをmicro:bitに与えて,ある作業を行わせるひな型も動作しました。