ITで遊ぶ

Web Serial API

ブラウザーからUSB経由で他デバイスとシリアル通信をする、Web Serial APIというものがあります。

Google ChromeだけだといきなりGoogleが「もう、やーめた!」と言い出しかねないのですが、すでにFirefoxもサポートしているので、そんな無責任状態にはならないようです。

長い目で見ると、ブラウザーのOS化の一環かな、とも思いますが、Visual BasicやPythonのTkinterなんかでデスクトップアプリケーションを書くよりも、HTMLで書いたほうがいいであろうとは思います。

私もVisual Basicで書いたアプリがあり、そろそろWeb Serial APIを使って書き直そうと思っていました。
Visual Basicを使っていることよりも、Microsoft OLE DBプロバイダーなんてものを使っているのが気になってしようがないのです。いずれ、MSはサポートを止め、ある日のアップデートで使えなくなるのでしょうから。。。

時々、なんの危機感もなく使用され拡張されているデスクトップアプリ(こんなの)を見ると「これからどうするつもりなんだろう?」と他人事ながら気になります。
下手に権力をもって小遣い稼ぎをしていると、他の人がWebベースの後継アプリを作って使ってもらおうとしても妨害されるでしょうから、作者がボケるか死ぬまで待つしかありません。
こんな話はいたるところに転がっていそうです。

さて、正式ドキュメントはWeb Serial APIのようです。チラ見しましたが、さっぱりわからん。正式ドキュメントって厳密かつ大事なこともどうでもいいことも並列してきちんと書いてなきゃいけないから、わかりづらいのは当然なんですが、なんとかならんかね?

以前、micro:bitでこの機能を使った時に思ったのは、やはりテスト用のコンソールをhtmlで作ってもっていると、疑問点が出てきた時に試すことができて便利でした。

というわけですが、かなりクセのあるコーディングになった記憶があり、私もここから借りて来ました。ただ、海外には同じようなコードがあちこちにあります。

<!DOCTYPE html >
<html lang="ja">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Web Serial API Console</title>

    <script>
        let port;

        async function onConnectButtonClick() {
            try {
                port = await navigator.serial.requestPort();
                await port.open({ baudRate: 115200 });

                while (port.readable) {
                    const reader = port.readable.getReader();

                    try {
                        while (true) {
                            const { value, done } = await reader.read();
                            if (done) {
                                addSerial("Canceled\n");
                                break;
                            }
                            const inputValue = new TextDecoder().decode(value);
                            addSerial(inputValue);
                        }
                    } catch (error) {
                        addSerial("Error: Read" + error + "\n");
                    } finally {
                        reader.releaseLock();
                    }
                }
            } catch (error) {
                addSerial("Error: Open" + error + "\n");
            }
        }

        function addSerial(msg) {
            var textarea = document.getElementById('outputArea');
            textarea.value += msg;
            textarea.scrollTop = textarea.scrollHeight;
        }

        async function sendSerial() {
            var text = document.getElementById('sendInput').value;
            document.getElementById('sendInput').value = "";

            const encoder = new TextEncoder();
            const writer = port.writable.getWriter();
            await writer.write(encoder.encode(text + "\n"));
            writer.releaseLock();
        }
    </script>
<h1>Web Serial API Console</h1>
<button onclick="onConnectButtonClick()">Connect</button>115200 Only
<input type="text" id="sendInput" />
<input type="button" value="Send" onclick="sendSerial();" />

<textarea cols="80" rows="6" id="outputArea" readonly="readonly">
</textarea>
</body>
</html>

そうそう、async/awaitなんですよ。

asyncで宣言したら非同期で動き、return時にPromiseオブジェクトを返します。
Promiseの値がresolveならasyncから始まった関数は成功していて、rejectなら失敗しています。

awaitはPromiseの結果が返されるまで待っています。返されるとasync内の処理を再開します。

この組み合わせで非同期で動きだしても、awaitで再び同期が取れるというわけですね。
PythonのFastAPIにも同じ仕組みがありました。

なんでこんなことしているかというと、Serialからデータが入ってきたら動き出したいからですね。

Arduino側はこんな感じ。

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
}

// the loop routine runs over and over again forever:
void loop() {
  Serial.println("Hello");
  delay(300);
  Serial.println("World");
  delay(300);
  Serial.println("");
  delay(300);        // delay 300 ms
}

これで作るアプリも画面はひとつかふたつで、後はJavascriptでデータを画面に表示することになるでしょうね。
あと、HTMLでダイアログボックス作れればパーフェクトなんですけどねぇ。
いずれにしても、だんだん、CodeIgniterとかRuby On Railsから遠ざかる。。。

データベースは共通なもの(Read Only)はウェブ上にJSONデータをJavascriptとして用意すればいいでしょう。
個人のものはブラウザ内ですかね。
参考リンク

Local Storageとは

なんか、できそうな気がしてきた。

最近、GitとGithubの使い方もわかってきたし!

関連記事

  1. PHPのクラスの継承

  2. Windowsスクリプト

  3. JavaScriptグラフィック(2)

  4. アプリケーションの開発では

  5. XMLhttpRequest -> fetch

  6. WooCommerceからB2Webへ(2)

  7. 音声をテキストに(google speech-to-text API)…

  8. Google Map APIでとりあえずマーカーを立てる