Skip to main content Link Search Menu Expand Document (external link)

p5.jsとmicro:bitでフィジカルコンピューティング

本記事は、Processing Advent Calendar 2022の9日目の記事です。

目次
  1. はじめに
  2. 環境と制限
    1. WebブラウザのWebUSB/WebBluetooth対応状況
    2. p5.js 環境の対応状況
  3. WebUSBサンプル:光センサ入力
    1. micro:bitプログラムの用意
      1. プログラム書き込みとペアリング
    2. p5.js WebUSBライブラリのロード
      1. WebUSBライブラリ のセットアップ
    3. 動作チェック
  4. WebBluetoothサンプル:光センサ
    1. micro:bitのBluetooth拡張
    2. micro:bitのBluetooth UART送信プログラム
      1. Bluetooth UARTサービスの開始と送信
      2. Bluetooth 接続状態の表示
      3. micro:bit のペアリングモード設定
    3. p5.js WebBluetoothライブラリのロード
    4. WebBluetoothライブラリ のセットアップ
    5. 動作テスト
    6. micro:bit のBluetoothペアリング
  5. WebBluetoothサンプル:加速度センサ
  6. まとめ
  7. 参考
  8. [おまけ] p5.js 環境でのハードウェア通信ライブラリ

はじめに

この記事では、p5.jsmicro:bitを使ってプログラミング初学者でも簡単に物理的な入出力デバイスを作成する方法について解説します。 具体的には、p5.jsからWebUSBやWebBluetooth経由でmicro:bitのボタンやセンサ入力のやり取りする方法を紹介します。

筆者が受け持っているシンガポール国立大学のインダストリアルデザイン学科での授業では、 p5.jsとmicro:bitをつかって、プログラミング経験ほぼゼロから7週で下のような作品を作れるようにしています。

 
BBCが英国の小学生全員に配布されるように開発したという歴史的経緯から初等STEM教育向けといった印象のあるmicro:bitですが、 標準で加速度、温度、光、磁気センサなどの基本的なセンサやボタン入力が装備されているため、 自作ハードウェア特有のセンサ値の不安定さに悩まされることなく、即センサ入力を利用したインタラクション設計を始めることができます。

フィジカルコンピューティング教材で一般的なProcessingやArduinoではソフトとハードのやり取りに主にシリアル通信を用いますが50人を超えるプログラミング初学者向けクラスでは、ドライバのインストールから通信ポートのトラブルシュートで授業時間(と私の❤️)ががっつり削られてしまいます。

一方、p5.jsとmicro:bit間の通信にはWebブラウザから有線のWebUSBと無線のWebBluetoothが使えます。 この場合、追加ドライバのインストールや設定が要らずWebブラウザだけで完結できるので楽勝です。

というわけで、ここでは、WebUSBとWebBluetooth経由でp5.jsとmicro:bitの通信を可能にする 以下の2つのライブラリをご紹介いたします。

     
WebUSB https://nkymut.github.io/microbit-webusb-p5js/ microbit-webusb をクラス化、
複数インスタンス接続可にしたもの
WebBluetooth https://nkymut.github.io/microbit-webble-p5js/ microBit.js by antefact IAMAS小林茂さんのGistのコードをマージしてUART対応したもの

環境と制限

まずはじめに、p5.jsとmicro:bitをWebUSB/WebBluetooth越しで使用する環境には、いくつかの制限があります。

WebブラウザのWebUSB/WebBluetooth対応状況

2022年12月現在、WebUSBとWebBluetoothをサポートしているブラウザはChrome(とOpera)のみになっています。 特にSafariではセキュリティ上の理由で実装しないことが明言されているので今後のサポートも期待できないでしょう。

各Webブラウザでのサポート状況は以下の様になっています。(caniuse.com調べ)

環境 WebUSB  WebBluetooth
Chrome (Win/Mac) / Edge
Safari × ×
Firefox × ×
Opera
Chrome on Android
Safari on iOS × ×
Chromium on Raspberry PI ×

p5.js 環境の対応状況

追記(2023/02/15): editor.p5js.orgのプレビューでもWebBluetoohが使えるように修正されました。よかったですね。

またeditor.p5js.orgユーザーには悲しいお知らせなのですが、 現状WebBluetoothが機能していないようです。

https://openprocessing.org/かローカルVS Code上のLiveServerで試すのをオススメします。

環境 WebUSB  WebBluetooth
https://editor.p5js.org/
https://openprocessing.org/
https://glitch.com/
VSCode LiveServer

WebUSBサンプル:光センサ入力

では早速、micro:bitの光センサで電球の色を変えてみましょう。

WebUSBライブラリダウンロード

p5js.org サンプルコード: https://editor.p5js.org/didny/sketches/_P18rzj9

https://github.com/nkymut/microbit-webusb-p5js/tree/master/examples/uart_lightsensor

micro:bitプログラムの用意

まずはmicro:bitから光センサの値をシリアルUARTで送信するコードを用意します。

プログラムのURL:https://makecode.microbit.org/_c7AV2KYY6YH9

micro:bit 光センサコード

この様にアホほど簡単です。

プログラム書き込みとペアリング

エディタとペアリング

プログラムが作成できたら、Downloadボタン横のConnect deviceをクリックしてmakecodeWebエディタとmicro:bitをペアリングします。成功するとDownloadボタンからプログラムをWebUSB経由で直接micro:bitにダウンロードできるようになります。

もしペアリングに失敗する場合、micro:bitのファームウェアが古い場合があるので こちらのmicro:bitファームウェアをアップデートする方法に従ってアップデートしてください。

micro:bitのコードをロードしたらShowData(Device)ボタンをクリックして、コンソールとグラフ表示でセンサーが正常に動作していることを確認します。

プログラムのセンサ入力値のチェック画像

コンソールで十分動作を確認したら、アドレスバー左横の🔒アイコンをクリックしてmicro:bitのペアリングを解除します。これをしないと後にp5.js側とシリアルのバッファを奪い合う形になり通信速度が低下してラグが生じます。

micro:bitのWebUSBペアリングを解除

p5.js WebUSBライブラリのロード

次に、p5.js側のindex.htmlファイルに以下の行を追加してubitwebusb.jsを読み込むようにします。

  <script language="javascript" type="text/javascript" src="https://nkymut.github.io/microbit-webusb-p5js/ubitwebusb.js"></script>

WebUSBライブラリ のセットアップ

ライブラリを設定したら、p5グローバル変数で宣言したmicro:bitにuBitWebUSBオブジェクトのインスタンスを作成します。

  let microBit; //グローバル変数

  microBit = new uBitWebUSB(); //microBit WebUSBインスタンスの作成

次にmicro:bitへの接続・切断用のボタンを作成します。 Chromeのセキュリティ設定上の理由からユーザーの入力なしに外部デバイスと接続できないようになっているのでボタン押下イベントコールバックとして設定します。

/* setup() 内*/
//add connect button
connectBtn = createButton("connect");
connectBtn.mousePressed(connect);
//add disconnect button
disconnectBtn = createButton("disconnect");
disconnectBtn.mousePressed(disconnect);
/* sketch内のどこか */
//connect to microBit
function connect() {
  microBit.connectDevice();
}

//disconnect from microBit
function disconnect() {
  microBit.disconnectDevice();
}

p5.js とmicro:bitのやりとりはコールバック関数として設定します。

  • microBit.onConnect()microBit.onDisonnect()では接続・切断時のふるまいを指定して、
  • microBit.setReceiveUARTCallback()ではmicro:bitからのデータを受信したときにどうするかを設定します。

ここでは受信した光センサのデータを電球の明るさ値に設定しています。

  /* setup() 内*/
  microBit.onConnect(function(){ // 接続成功コールバック
    console.log("connected");
  });

  microBit.onDisconnect(function(){ //切断時コールバック
    console.log("disconnected");
  });


  microBit.setReceiveUARTCallback( // UART受信コールバック
    function(receivedData){ 
      let val = int(receivedData); //受信テキストを数値に変換
      bulb.brightness = val; //電球の明るさ変更
    
      fadeSlider.value(bulb.brightness); //フェーダーに明るさを表示
    }
  );

動作チェック

というわけで実際に動作を試してみましょう。

Connectボタンを押すと、下のようなポップアップ表示が出るので、お目当てのmicro:bitを選択して接続します。

micro:bitとの接続が完了すると、光センサの値によって電球の明るさが変わるはずです。 スマホのライトを当てたりして遊んでみてください。
もし、反応がひどく鈍い場合、

  • micro:bitのエディタがmicro:bitに接続しっぱなしになっていないか?
  • 複数のタブでWebUSBを使うp5スケッチが開かれて両方ともmicro:bitに接続されていないか?
  • console.log()やprint()でUART受信したデータのログを大量に吐いてないか?

を確認してください。

以下、コードの全体です。

https://github.com/nkymut/microbit-webusb-p5js/blob/master/examples/uart_lightsensor/sketch.js


WebBluetoothサンプル:光センサ

WebUSBが動いたところで早速、同じコードをWebBluetoothで無線化してみましょう。

WebBluetoothライブラリダウンロード

https://github.com/nkymut/microbit-webble-p5js/tree/master/examples/uart_lightsensor

micro:bitのBluetooth拡張

まず、micro:bitのmakeCodeエディタにBluetooth拡張を追加します。

micro:bitのBluetooth UART送信プログラム

micro:bit BLE 光センサコード

https://makecode.microbit.org/_WhKc1b3w82kx

Bluetooth UARTサービスの開始と送信

WebUSBサンプルで使用したコードに2点追加します。

  • [bluetooth uart service]: Bluetooth UART サービスを開始する。
  • [bluetooth uart write line] micro:bitから改行付きテキストデータを送信します。
  • (convert to text): [bluetooth uart write line] は、数値データを直接指定することができないので数値をテキストに変換する必要があります。

WebBluetooth光センサ micro:bitコード v01用: microbit-LightSensorBLEUARTv01.hex

Bluetooth 接続状態の表示

micro:bit BLE 光センサコード改良版

WebBluetooth光センサ micro:bitコード v02用:microbit-LightSensorBLEUARTv02.hex

WebUSBと違い無線の場合、コンソールからmicro:bitの状態を確認できないので、 LEDマトリクスにBluetoothの接続状態を表示すると便利です。 しかし、LEDマトリクスの表示はメモリを大量に消費するらしく非力なv01(スピーカーやマイク入力のついていないタイプ)のmicro:bitだとError 20を表示して止まってしまう場合があります。

ここでは、

にそれぞれLED表示を設定します。

micro:bit のペアリングモード設定

そして最後に一番大事なプロセス、makeCodeエディタ右上の⚙️のProject Settingsを選択して、 No Parining Requiredオプションを選択してください。 これを選択しないと、p5スケッチのConnectボタンを押してもmicro:bitが一覧に出てこず大いに時間を無駄にします。

   
NoPairing 設定メニュー No Pairing 設定2

https://makecode.microbit.org/_F8DFrygkTRP1

p5.js WebBluetoothライブラリのロード

次に、p5.js側のindex.htmlファイルに以下の行を変更してubitwebble.jsライブラリを追加します。

  <!-- WebUSBライブラリ -->
  <!-- <script language="javascript" type="text/javascript" src="https://nkymut.github.io/microbit-webusb-p5js/ubitwebusb.js"></script> -->

  <!-- WebBluetooth ライブラリ -->
  <script language="javascript" type="text/javascript" src="https://nkymut.github.io/microbit-webusb-p5js/ubitwebble.js"></script>

WebBluetoothライブラリ のセットアップ

ライブラリを設定したら、以下の様にsetup()関数内でmicroBitのコンストラクタをuBitWebUSB()からuBitWebBluetooth()に変更してWebBluetoothオブジェクトのインスタンスを作成します。

  let microBit; //グローバル変数

  microBit = new uBitWebBluetooth(); //microBit WebBluetoothインスタンスの作成

動作テスト

では実際に動作テストをしてみましょう!
えっ、他にコードを追加しなくてよいんですかって? そうなんです、uBitWebUSBuBitWebBluetooth では同じAPIでUART通信できるようにしてあるので、コンストラクタの変更だけで動きます。 あっと驚くタメゴローです。

micro:bit のBluetoothペアリング

Connectボタンを押すと、WebUSBの時と同様に、ペアリングの画面が表示されます。

BBC micro:bit [固有ID]

ここで表示される5文字のアルファベットがmicro:bitのBluetooth通信時の固有IDになっており、 複数台のmicro:bitを扱う場合は、このIDで個体を認識します。

が!

このIDがなんと 実際接続してみる以外に知る方法がない! のでワークショップなどで 数十台のmicro:bitを扱うときに事前にIDを調べておかないとハマります(ハマりました)。

追記:micro:bitの固有ID (device name)を知る方法ありました。 https://support.microbit.org/support/solutions/articles/19000067679-how-to-find-the-name-of-your-micro-bit

Advanced -> Control -> more から (device name) で取得できます。

device name

[show string]や[serial write line]で表示されたのち micro:bit本体にシールなどでメモっておくと便利です。

WebBluetoothサンプル:加速度センサ

ブルーツース全部入り

micro:bitのBluetooth拡張には、UARTの他にもmicro:bitの内部センサ値やボタンやLED・GPIOなどの入出力に直接アクセスするサービスが公開されています。 こちらがmicro:bitのBluetooth サービス全部入りコードです。 https://makecode.microbit.org/61779-39134-92711-11083

ここでは加速度センサを使った例を見てみます。

https://github.com/nkymut/microbit-webble-p5js/tree/master/examples/accelerometer_3Dbox

受信時のコールバック関数を指定する必要があったUARTと違い直接加速度センサのオブジェクトを取得して、 XYZのプロパティ値にアクセスできます。

acceleration=microBit.getAccelerometer(); // 加速度センサオブジェクトの取得
acc_x=acceleration.x; // X軸
acc_y=acceleration.y; // Y軸 
acc_z=acceleration.z;  // Z軸

上の例ではX軸とY軸の値を箱のZとX軸の回転に割り当てています。

function draw() {
  background(78);
  if (microBit.connected){

    noStroke();
    push();
    print("X:"+microBit.getAccelerometer().x);
    print("Y:"+microBit.getAccelerometer().y);
    print("Z:"+microBit.getAccelerometer().z);
   
    //箱の各軸を回転させる。
    rotateZ(map(microBit.getAccelerometer().x,-980,980,Math.PI/2,-Math.PI/2));
    rotateX(map(microBit.getAccelerometer().y,-980,980,-Math.PI/2,Math.PI/2));
    box(150);
    pop();

  }

}

この加速度センサ入力をp5.playと組み合わせると このようなゲームを作ることができます。


まとめ

以上、p5.jsとmico:bitをWebUSBとWebBluetooth経由で通信させて簡単な物理入力デバイスを作る方法を紹介しました。

今回紹介しきれなかった、Neopixel LEDのコントロールなど様々なサンプルを今後もアップデートしていくので、 下の各ライブラリGitHubプロジェクトのフォローをお願いします。

もし、改善要望やバグなどありましたらどうぞお気軽にIssueやプルリクを送ってください。 特に、現状WebBluetoothライブラリでは IO操作が実装されていなかったり、LEDマトリックス操作に 致命的なバグがあるので協力して頂ける人を募集中です。

p5.jsでハードウェア入力を扱う方法としては他にWebMidiという方法があります。 以前p5.soundをMIDI経由で鳴らすチュートリアルを行った際のドキュメントがここにありますので興味がある方はぜひ。 https://github.com/nkymut/ShapeOfSound/blob/main/tutorials/wk06/p5sound_tutorial.md#06-p5sound–midi-input

それでは良い師走を〜🎅

参考

[おまけ] p5.js 環境でのハードウェア通信ライブラリ

p5.jsとハードウェアの通信用ライブラリは、WebUSBやWebBluetooth以外に様々あるのですが、 ググってもWeb上にいまいち情報がまとまってないのでここにまとめます。 もしここに載っていない便利なライブラリがあればプルリクなどで教えて下さい。

プロトコル ライブラリ 状況 ライセンス
Serial p5-serial ブラウザ非依存だが、ホストPC側に別途ミドルウェアをインストールする必要があり、イマイチ不便 MIT
WebUSB microbit-webusb WebUSB 安定してるがクラス化されてない MIT
WebBluetooth microBit.js by antefact WebBluetooth 一通り動くがI/O PinとUARTサポートしてない LGPL-2.1
WebBluetooth IAMAS小林茂さんのGist WebBluetooth UART p5.js サンプルコード N/A
WebBluetooth p5.ble.js p5.js汎用WebBluetoothライブラリ、
UUIDを直接指定する必要あり、初学者にはハードル高い
MIT
WebBluetooth p5.toio toio™をWebBlueetoh経由でp5から操作する MIT
WebMIDI webmidi.js p5.soundをMIDIデバイスで鳴らしたりできる。 Apache2.0
WebSerial p5.webserial 試してないがBautRateとか指定できて便利そう N/A
WebSerial p5.web-serial 上に同じ MIT