micro:bitでBluetooth

micro:bitでラジコンを作りたい

micro:bitでBluetoothが使えるようなので、ラジコンを作ることにしました。

Bluetoothといってもいろいろあるらしくて、使えるのはLE(Low Energy)というものらしいです。Bluetooth Low Energyno略でBLEという書き方のほうが多いですね。

micro:bitではBR(Basic Rate)とEDR(Enhanced Data Rate)は使えないようです。

ググってみたところBR/EDRとLEは互換がないと書いてありましたが、互換が無いのなら混乱するので他の名前にすればいいのにって思います。ハードは共通なのでBluetoothにしたのかな?

micro:bitの設定

最初からmicro:bitでbluetoothは使えません。使えるように設定を行います。まずは下の絵の歯車アイコンをクリックします。

下の絵のような画面が出てくるので、bluetoothをクリックします。

bluetoothを使えるようにすると、もともとあったradioという機能が使えなくなります。これで良いのか聞かれるので下の絵の場所をクリックします。

bluetoothを使えるようにになりました。ブロックエディタでbluetoothが選択できます。

もう一回歯車アイコンをクリックし、「プロジェクトの設定」を選択すると以下のような画面になります。これはbluetoothのペアリングモードを選択するものです。「No Pairing・・・」を選択します。セキュリティとか気にする人はほかのモードを選択すべきですが、まずは動かしてから変更しましょう。

micro:bitのプログラミング

ラジコンなので、xの移動量とyの移動量を受け取るようにします。

Bluetooth UARTサービスでシリアル通信を行います。xと数値とカンマの組み合わせと、yと数値とカンマの組み合わせを受信すると、それぞれx、とyの変数に値を格納します。ラジコンを作るときにはこれをもとにモーターを制御します。

今回作った通信のプログラムは以下になります。

web bluetoothを使う設定

micro:bitへの指示はスマホから行います。GoogleのPlayストアでBLEのUARTターミナルとかありましたが、 ここはweb bluetoothを使ってみようかと思います。web usbとかもあるようで、ブラウザからハードを扱うものが気になっていました。

web bluetoothを使うには、ブラウザの設定を行います。多分セキュリティとか結構まずいことになりそうなので、 まずはCromeのデベロッパ版をインストールして、こちらの環境で実験します。

Chromeからchrome://flagsに移動すると、Chromeの設定項目がいっぱい出てきます。「experimental-web-platform-features」という項目を探してenabledに設定します。

chrome://flags/#experimental-web-platform-features ここから直接設定に行けます。 ただこの項目は数年前は違う名前だったようで、参考にしたらうまくいかなくて苦労しました。特に根拠はありませんが、今後も変わりそうな気がします。

web bluetoothのプログラム

miro:bitのUARTサービスに接続して、フォームに入力された文字を送信するプログラムを作ります。

miro:bitに接続するため、「6e400001-b5a3-f393-e0a9-e50e24dcca9e」というUUIDでmirobitを探します。これはmicro:bitで設定したUARTサービスに対応するものです。UUIDというのは同じ番号が無い数値だと思ってください。この番号に対応する機能が割り当てられています。micro:bitのUUIDの一覧はここにあります。UART以外にもいろいろありますね。

micro:bitが見つかったら「6e400003-b5a3-f393-e0a9-e50e24dcca9e」のUUIDでUARTの受信サービス(micro:bitからみて受信)を取得します。

あとはUint8Arrayのデータを書き込めば終わりです。作成したコードは以下になります。


<!DOCTYPE html><html><head><meta charset="utf-8" />
<title></title></head><body>

<form name="test">
<input type="button" value="接続" onclick="connect();"/>
<input type="button" value="切断" onclick="disconnect();"/>
<input type="text" name="msg" size="20">
<input type="button" value="送信" onclick="send();"/>
</form>
<script>
var bluetoothDevice;
var characteristic;

//接続
function connect() {
  // micro:bitを探す
  navigator.bluetooth.requestDevice( {acceptAllDevices: true, optionalServices:['6e400001-b5a3-f393-e0a9-e50e24dcca9e']} )
  .then(device => { bluetoothDevice = device; return device.gatt.connect(); })
  .then(server => { return server.getPrimaryService ('6e400001-b5a3-f393-e0a9-e50e24dcca9e'); }) // UART
  .then(service => { return service.getCharacteristic('6e400003-b5a3-f393-e0a9-e50e24dcca9e'); }) // microbitのRX
  .then(chara  => { characteristic = chara; alert("接続"); })  
  .catch(error => { alert("接続失敗"); });    
}

// 送信
function send() {
  if (!bluetoothDevice || !bluetoothDevice.gatt.connected || !characteristic) return ;
  characteristic.writeValue(new Uint8Array(new TextEncoder().encode(test.msg.value)))
  alert(test.msg.value);
}

//切断
function disconnect() {
  if (!bluetoothDevice || !bluetoothDevice.gatt.connected) return ;
  bluetoothDevice.gatt.disconnect();
  alert("切断しました")
}
</script>
</body></html>

このコードで以下のような表示になります。

「接続」ボタンを押してmicrobitを選択して「ペア設定」を押します。ダイアログで「接続」のポップアップが表示されたら接続成功です。ちょっと時間がかかるときがあるようです。「接続」のポップアップが無い状態ではなぜかたまに動かないなど不安定な動きに見えるの、で接続されたことが分かるようにしておくのは必要かと思います。

テキスト入力に「x11,」「y22,」のように先頭がxまたはyで送信したい文字列を入力し最後に,(コンマ)を入力すると、xまたはyの変数に送信した文字列が格納されます。「x11,」を入力した場合には、変数xに11が格納されます。これによりmicrobitの5x5LEDに「x11」が表示され、通信がうまくいったことがわわかるようにしています。

次はラジコンを動かす

micro:bitにつながるモーターと、モーターを制御するためのモータードライバICを購入してラジコンを作ってみます。