obnizのディスプレイをコンソール代わりに使ってみた

## はじめに

どうも皆さん，お久しぶりです．

気づいたらアドベントに招待（ニッコリ）されていたので必死になって記事を書いています．
~~運営の横暴を許すな~~

前の投稿からもう1年経っていることに驚きが隠せない...
昨年のアドベントカレンダーも2日目の参加で，「[obnizでRFIDタグを使ってユーザー名とID認証やってみた](https://qiita.com/k_zoo/items/cb0bafae311346f43c48)」という記事を書きましたが，概ね好評だったようで良かったと思ってます．

さて，今回の記事は~~ユーザーデバッg~~なんと読者参加型！
自分のデバイスで再現性を確認して，筆者に報告してくれれば記事に反映します．
筆者は昔のobniz Boardを持ってるのですが，最近デバイスが色々増えててどこまで再現性あるか分からんのでね...

#### この記事での動作確認機種(とりあえずディスプレイ付きのデバイスをリスト)

|  | display.print() | display.drawing() | display.draw() | .drawImage() (画像) |
|:-:|:-:|:-:|:-:|:-:|
| obniz Board    | x | x | ○ | x |
| obniz Board 1Y |   |   |   |   |
| M5StickC       |   |   |   |   |


## なぜこの記事を書いたか
今回，アドベント登録時に宣言した「obnizで使って面白いJSプラグイン系」として
「加速度・角度センサMPU9250とAframe.jsを使って3D空間上のオブジェクトをMPU9250の動きとリンクして動かす」
って記事を投稿する予定だったんですが，開発している際に下図みたいに実行時に挙動を確認する画面が足りなくなりました．
そこで「obnizは簡単に描画できるディスプレイついてるし，ここに変数表示して状態監視できるやろ」と思ったんですが，いい感じのドキュメントがなくて詰まったので，元の目的から外れてこちらを載せることにしました．
obnizのドキュメントは「初見だとここの理解詰まるよなあ」というサポートがまだ足りてないと感じるところです．
え，筆者obnizで記事書いてる人じゃないかって？ウッ(心停止)

<img width="500" alt="Untitled Diagram.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/df88e93f-a6b4-d5d9-7be6-11a59f8005b4.png">

ちなみに「加速度・角度センサとAframe.jsを使って3D空間上のオブジェクトをセンサの動きと同じように動かす」の筆者募集中です．
ネタあげるからアドベントで誰か書いて...

## なにで詰まったのか

取り敢えず公式の[obniz.js (デバイス操作) - ディスプレイ](https://obniz.com/ja/doc/reference/common/display)を参照．

### display.print()
obniz.display.print()，1文で出力とか楽やん．ということで実行．
プログラムは最後に載せてますので気になる人は適宜どうぞ．
出力変数には，[MPU9250のライブラリ](https://obniz.com/ja/sdk/parts/MPU9250/README.md)を使って加速度と速度のx,y,z軸を列挙しています．
まあ今回はディスプレイの話なのでパーツは何でもいいんですけど．

```js
    // Case1: display.print()
        obniz.display.print('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2));
        obniz.display.print('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2));
```
<img width="500" alt="IMG_20201201_175433.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/330d79a0-8109-f47e-e6e7-021e3a416c9e.jpeg">

改行されるんですね．
1回出力消去しないとダメかーということでobniz.display.clear()を使ってみます．

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/c56885dc-7d08-eada-7ecc-325e02dcb535.gif)

点滅する!?
LCD等でもありますが，画面のリセットかけた後遅延があるとシームレスに画面が遷移しないんですよね...
しかもディスプレイに変数が収まりきらない...
他の方法を探してみます．

### display.drawing()
obniz.jsのClass内のdisplayの定義についてもう少し詳しく見てみます．
[Class Display<EventTypes>](https://obniz.github.io/obniz/obnizjs/classes/obnizcore.components.display.html)
一通り読みましたが，画面出力はdisplay.draw()とdisplay.print()，そしてdisplay.drawing()になるようです．

そこでdisplay.drawing()をやって見ました．

```js
    // Case2: display.drawing()
        obniz.display.drawing(false);
        obniz.display.pos(0,0);
        obniz.display.font('Serif',16);
        obniz.display.print('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2));
        obniz.display.print('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2));
        obniz.display.drawing(true);
```

<img width="500" alt="IMG_20201201_175554.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/5cd6389f-090d-3d68-9653-edbf52cec368.jpeg">

変数を出力するたび出力した行がどんどん上書きされていく...
結局display.clear()関数で消去しなければならず，画面が点滅しました．

### display.draw()

さて，最後のdisplay.draw()ですが，結論から言うと上手くいきました．
先ほどの[Class Display<EventTypes>](https://obniz.github.io/obniz/obnizjs/classes/obnizcore.components.display.html)によると，この関数は[CanvasRenderingContext2D](https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D)のクラス規則に則っているそうです．
なので，CanvasRenderingContext2Dにサポートされている文字列やパスのスタイル変更，更には画像の読み込みが出来そうです．ということでサイト読み読みしつつ実行．

```js
    // Case3: display.draw()
        let ctx = obniz.util.createCanvasContext(obniz.display.width, obniz.display.height);
        ctx.fillStyle = "white";
          // 白黒反転したい際に使う
          // ctx.fillRect(0, 0, obniz.display.width, obniz.display.height);
          // ctx.fillStyle = "black";
        ctx.font = "20px serif";
        ctx.fillText('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2), 0, 20, obniz.display.width);
        ctx.fillText('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2), 0, 50, obniz.display.width);
        obniz.display.draw(ctx);
```

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/e73fc270-8279-32ff-0956-5dbe21d4436d.gif)

はい．動きました．
面白いなと思ったのは，描画範囲をobniz.display.height()とobniz.display.width()で指定できるので，文字が画面からはみ出ないように自動で縮尺を合わせられることです．
フォントサイズが大きくても文字が縦長になって全部見ることが出来るのは，見やすくて嬉しいところだと思います．

### display.draw(drawImage)

余談でCanvasRenderingContext2Dにサポートされている画像の読み込みもやってみました．

```js
    // Case4: 画像を読み込みたい時
        let ctx = obniz.util.createCanvasContext(obniz.display.width, obniz.display.height);
        ctx.fillStyle = "white";
        var img = new Image();   // 新たな img 要素を作成
        img.addEventListener("load", function() {
          ctx.drawImage(img, 0, 0, obniz.display.width, obniz.display.height);
        }, false);
        img.src = 'https://illust-stock.com/wp-content/uploads/oblique-black.png';
        obniz.display.draw(ctx);
```

<img width="500" alt="IMG_20201201_183037.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/5cbc3078-cf78-5025-20d8-cd363ea46e41.jpeg">

読み込みは出来ているようですが黒一色で何も分かりませんでした．
M5持ってないので，色が出るディスプレイなら出来てるか気になるところです．
まあ当初の目的は達成したのでここら辺で終わりにしようと思います．

## 最後に

一番下にプログラムを載せるので，皆さんそれぞれ自分のデバイスで動確してなんなら報告してくれたらなあと思います．
因みにcanvasで頑張ってグラフ描画できそうですが，画像からcanvasに逆変換する方法があるらしいです．
それを使えばobnizの公式デバイスで画像表示やグラフ表示をディスプレイ上に出来る気が...誰かやっｔ

さて，obnizアドベントカレンダーはスタートしたばかりなので他の人の投稿が今年も楽しみです．
そういえば去年の記事でUbuntuに住み始めた話をしましたが，CLIとパッケージマネージャーの概念が快適すぎて今ではメインで使ってます．久しぶりにWindows使ったらウザすぎて発狂したのでもうダメそうです．

まあ与太話もこの辺で．
ではまた！


あと宣伝．
バイトでもいいのでぜひ...別に記事経由で入社しても筆者にキックバックとか一切ないですが，筆者の仕事量が減るといいなぁという淡い期待です．

>obnizではエンジニアとマーケティング/広報担当者を募集しています！
[Careers / 採用情報](blog.obniz.io/ja/careers/)
＜エンジニア＞
自由度の高い環境でIoTを学びながら成長できます！
ものづくりに興味のある方はお気軽にご連絡ください。
＜マーケティング/広報＞
企画を立ち上げたり広告を出して効果を検証するなど、マーケターとしてのお仕事が可能です。
資金力があり自由度の高いスタートアップだからこその経験がしたい方、ご応募お待ちしています！

## プログラム

```html:obniz_display.html
<html>
<head>
	<script src="https://unpkg.com/obniz@3.x/obniz.js"></script>
</head>
<body>
	<script>

		var obniz = new Obniz("obniz-id"); // obniz ID number
		obniz.onconnect = async function () { // if obniz connected

			var sensor = obniz.wired("MPU9250", { gnd: 2, sda: 0, scl: 1 });  // get MPU9250 library
			obniz.repeat(async function () {  //　repeat every 100msec (Callback)
				const MPU9250_data = await sensor.getAllWait();
				var [a_x, a_y, a_z] = Object.values(MPU9250_data.accelerometer);
				var [r_x, r_y, r_z] = Object.values(MPU9250_data.gyroscope);

    // Case1: display.print()
        // obniz.display.clear(); //画面クリア用
        // obniz.display.print('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2));
        // obniz.display.print('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2));

    // Case2: display.drawing()
        // obniz.display.clear(); //画面クリア用
        // obniz.display.drawing(false);
        // obniz.display.pos(0,0);
        // obniz.display.font('Serif',16);
        // obniz.display.print('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2));
        // obniz.display.print('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2));
        // obniz.display.drawing(true);

    // Case3: display.draw()
        let ctx = obniz.util.createCanvasContext(obniz.display.width, obniz.display.height);
        ctx.fillStyle = "white";
          // 白黒反転したい際に使う
          // ctx.fillRect(0, 0, obniz.display.width, obniz.display.height);
          // ctx.fillStyle = "black";
        ctx.font = "20px serif";
        ctx.fillText('Accel: ' + a_x.toFixed(2) + ',' + a_y.toFixed(2) + ',' + a_z.toFixed(2), 0, 20, obniz.display.width);
        ctx.fillText('Gyro: ' + r_x.toFixed(2) + ',' + r_y.toFixed(2) + ',' + r_z.toFixed(2), 0, 50, obniz.display.width);
        obniz.display.draw(ctx);

    // Case4: display.draw(drawImage)
        // let ctx = obniz.util.createCanvasContext(obniz.display.width, obniz.display.height);
        // ctx.fillStyle = "white";
        //var img = new Image();   // 新たな img 要素を作成
        // img.addEventListener("load", function() {
        //   ctx.drawImage(img, 0, 0, obniz.display.width, obniz.display.height);
        // }, false);
        // img.src = 'https://illust-stock.com/wp-content/uploads/oblique-black.png';
        // obniz.display.draw(ctx);
			}, 100);

		};
	</script>
</body>

</html>
```