obnizとは?

 今回はマイクロビットのシリアル通信機能を使ってobniz(オブナイズ)とデータのやりとりを行ってみます。
obnizはネットとリアルを繋ぐ、まさにデジタルハブです。ブラウザからコントロールすることができるため、最新のJavaScriptなどWeb技術を使うことができます。特にWeb技術をIoT機器制御に利用できるのは大きな魅力/メリットと言えます。IoT/電子工作の世界に興味がありWeb技術を持っているなら、最初にobnizを選択するのがよいでしょう。各種センサーなどからデータを収集してデータベースに記録しておくのであれば、これほど手軽で便利なものはありません。

・obniz
https://obniz.io/

 obniz(ハードウェア)は、いくつかのファームウェアバージョンがありますが、今回のプログラムはいずれのバージョンでも動作します。また、obnizは2つのUART(シリアル通信)が可能なので、2台のマイクロビットを繋げて通信を行うことができます。
 また、ネットワーク通信機能がないシングルボードコンピューターなどをobnizに繋ぐことでネットワーク上にデータを送ったり、受け取ることが可能になります。さらにobnizはOSとしても供給されておりM5Stackなど他のデバイスにもインストールしobnizと同じ仕組みで制御することができます。まさに、デジタルハブと言えます。
 大変、便利なobnizですがネックもあります。特にWebブラウザもしくはnode.jsから(もしくはクラウドから)集中制御するタイプなので、完全に独立してデータを保存するようなことはできません。どうしても制御を行う親機(サーバー等)が必要になります。obnizとセンサーを繋げてデータをobniz内に記録していくような使い方はできません。

obnizのセットアップ

 obnizを使うためにはインターネットに接続する必要があります。WiFiでもテザリングでもとにかくインターネットに接続できればOKです。
最初にobnizの電源を入れると下図のような画面が表示されます。Switch this!と表示されたらobnizの左上にあるスイッチを押します。

しばらくすると接続可能なWiFiの一覧が表示されます。obnizの左上にあるスイッチを左右に移動させ、接続するWiFiを選択します。決定するにはスイッチを押し込みます。

WiFiに接続するためのパスワードを入力します。スイッチを左右に動かして、文字を選択します。文字を入力するにはスイッチを押します。

パスワードを入力したらスイッチを左右に動かして[END]に合わせます。合わせたらスイッチを押します。

パスワードが間違っていなければ下図のような画面になります。

QRコードをスキャンすることで、そのobnizを駆動するためのプログラムを開発する画面が表示されます。QRコードがうまく認識できない場合は、obnizのトップページからコードエディタかブロックエディタを選択します。その後、対象となるobnizの番号を入力します。

なお、接続するWiFiを変更する場合や、ファームウェアリセットを行う場合には、あらかじめobnizの左上のスイッチを押したまま電源を入れて下さい。メニューが表示されるので、処理したい項目を選択しスイッチを押して下さい。

マイクロビットとobnizをつなげる

 まず、マイクロビットとobnizをつなぎます。マイクロビットとobnizはシリアル通信(UART)を使ってデータの送受信を行います。データの送受信を行うためには3本のケーブルが必要です。ワニ口クリップやジャンパーワイヤーなどを使って以下のようにつなぎます。obnizには12の入出力端子がありますが、すべて汎用入出力端子となっているため、どこに差し込んでも構いません。多くのIoT機器やシングルボードコンピューターでは、どの端子に何を接続するかが決められていますが、obnizは制御側のプログラムで自由に決めることができます。このため、複数のセンサーなどを多く接続することが容易になっています。
 今回は以下のようにobnizのio0〜io2にマイクロビットのP0,P1,GND端子をつなぎます。

【マイクロビット側】 【obnize側】
P0端子 io0 (RX/RXD)
P1端子 io1 (TX/TXD)
GND端子 io2 (GND)

 次にobniz側でマイクロビットから受け取るデータを表示するプログラムを書きます。obnizでは通常のコードを入力して作成する方法とブロックを使って組み立てていく方法があります。今回は、コードを入力してプログラミングを行います。トップページからDeveloper's Console(開発者コンソール)クリックで開発者ページを表示、「プログラム」のボタンをクリックします。

 すると対象となるobnizの番号を入力する画面になります。obnizに表示されている番号を入力します。

obnizのドキュメントやリファレンスは用意されているので、詳細については説明しません。おおまかな流れだけ説明します。  まず、obnizの処理のいくつかは非同期で処理されます。非同期処理だとPromiseオブジェクトを利用することになりますが、obnizはWebブラウザから制御するため常に最新のJavaScriptを使うことができます。このため面倒なPromiseオブジェクト云々を書かなくても便利なasync, awaitを使うことができます。asyncは非同期処理する関数に対して指定します。awaitは非同期で処理を待つ場合に指定します。

 最初に対象にするobnizを指定します。new Obniz()とするとコンストラクタが作成されます。この時にパラメーターを指定しないと実行時にダイアログが表示され、そこでobnizの番号を指定することになります。複数のobnizで動作検証を行う場合や、どのobnizで実行するか決まっていない場合には便利です。
 実行するobnizが決まっている場合にはnew Obniz('1234-5678')のようにobnizの番号を指定しておきます。なお、今回の書き方では誰でもネットからアクセスし制御できてしまいます。他の人によるアクセスを回避する場合はアクセストークンを使ってください。
 obniz側の実行準備が可能になるまでawait obniz.connectWait()として待ちます。
 次にマイクロビットと接続するIO端子の設定を行います。io2番をGNDに設定するにはobniz.io2.output(false)とします。

 io0をRX(受信)、io1をTX(送信)に設定するにはuartのtart()メソッドを使い以下のように指定します。0や1がIOの番号を示しています。

obniz.uart0.start({rx:0, tx:1})

 これで設定が完了です。あとは、データを受信したらWebブラウザの画面(obnizのデバッグコンソール)にデータを表示します。標準状態では表示されていないので、グレーの帯になっておりShow Consoleと表示されている文字の部分をクリックしてください。データを受信するとreceiveイベントが発生します。イベントが発生した場合に何か処理を行うにはonreceiveプロパティにイベントハンドラ(関数)を指定します。イベントハンドラには2つのデータが渡されます。最初のパラメーターには受信したデータが配列として渡されます。受信したデータが配列に格納されています。1文字ずつ処理する場合には便利です。
 2番目のパラメーターには受信したデータを文字列に変換したものが渡されます。今回はマイクロビットから明るさのデータが文字列で渡されますので、これをそのまま表示します。せっかくなので、先頭2文字分のデータも表示することにします。
 obniz側のプログラムは以下のようになります。なお、ヘッダー部分(<head>〜</head>)はバージョンが異なる場合には注意のアイコンが表示されます。その場合は最新版にアップデートしてください。今回必要なプログラムは<body>〜</body>のみですので、ここだけコピー&ペーストして利用しても問題ありません。

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport"     content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://unpkg.com/obniz@latest/obniz.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/iothome/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/airobot/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ui/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/opencv3.4/opencv.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.5"> </script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@0.2.2">     </script>
</head>
<body>
Micro:bit Serial
<div id="OBNIZ_OUTPUT"></div><br/>
<script>
(async function(){
  var obniz;
  obniz = new Obniz('●●●●-●●●●');
  await obniz.connectWait();
  obniz.io2.output(false);
  obniz.uart0.start({rx:0, tx:1});
  obniz.uart0.onreceive=function(data,text){
    console.log(data[0]+":"+data[1]+">"+text);
  }
})();
</script>
</body>
</html>
【注意】●●●●-●●●●には使用するobnizの番号を入れてください。obnizの電源が入った時に液晶画面に表示される4桁の番号です。以後のコードでも同様です。

次にマイクロビット側のプログラムを作成します。これまでと同様に「明るさ」を取得してobnizに送信してみましょう。シリアル通信のカテゴリは高度なブロック内に用意されています。

使用するのは「シリアル通信 送信先を変更する」「シリアル通信 数値を文字で書き出す」の2つのブロックです。まず、通信速度などの設定はマイクロビット側で用意してあるものをそのまま使います。また、obniz側でも同じ設定になっているため、最初だけのブロック内に「シリアル通信 送信先を変更する」ブロックを入れます。次に明るさを送信するブロックを図のように組み立てます。

 JavaScriptコードの場合は以下のようになります。

serial.redirect(
SerialPin.P0,
SerialPin.P1,
BaudRate.BaudRate115200
)
basic.forever(function () {
    serial.writeNumber(input.lightLevel())
    basic.pause(1000)
})

 プログラムをダウンロードしマイクロビットに転送して動作を確認します。マイクロビットから送られた明るさの数値がWebブラウザの画面に表示されるはずです。
 データがうまく受信できない場合は、obniz側のプログラムを一度終了し再度実行してください。もし、ブラウザ画面上にWebSocketエラーのメッセージが表示される場合も一度プログラムを終了させ再度実行してください(表示されても通信されている場合はそのままでも構いません)。どうしても通信できずエラーが出る場合はブラウザを変えてみてください。
 また、ワニ口クリップなどで接続している場合、線がちゃんとつながっているか、他の線や端子に接触していないか確認してください。

次にWebブラウザの画面上に明るさの数値を表示するのではなく、obnizの液晶画面に表示してみましょう。液晶画面に表示する文字のサイズは以下のように指定します。font()の最初のパラメーターには書体名を指定しますが、nullにしておくとデフォルトのフォントになります。2番目の数値が文字サイズになります。

obniz.display.font(null,48)    

 次に液晶画面に文字を表示しますが、その際obniz.display.clear();として表示内容を消去しておきます。消去した後でobniz.display.print(表示する数値)とします。obniz.display.print()だけでも数値は表示されますが、画面下まで表示した際に自動的にスクロールしません。このため、液晶画面全体を消去した後で数値を表示します。
 実際のプログラムは以下のようになります。

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://unpkg.com/obniz@latest/obniz.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/iothome/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/airobot/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ui/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/opencv3.4/opencv.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.5"> </script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@0.2.2"> </script>
</head>
<body>
Micro:bit Serial
<div id="OBNIZ_OUTPUT"></div><br/>
<script>
(async function(){
  var obniz;
  obniz = new Obniz('●●●●-●●●●');
  await obniz.connectWait();
  obniz.io2.output(false);
  obniz.display.font(null,48)
  obniz.uart0.start({rx:0, tx:1});
  obniz.uart0.onreceive=function(data,text){
    obniz.display.clear();
    obniz.display.print(text);
  }
})();
</script>
</body>
</html>

obnizからのデータをマイクロビットで受信する

 それは次にobnizからマイクロビットにデータを送信してみます。マイクロビットでは送信された文字をLEDに表示します。
まず、シンプルに決められた文字をobnizからマイクロビットに送信します。シリアルで送信するにはsend()メソッドを使います。パラメーターに送信したい文字列を指定します。例えばsend("A")とするとAの文字が送信されます。なお、マイクロビット側で受信できる文字数に限度があるので、一度に多くの文字列を送信すると途中までしか処理されません。
 実際のプログラムは以下のようになります。

<html>
<head>
    <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://unpkg.com/obniz@latest/obniz.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/iothome/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/airobot/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ui/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/opencv3.4/opencv.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.5"> </script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@0.2.2"> </script>
</head>
<body>
Micro:bit Serial
<div id="OBNIZ_OUTPUT"></div><br/>
<script>
(async function(){
  var obniz;
  obniz = new Obniz('●●●●-●●●●');
  await obniz.connectWait();
  obniz.io2.output(false);
  obniz.uart0.start({rx:0, tx:1});
  obniz.uart0.send("microbit+obniz");
})();
</script>
</body>
</html>

 次にマイクロビットの受信プログラムを作成します。初期設定部分は今までと同じブロックをそのまま配置します。
「シリアル通信 文字列を読み取る」ブロックを使えばシリアル通信データを読み出すことができます。データは文字列なので、このブロックをLEDの「文字列を表示」ブロックに入れます。
 プログラムは図のように組みます。

 JavaScriptコードの場合は以下のようになります。

serial.redirect(
SerialPin.P0,
SerialPin.P1,
BaudRate.BaudRate115200
)
basic.forever(function () {
    basic.showString(serial.readString()    )
})

マイクロビットとobnizをつないだら、Webブラウザ上でプログラムを実行します。するとマイクロビットのLEDに文字が表示されていきます。

文字が表示されない場合は、線がちゃんとつながっているか確認してください。obnizの液晶画面には接続されているIO番号とともにIO接続情報が表示されています。例えば以下のように表示されます。

0 uart0 rx
1 uart0 tx
2 io output
3
4
5
6
7
8
9
10
11

 この液晶画面の表示情報とプログラムで設定した内容が合っているか確認してください。rxとtxが逆だったりすると通信できません。受信はできるのに送信できない場合はIO設定と接続を確認してください。

 それでは次にWebブラウザ画面でキーが入力されたら、マイクロビットのLEDに入力された文字を表示してみます。マイクロビット側のプログラムは何も変更する必要はありません。obniz側のプログラムを以下のように変更します。

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://unpkg.com/obniz@latest/obniz.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/iothome/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/airobot/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ui/index.js"></script>
    <script src="https://unpkg.com/obniz-parts-kits@0.11.2/ai/opencv3.4/opencv.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.5"> </script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@0.2.2"> </script>
</head>
<body>
Micro:bit Serial
<div id="OBNIZ_OUTPUT"></div><br/>
<script>
var obniz;
(async function(){
  obniz = new Obniz('●●●●-●●●●');
  await obniz.connectWait();
  obniz.io2.output(false);
  obniz.uart0.start({rx:0, tx:1});

})();
document.body.onkeydown=function(e){
  obniz.uart0.send(String.fromCharCode(e.keyCode));
  console.log(String.fromCharCode(e.keyCode));
}
</script>
</body>
</html>

キー入力はdocument.body.onkeydownのキーダウンイベントを捕捉していますが、実行時にはobnizの情報が表示されている領域内でのキー処理になります(obnizでのコンソール画面をクリックしてから実行でもOK)。
 Webブラウザで文字を入力するとマイクロビットのLEDに文字が表示されます。日本語や特殊文字には対応していないので英数字のみの表示になります。

今回はobnizのシリアル通信機能のみ使用しましたが、obnizは多数のセンサーやモーター制御などを手軽に処理することができます。ネットワーク機能がなくてもシリアル通信が可能なデバイスならobnizを経由することで簡単にネットワーク上にデータを送信することができます。デジタルハブとしてobnizは大変便利なデバイスです。また、マイクロビットと同様にブロックエディタによるプログラムの作成も可能です。興味ある方はぜひobnizでのプログラミングにもチャレンジしてみてください。

著者 古籏一浩
プログラミングをベースにして面白そうなものはとりあえずやってみるというスタンス。複雑なものよりシンプルで楽しめるものが好み。最近は30年前に移植したゲーム(mz-700版 SPACE HARRIER)の話などを書いたりしています。
著者サイト:http://www.openspc2.org/