こちらの記事について、内容・翻訳・視点・長さなど、皆様のご意見をお送りください。今後の記事製作の参考にしたいと思います。
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
こちらの記事の感想をお聞かせください。
はじめに
ようこそ!この記事は私のプロジェクトであるブリーズベターベアー(Breathe Better Bear)についての連載記事です。今回はその最終パートとなります。
Part 1ではプロジェクトの紹介、課題と使用材料についてお話しました。Part 2ではこのプロジェクトを再現するためのレーザーカットファイルと3Dプリントされたパーツ、さらに部品同士や部品とReka:bitボードとの接続方法についての構築ガイドをしました。
このPart3ではプロジェクトのプログラミングについてお話します。私はプログラムやIoT関連の製作を行うのが初めてだったのでとても苦労しましたが、幸いなことに優秀なPete Milneさんにたくさん助けてもらいました。
ブリーズベターベアーのアイデアはESDKセンサーからの情報と、大気質指数の予測を支援する外部APIの両方にアクセスを実現します。これにより、ユーザーはセンサーによる現在の(地域の)状況と、APIによって情報提供される地域の予測の2つのモードを選択できる構成となっています。
では早速コーディングを行っていきます。コーディングは以下のようにいくつかのセクションに分けて実行していきます:
- クマの挙動をコーディング
- クマをWi-Fiに接続
- Mosquittoを使ってMQTT接続をテスト
- Node-REDをインストール
- Node-REDを用いてESDKセンサーのデータを取得
- Node-REDを用いてAPIに接続
クマの挙動をコーディング
こちらのサイトではこのセクションで作成したクマのコードを閲覧、ダウンロードすることができます。
ではクマの内部のコーディングをしていきます!今回、私はMicro:Bitが含まれたReka:Bitボードで使用したので、MakeCodeコーディングをしました。
前回の記事(Part2)ではクマの作成と組み立て方法を説明しました。作成したクマに命を吹き込むためには、4つの要素をコーディングを通して動かす必要があります。4つの要素とは指差す腕、左眉毛、右眉毛、反転して表情を変える口です。
それに加えて、受信情報をローカル(局地)情報かリージョナル(地域)情報かを切り替えるトグルスイッチと、選択状態を示すライト、そして大気の質が大きく低下したときに点滅するハザードコンディションライトの動作もコーディングします。
前回お話したように、クマは6段階の大気質指数(AQI)によって表情を変えます。プロジェクトではアメリカのレベル分け、良好(Good)、ふつう(Moderate)、過敏症の人には健康害有(Unhealthy for Sensitive Groups)、不健康(Unhealthy)、非常に不健康(Very Unhealthy)、危険(Hazardous)の6段階を使用しています。そのため、各レベルの表情と挙動は対応付けられ、一連のパラメータは異なる関数にそれぞれ割り当てられます。関数ブロックはAdvancedドロップダウンメニューの下にあります。
私のコードでは構築ガイドでも話したように、サーボ1(S1)が腕、サーボ2(S2)が口、サーボ3(S3)が左眉毛、サーボ4(S4)が右眉毛になります。9番ピン(P9)はハザードビックリマークで、12番ピン(P12)とP2がステータスライトです(ステータスライトのコードは上の写真に写っていません)。
プロジェクトではMicro:bit v.2を使用したため、ピンを割り当てずとも簡単な音を再生できます。ここで使用したオレンジ色のサーボブロックはすべてReka:Bitエクステンションの下にあります(Advanced>Extensions>Rekabitにあります)。
下のコードは異なる表情ごとの関数を呼び出す永久ループです。このコードを追加することでクマの挙動をテストできます。
この永久ループでサーボの回転位置、設定角度を試行錯誤して決定しました。AQIレベルごとに欲しい挙動が得られるようになったら、次にクマをWi-Fiに接続します。
クマをWi-Fiに接続&MQTT接続テスト
Wi-FiとMQTTサーバーに接続するには、Wi-Fモジュールを使用できるようにする別のMakeCodeエクステンションが必要です。エクステンション(extensions)でesp8266と検索すると、下のようにいくつかのオプションが表示されます。今回使用しているモジュールはCytronブランドですが、MQTTブロックへのアクセスがより容易なiot-environment-kitの方を使用することにします。
Wi-Fiモジュールとの接続を確立し、その後にMQTTブローカーとの接続を確立するには、ブロックが「on start」に含まれている必要があります。トラブルシューティングを容易にするためにコードに含まれているのは、下図のように数個のみの接続テストブロックです。
まずMicro:bitが起動したら、ハートのアイコンを表示させます。次にWi-Fiモジュールが接続されているPin(今回はRx P16とTx P15)に接続情報を設定します。そして、Wi-Fiの認証を行い(ブロック内のName of WiFiとPasswordのテキストを置き換えてください)、数秒間待ちます。ポーズ後にWi-Fi接続がtrueかどうかをテストする、if trueブロックが実行されます。接続されているかどうかに応じてチェックマークまたはxを表示します。それが完了したら、MQTTサーバーとの接続を確立するためのブロックが実行され、接続状況に応じて再びチェックマークかxが表示されます。今のところ、このコードではtest.mosquitto.orgサーバーを使っていますが、これについては後程説明します。この時、別のMQTTサーバーを使用する場合は後で変更する必要があります。
このコードではクマの電源を入れ、Wi-FiとMQTT接続が確立されていればMicro:bitにハートアイコンが表示され、次にチェックマークが表示され、数秒後にまたチェックマークが表示されます。ハートの後にxが表示された場合は、Wi-Fiの接続に失敗しているのでピンのチェックまたはWi-Fiの認証情報を確認する必要があります。1回目のチェックマークの後にxが表示される場合は、MQTTサーバーの接続に失敗しているので、サーバーの情報(スペル、ポート)が正しいかを確認する必要があります。
「はじめに」でお話したように、クマの設定には2つのモードがあります。1つはESDKセンサーからの情報を取得、もう1つはAPIの情報を取得するモードです。この2つのモードを可能にするために、クマの上にあるスイッチ用のコードは「mode」変数を「local」または「regional」に設定し、モードに対応した表示灯を点灯させるようにします(下図)。
次にMQTTブロックに、MQTTサービスが特定のTopicで送信するメッセージを待ち受ける「when Topic」ブロックを追加することができます。このクマの場合、2種類のトピックについてのメッセージを取得します。1つはregional/api(APIサーバーからのAQIデータを取得)で、2つ目はlocal/pm2pt5(ESDK PM2.5センサーデータを取得)です。
このコードでは、まずそのトピックに関するメッセージがあるかどうかを確認し、メッセージがある場合にはそれがスイッチによって設定された変数の正しい「モード」であるかを確認します。trueの場合には、そのメッセージ内容を確認します。メッセージの内容はユーザーによって定義されますが、上のコードでは1~6の数字に設定されています。これは大気質指数APIの大気質レベルの数字と一致するようにしているためです。特定の番号を受信すると、コードは対応する変数を呼び出し、クマはプログラムされた動作を行います。
もしMakeCodeが数字をメッセージとして追加させてくれない場合は、数字を”テキスト”として解釈させて追加します。テキストと解釈させるにはテキストボックスを使って下のようにコーディングします。テキストボックスブロックは、Advanced>Textの一番上にあります。
これでクマ内部のコーディングは完了です!
Mosquittoを使用してMQTT接続をテスト
クマのコーディングができたので、次はMosquittoテストサーバーでテストしてみましょう。MosquittoとはMQTTブローカーです。開発者がMQTT設定などを確認するために提供しているテストサーバーなどに使用します。
初めにMosquittoをコンピュータにインストールして、サーバーと「会話」できるようにします。Mosquittoのウェブサイト(https://mosquitto.org/download/)には、様々なシステムに対応したダウンロード方法が掲載されています。自身の環境に合わせてダウンロード・インストールしてください。
ダウンロード・インストールしたら、Mosquittoを使ってテストサーバーにコマンドを送信して希望のトピックに関連するメッセージを公開します。
※今から説明するコンピュータの環境はMacOSでしたので、違うOSをお使いの方は手順が違っているかもしれません、ご注意ください。
MacOSでメッセージを送るには、Mosquittoが正常にインストールにした後でターミナルウインドウを開き、次のように入力します:
mosquitto_pub -h test.mosquitto.org -t ‘regional/aqi’ -m ‘3’
上のコマンドはMosquittoのホストである、test.mosquitto.orgのトピック「regional/aqi」にメッセージ「3」を公開することを意味しています。MacOSのターミナルではメッセージの送信にダブルクォート「" "」ではなくシングルクォート記号「' '」を使用することに注意してください。
この時点でクマの電源が入り正しくコーディングされ、上部のスイッチが「regional」設定に切り替えられていれば「Unhealthy for Sensitive Groups」カテゴリの挙動をするはずです。
Node-REDのインストール
ここからはESDKユニットをお持ちで、基本的なセットアップ手順に従った説明となります。もし、Raspberry Piにセンサーを付けて動作させている場合などある程度技量がある方は説明についてこられると思います。※別途でESDKユニット以外のアーキテクチャを使用したガイドはすることができません。
ESDKにはセンサーからの情報をMQTTメッセージとして「airquality」というトピックで送信するなど、カードをイメージ化する際に必要な設定があります。
私はビジュアルコーダー(視覚的プログラマ)なので、Peter Milne氏の案内でビジュアルコーダーに合うNode-REDをインストールすることにしました。これはブラウザ経由で「node」コーディングにより、Raspberry Pi(その他のプラットフォームも可能)をコーディングできるプログラミングツールです。
Peter Milne氏が教えてくれたNode-REDのインストール方法です:
1. SSHでリモートログイン
ssh pi@airquality.local
2. システムのアップデート
sudo apt update
sudo apt upgrade
3. stop(下)ボタンで電源を切り、電源を取り外し、数秒待ち再度電源を入れる
システムが正常に動作していることを確認
4. Node-REDを下記のRaspberry Piインストールスクリプトを実行し、インストールする(詳細は>https://nodered.org/docs/getting-started/raspberrypi)
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
スクリプトを実行すると次のような出力が得られる:
Running Node-RED install for user pi at /home/pi on Raspbian
This can take 20-30 minutes on the slower Pi versions - please wait.
Stop Node-RED ✔
Remove old version of Node-RED ✔
Remove old version of Node.js ✔
Install Node.js 14 LTS ✔ v14.18.3 Npm 6.14.15
Clean npm cache ✔
Install Node-RED core ✔ 2.2.0
Move global nodes to local -
Npm rebuild existing nodes ✔
Install extra Pi nodes ✔
Add shortcut commands ✔
Update systemd script ✔
エラーが発生した場合は/var/log/nodered-install.logにログが記録されます。
これですべて完了です。
Node-REDを起動するにはnode-red-startコマンドを実行するか、Menu / Programming / Node-REDにあるアイコンを使います。
次にブラウザでlocalhost:1880またはhttp://{your_pi_ip-address}:1880にアクセスします。するとpiでは次のような出力が得られます:
Started : Tue 1 Feb 11:34:14 GMT 2022
Finished: Tue 1 Feb 11:38:09 GMT 2022
うまく行かない場合はnode-red admin initを実行して初期オプションと設定を変更してみてください。
5. Node-REDを起動する
node-red-start
6. 自動起動の有効化
sudo systemctl enable nodered.service
7. システムの再起動とNode-REDの自動起動の確認
8. ブラウザを起動し、airquality:1880に移動 - ブラウザウインドウにフローが表示
nodeを変更する場合はその都度、デプロイし直す必要があります。
Node-REDのドキュメントは>https://nodered.org/docs/
ESDK MQTTメッセージのフォーマット:
{"hardwareId": "RPI0000000010f6d74f",
"thv": {"vocIndex": 100, "temperature": 23.7, "humidity": 36.5, "sensor": "THV0.2"},
"pm": {"sensor": "PM20.2", "pm1.0": 1, "pm2.5": 1, "pm4.0": 1, "pm10": 1},
"geohash": "u11n9g377406", "co2": {"sensor": "CO20.2", "co2": 720}
}
Node-REDをインストールが済んだら、ブラウザでお使いのpiのIPアドレス:1880(クマ + ESDKの場合はhttp://airquality.local:1880)を入力して接続し、コーディングを開始することができます。
この時点でクマがESDKと会話し、それからESDKからのMQTTメッセージを受信できるようにするには、connect MQTTブローカーホストブロック内のコードをESDKのIPアドレスと一致するように変更する必要があります。このIPアドレスはルーターのadmin(管理)ページから確認できます。hostname(ホスト名)を使用すると接続はうまくできませんので注意してください。
Node-REDを用いてESDKセンサーのデータを取得
Node-REDではブロック、またはnode(ノード)と呼ばれるものを使用しています。ダブルクリックすることで設定を変更でき、横にある小さな灰色のボックスをクリックして、接続したいブロックにラインをドラッグすることで相互に接続できます。
これが私の最初の「フロー」の概要で、センサーデータを取得してクマに送信するためのコードです。
以下、各ノードについて説明します。使いたいノードを見つけるには、色とアイコンを見ます。名前はカスタマイズ可能で、例えば「pm2pt5_filter」という名前のノードがデフォルトであるわけではありません。ダブルクリックすると、設定を編集できます。
- ESDK - このノードはairqualityというトピックをサブスクライブしているESDKのMQTTサービスに接続します。これはESDKに接続されたセンサーから、送信している情報を読み取ります。鉛筆の編集ボタンをクリックすると、MQTTブローカーの特定の情報を編集できます。
- Pm2pt5_filter - ESDKからの情報をフィルタリングして、大気中の微粒子を測定するpm2.5フィルターデータ「のみ」を抽出するノードです。さらに、AQIを計算するためにも使用します。
- Pm2pt5_rules - このノードはセンサーデータを解釈するための一連のルールを設定しています。これは、センサーが例えば0~12の間の値を取得した場合、大気質は良好な状態であると判断され、送信されるメッセージは「1」になるというルールです。他方で、13~35の間であれば大気質は中程度であり、送信されるメッセージは「2」というようになります。ここで使われている値はAirNow.govのウェブサイトで計算されたもので、汚染物質(PM2.5など)を入力できるようになっており、入力値がどの大気指数に相当するかを教えてくれます。
- 1,13,36,56,151,252 - これらのボタンはメッセージが正しく送信されているかどうかをテストするものです。それぞれの左側にある丸みのある正方形を押すと、そのボタンに対応するメッセージや数字が送信されます。押すと、クマはそのメッセージを受け取り、それに従って動作するはずです。この場合だと、それぞれ次のAQIレベルを発動させる一番低い数字に対応しています。
例:下図は「1」のもので状態は「Good」となります - Changes - 値の変更がない場合、新しいメッセージの送信をブロックします。これにより、常に同じ数値を何度も送信することが無くなります。
- Msg.payload - デバッグに使用されます。
- Local/pm2pt5 - 先に決定したMQTTメッセージまたは番号を指定したトピックへと送信するノードです。ここでは、クマが取得できるようにコーディングされたトピックになるようにします。
Node-REDを用いてAPIに接続
APIを使うにはまず、どのAPIを使うかを決める必要があります。このプロジェクトでは予測が可能な大気質指数のデータを使用します。そしてもちろん、無料であることが条件です。
アメリカには政府のウェブサイトAirNow.govがあり、APIコールの許容数を超えない限り、無料でAPIをサブスクライブできます(詳細は後述)。APIコールに必要なキーを入手するにはアカウントを作成する必要があります。アカウント作成はこちらから>https://docs.airnowapi.org/
アカウントを作成したら、ウェブサービスに進み「緯度・経度による予報」または自分好みの予報オプションをチェックし、予報を希望する局地や地域情報を入力してください。これでAPIキーが生成され、Node-REDで使用できるようになります。
Node-REDでは(最初にセンサーフローを作成したと仮定して)hamburger menu > Flows > Addで新しいフローを作成する必要があります。
上図は私のプロジェクトにおける2番目の「フロー」であり、ここで使用される各ノードについて以下でお話します。ノードについては先ほどのセンサーデータの取得と同様に、コーディング時には色とアイコンを見て、正しいノードを探してください。各ノードはダブルクリックすることでその設定を変更することができます。
- Timestamp - APIウェブサイトの更新を確認する頻度を設定します。AirNowアカウントでは1時間以内に多くのコールを受けるとブロックされる可能性があるので、あまり頻度を高く設定しない方が良いです。今回は予測オプションを使用するので、60分間隔程度で繰り返すように設定します。
- AirNow - httpリクエストノードです。URLセクションに入力したパーソナルキーを使用してAPIに接続します。
- Function - 関数ノードで、APIのレスポンスであるJSON文字列をチェックします。「Category」、「Number」要素にある大気質指数を直接取得します。後でクマに送信されるのは、この1~6のAQインデックスです。
- Msg.payload - デバッグに使用されます。
-
Regional/aqi - 設定した特定のトピックにMQTTメッセージを送信するノードです。ここでは、クマが取得できるようにコーディングされたトピックになるようにします。
-
1,2,3,4,5,6 - これらのボタンはメッセージが正しく送信されているかどうかをテストするものです。それぞれの左側にある丸みのある正方形を押すと、そのボタンに対応するメッセージや数字が送信されます。押すと、クマはそのメッセージを受け取り、それに従って動作します。
まとめ
これでブリーズベターベアーの動作準備は完了です!長らくお疲れ様でした!!
クマ内部のMicro:bitがWi-FiとESDK内のRaspberry Piに設定した、MQTTブローカーに接続するようにコーディングにより、ESDKのセンサーを読み込んでローカルに大気質指数の状況を指し示したり、無料の大気質指数APIに接続して地域の予報を指し示すことができます。
ここまで、ブリーズベターベアー連載記事をお読みいただきありがとうございました。このプロジェクトであなた自身のプロジェクトに何かインスピレーションを感じていただけたら幸いです。
また、このブリーズベターベアーのプロジェクトを自作しさらに改良して改善点や新しいアイデアを生み出す事が出来たらコメントで皆さんと共有していただけたら幸いです。