見出し画像

【SALZmini2022作製日誌】BLEレシーバーを作りはじめたら、どんどん脱線して盛り上がってしまった件

はじめに

前回の記事にて、SALZmini2022の本体部分を作製しました。

今のところ、大きな問題もなく順調です。

いつも、青点滅のSALZmini2022。表面の小石はいつも乾いているので、気になって少し掘り返してみると、しっかり濡れていました。本当に乾いてから水やりできているのかわかりません。

この装置がどれだけ頑張っているか、よく見てみたいと思うようになってきました。

今この時点で、やりたいことが2つあります。

1つ目は、今までのようにWifi接続しAmbientへデータを飛ばすゲートウェイ機能を実装することです。今まで使ったことのないデバイスを試してみたいと思っています。

2つ目は、装置のコントロールです。
BLEアドバタイズ通信で一方向の通信を行うことができましたが、本来ならもっと装置に働きかけができるんじゃないか、と思っています。

例えば、「今すぐ水やり」、「しきい値設定」コマンドなどできるとよいと思います。これができると、可能性が格段に上がってきます。AtomLiteやM5StampC3で、いろんなものの制御ができるようになると思います。

昨年買ったChromeBookを活用してみよう。

ゲートウェイ機能は、常時動作させるものなので、24時間電源入れっぱなしでも罪悪感のないマイコン系がいいかなと思いますが、アドバタイズ信号を一時的に確認するのは、スマホやタブレットのようなものがよいと思います。マイコン系でのゲートウェイ機能の実装は実績があるので、いつでもできます。であれば、ここはスマホやタブレットで制御できるものを探してみたいと思いました。

ゲートウェイというよりも、レシーバーを作りたい。

ということになりそうです。
昨年、屋外でマイコンのそばで使えるPCが欲しいと思い購入したChromeBook。苦手だったUnixの克服。Pythonの習得。人工生命の復習。など、たくさんの知識を得ることができました。
今回はこちらの端末を用いて進めて行きたいと思います。

ネットで検索するといい情報に当たりました。

株式会社 芳和システムデザイン さんの
Web Bluetooth を使ってみよう!その1

を参考に進めて行きたいと思います。
と勢い込んで進めてみましたが、理解が追いつきません。
Webページを作るのも数十年ぶりで、どこから手を付けていいか分かりません。

「どこにスクリプトを書けばいいの?」

からのスタートです。

「ローカルでhtmlファイルを書くの?」
「JavaScriptはどこで書くの?」

謎は深まるばかりです。

かじるプログラミング さんの
VS-CodeであっさりJavaScript

を見ました。
そうか。VSCodeがあるじゃないか!!

こういう、もやもや案件にぴったりのツールがVisualStudio Code のような気がしてきました。

読み進めると、拡張機能で「Live Server」を追加するとよいようで、ローカルで組んだWebページをChromeブラウザで動作させることができるようです。

こういった小技がすぐに見つかるのが、ありがたいです。そして、こんな拡張機能を作ってくれたRitwick Deyさんにも感謝です。

Ritwick Deyさん

というわけで、早速試してみることにしました。

ばっちり動きます。
ならば、Web Bluetooth もうまく動くんじゃないか?
やってみることにします。

まずはChromeの設定を変えるようです。
URL欄に「 chrome://flags/#enable-experimental-web-platform-features」を入力し、「Experimental Web Platform features」を「Disabled」から「Enabled」へ変更します。

ブラウザを再起動して、さあここからと思ったのですが、ゴールまで見渡せるサンプルを見つけることができませんでした。

Javascriptのサンプルファイルはあるのですが、ブラウザから呼び出すためのhtmlファイルが見当たりません。初心者にとってはここが一番肝心です。

少し戻ってみることにします。
別のサンプルを探してみました。

アナログ・デバイセズさん
センサーデータをWeb Bluetooth APIで取得しよう!

https://www.analog.com/jp/education/landing-pages/003/iot_lectureship/content_01.html

こちらにもサンプルがあり、こちらには、htmlとJavaScriptの両方がありました。ソースを見てみると、BlueJellyというものを使っていました。
これは何だろう?
と思い調べていくと、

BlueJellyって何だよ!

に行き当たりました。
Chromeのテスト機能である「Web Bluetooth API」をシンプルにラッピングしたライブラリという感じでしょうか。

これはなかなか期待が持てそうです。

bluejelly

ここにサンプルがありました。

クラゲのIoT - Scanで Hello, BLE

ああ。まさにこれです。
これがやりたかったのです。

これが、ChromeBookにダウンロードしたソース上で動くでしょうか。
試してみました。

右側のペインで右クリックし「Open with Live Server」を選ぶと。。。

お、動いた!

SALZmini2022-1が見つかりました!ペア設定ボタンを押してみます。

ばっちり動きました。
あとはこれらのサンプルを読み解き、目的のツールを作ることとなりました。

JavaScriptについて、分からんなー、難しいなーと思っていましたが、そう言えば、昔チャレンジしていたことを思い出しました。

そうか。obnizを使ったときに勉強したな。コールバック地獄の日々が懐かしいです。この手のプログラミングは、どんなシチュエーションで、どんな割り込みが起こるかわかっていないと、想定外のことが起きてしまうという、よい教訓になりました。

このときは、obnizのサイトでプログラムが組めたのでした。

サンプルを見ながら少しずつ理解を深めていきます。

こちらのサイトは段階を踏んで丁寧にわかりやすく書かれています。

クラゲのIoT - ConnectとUUID

クラゲのIoT - Readでデータ読み込み

クラゲのIoT - Notifyでデータ読み込み

クラゲのIoT - Writeでデータ書き込み

クラゲのIoT - Disconnectなどの終了処理と状態遷移

全部理解して試したい気持ちがふつふつと沸いてきました。
ということは、ひとまずSALZminiから離れ、こちらのサンプルに沿ってmicro:bitでお相手を作るところから始めたいと思います。

家のストックから探してみると、chibi:bitが見つかりました。

ありました!chibi:bit
電池駆動できるようにしてました。

私の現在の活動の元となった最初に入手した記念すべきマイコンです。
当時、何もわからないまま、組み込み装置の勉強がしたくなって、日本橋の共立電子へ行き、店頭で見つけたものです。

今では、micro:bitが日本国内で普通に売っていますが、当時は「技適」の関係で互換機が作られていたということなんでしょうか。詳しいことはわかりませんが、今思うとなかなかレアな買い物をしていますね。

chibi:bit

これがChromebookとつながり、実験のためのプログラムが書き込めるかやってみることにします。
BLE信号の発信元を作り出せれば良いので、Chromebookと繋がることはマストではありませんが、チャレンジしてみます。

クラゲのIoT - micro:bitでBLE設定

ここはとことんクラゲさんに頼って進めてみます。
何度も書きますが、とても親切な説明で迷うことなく進めることができます。

クラゲのIoT - micro:bitでのBLEブロック作成例

久しぶりにMakecodeを使います。ブラウザで動く開発環境は本当にお手軽でよいですね。
本当はクラゲさんの言うとおりにブロックをポチポチ置いて行きたかったのですが、JavaScriptのコードをコピペしてしまいました。

Chromebookと chibi:bit を接続します。
接続は、Type-C => Type-C - Type-A*4ハブ => Type-A - Micro USB Type-B(2.0)で、プログラムを書き込みます。

多分、成功。ちょっと歯切れが悪いです。

というのも、chibi:bitの動作が期待したものと違う感じだからです。

ディスプレイには「☹050」が繰り返し表示されています。

温度計、LED、UARTサービスを初期化しているのですが、そもそも、温度計はついてたっけ?

とか、いろいろ考えてしまいます。

それでも、BLE通信は動いているようです。

BBC micro:bitの表示が見えています。

どうも正しく動いていないようです。
調べてみます。

Haradware errors
050: An error occurred with the micro:bit's accelerometer component.

とあります。

テストのためにmicro:bit v2を購入するのはどうかと思いましたが、折角の学びの機会を逃してしまうのは勿体ないと思い、取り寄せました。

こちらを用いて、テストの続きを行います。
同じプログラムを入れて試してみると。。。

明らかに動作が異なっています。
このBLE発信機を用いて従前のサンプルを試してみることにしました。

クラゲのIoT - Scanで Hello, BLE

クラゲのIoT - ConnectとUUID

クラゲのIoT - Readでデータ読み込み

クラゲのIoT - Notifyでデータ読み込み

クラゲのIoT - Writeでデータ書き込み

クラゲのIoT - Disconnectなどの終了処理と状態遷移

当然のことなのですが、いずれのテストも正常に動作しました。

クラゲさんの貴重な情報により、BLE通信についても少し理解が深まった気がします。
Scanして、Connectして、Readして、Notifyして、Writeして、Disconnectする。
これらに必要な手続きを一つずつ学んで行きました。

各サンプルのhtmlを読み、その中のJavaScriptで書かれた部分を読み解いて行きます。JavaScriptのソースは、イベントハンドラの塊で、逐次実行されるフローを追うという感じではありません。

私の理解では「イベントハンドラ」というのは、「こんなことが起こったら、通常と違ってこんな処理するからよろしく。」という、下打ち合わせをするものと理解しています。

「通常と違って」というのがミソで、各イベントの発生時にデフォルトの処理は行われていることが多いです。何も気にしないときは、デフォルトの処理に任せておき、特別な処理をしたいときのみ、イベントハンドラで処理を記述します。

ということは、
 ・いつイベントが発生するのか?
 ・どこでイベントが発生するのか?
 ・誰がイベントを発生させているのか?
 ・どんなイベントが発生するのか?
 ・なぜイベントが発生するのか?
ということを知ってないと、組めないと思うのです。

私は、今となっては古いタイプのプログラマだと思うので、上記のことが気になって、オブジェクト指向型のプログラムがとても苦手です。

ソースを読んで何となくやりたいことは理解できるのですが、じゃ自分で書いて。と言われると、書ける自信が全くありません。

藁をも掴む気持ちで、以前読んで参考になった本、

Bluetooth Low Energyをはじめよう

をもう一度読み返し理解を深めようとしました。

が、結果は失敗でした。
2つの情報の間で情報のつなぎ合わせがうまくできず、さらに混乱してしまいました。
BLE通信の沼にはまり溺れてしまうところでした。
ただ、BLEを理解するときに必要となるだろういくつかのキーワードを拾うことができました。

GATT:Generic ATTribute profileの略

GAP:Generic Access Profileの略

UUID:ソフトウェア上でオブジェクトを一意に識別するための識別子のこと。サイトで発行したものを使用することができる。

GATT、GAPこのあたり説明できません。意味も理解できていません。

久しぶりに、壁にぶつかりました。

できそうでできなくて。でもできていて。
一晩寝て、ひとつのプランがひらめきました。

ESP32 BLE関連サンプルのまとめ(自分用)

ArduinoIDEでM5StampC3に対して、BLEのプログラミングをする際に、上記のサンプルを見てみました。よく見ると、

BLE_server
BLE_notify
BLE_write
BLE_uart

あたりは、micro:bitで行ったテストに近いんじゃないか。ということに気が付いたのです。ということは、micro:bitの替わりにM5StampC3で置き換えることができるのではないか。

多分、このあたりのことをよくわかってらっしゃる方からしたら「何をやっとるんだ。」とお叱りを受けそうですが、どうもこのあたりが、もやもやしている部分なのです。

ともかく、試してみることにしました。

M5StampC3でBLE_server

を動かし、

クラゲのIoT - Scanで Hello, BLE

で受けてみます。

結果は成功です。

ここで安心しないで、記事をきちんと読んでみました。
JavaScriptのイベントハンドラとメソッドの嵐の中、ソースを読んで理解することはできました。
基本の基本はOKです。

次に、M5StampC3でBLE_server

を動かし、

クラゲのIoT - ConnectとUUID

を試してみたいと思います。
このあたりから、ゆっくり進めた方がよいでしょうか。

connectするためには、相手のUUIDを指定しなければなりません。connect.htmlをコピーし、myconnect.htmlを作成します。

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

を指定してみます。

myconnect.html:

//--------------------------------------------------
//ロード時の処理
//--------------------------------------------------
window.onload = function () {
  //UUIDの設定
  ble.setUUID("UUID1", "4fafc201-1fb5-459e-8fcc-c5c9c331914b", "beb5483e-36e1-4688-b7f5-ea07361b26a8");
}

のように書き換えました。
これで、実行してみると。。。

動きました!「connected GATT!」の表示が見えます。

出ました「GATT」。「Bluetooth Low Energyをはじめよう」に出てきた用語です。まだあまり理解できていないですが、見知った単語が出てくるだけで安心します。事前に勉強していたことが活用できている感じがします。

今度は、

クラゲのIoT - Readでデータ読み込み

に挑戦します。

合わせるプログラムは、BLE_notify

です。M5StampC3のサンプルを見ていて、一番合ってそうだったからです。ただ、ソースも全体をぼーっと見ているだけで、細かい部分まで理解はしていません。

なんだか、動いてるっぽいです。「Read」ボタンを押すたびに、ランダムに数値が変化します。ざっと見たソースの感じだと、

BLE_notify:

uint32_t value = 0;
(略)
void loop() {
    // notify changed value
    if (deviceConnected) {
        pCharacteristic->setValue((uint8_t*)&value, 4);
        pCharacteristic->notify();
        value++;
        delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
(略)
}

32ビット符号なし整数valueをloop()の中でdeviceConnectedのとき、setValueして、カウントアップしています。この際、setValue((uint8_t*)&value, 4)としているので、4バイトの値を書き込んでいるのですが、(uint8_t*)にキャストしているのは、

void BLECharacteristic::setValue(uint8_t *data, size_t length)

setValue()の定義のようでした。深読みすると、「?」がたくさんあるので、今はここまでで先へ進むことにいたします。

さらに、実験を続けます。

クラゲのIoT - Notifyでデータ読み込み

をBLE_notify

に合わせます。

これは動く自信がありました。
こんな感じです。

「Start Nortify」ボタンで開始です。
「ESP32」を選択します。
カウンターの数字が高速で書き換わります。

動画にしてみました。

delay(3);

が効いているのでしょうか?
更新間隔がとても速いです。

これで最後の実験です。

クラゲのIoT - Writeでデータ書き込み

合わせるプログラムはBLE_write

です。

プログラムの初期画面です。
受け側のM5StampC3のシリアルモニタの様子です。

まず、「Write」ボタンを押し、デフォルト文字列を送信した後、「BonitoBonsaiDaisuki!」と打って「Write」ボタンを押しました。

5- See the magic -)

どちらの文字列も送信できていました。すごい!

何度も書きますが、分かっている人にとっては何でもない作業だと思うのです。
これが初学者にはとても高い壁になっていて、その壁に風穴を開けることができたことに対してとても感動しています。

さいごに

今回はここまでで力尽きてしまいました。
SALZmini2022のBLE信号を捕まえるために色々調べていたら、どんどん脱線して盛り上がってしまいました。今回の最大の収穫は「Web Bluetooth API」との出会いです。そのラッパーライブラリ「BlueJelly」とその説明ページに出会え、一気に理解が進みました。

BlueJellyとmicro:bitをコネクトするサンプルを元に、BlueJellyとM5StampC5をコネクトできるか試してみました。結果的には、よく似たサンプルをマッチングし、BlueJelly側のhtmlファイルのUUIDをM5StampC5のサンプルプログラムのものに書き換えただけで、connect、read、notify、write、のテストを行うことができました。

これで、なんとか次へ進めそうです。

次回はChromeBookから、M5StampC5を覗いたり、値を書き込んだりできるようチャレンジしたいと思います。

最後までお読みいただき誠にありがとうございました。

#SALZ
#自動水やり装置
#園芸
#電子工作
#M5StampC3
#WateringUnit
#M5Stack
#ArduinoIDE
#BLE
#WebBluetoothAPI
#BlueJelly
#Chromebook
#IoT
#chibibit
#microbitv2
#Javascript
#Makecode

この記事が気に入ったらサポートをしてみませんか?