
驚愕の使い心地:Node-RED-MCUで自動水やり装置のモックアップを作成してみた
はじめに
前回の記事にて、Raspberry Piを手に入れ、Node-RED、Node-RED-MCUの環境を手に入れたことをご報告しました。
今回は、Node-RED-MCUを使って、昨年作成した自動水やり装置のモックアップが完成しましたので、その経過を報告いたします。驚愕の使い心地の良さです。この気持ちが伝わるのかどうか。
まずは何かをしなければ。。。
もちろん新しい盆栽の装置作りのためのチャレンジではあるのですが、取り掛かりとして何から始めようか迷っていました。
そもそもNode-REDで何ができるのか?
どんなふうに作っていくのか?
全く分からないところからの出発です。
最初の第一歩
実は最初の第一歩って、とても重要だと思うのです。
プログラミング言語であれば、「Hello, world.」を出力するプログラムを作るまで。
電子工作であれば、LEDをチカチカさせる「Lチカ」。
Node-REDの場合は何だろう。。。
が、最初すぐには見つけられませんでした。
Open Creation Lab.さんに教えていただいたのは、
1.injectノードとdebugノードをドラッグして配置し、線で結びます。

2.デプロイボタンを押します。

3.デバッグ(虫のアイコン)ボタンを押します。

4.injectノードの左のボタンを押します。

5.デバッグウインドウに結果が出力されます。

こんな風に動くということがわかりました。
次の一歩は難しいと思っていました。
実際には、いくつかのヤマを越えなければなりませんでしたが、驚くほど簡単にモックアップを完成させることができました。
SALZ mini MQTTを作ってみました。
昨年、ゴリゴリの力技で作りこんだ自動水やり装置SALZ mini 2022をNode-RED-MCUで焼き直してみることにしました。
SALZ mini 2022は、M5StampC3 MateにWateringUnitを接続し、スマホとBLEで通信して、現在の様子を表示したり、ボタンを押して水やりしたりするものです。
これを、Node-RED-MCUで簡単にできる技術を使って、作ってみようと思いました。目的がはっきりしている方が、学習が進むと思ったからです。
対象マイコンはAtomMatrix/Liteに決定
Node-RED-MCUでサポートされているマイコンがある程度決まっています。
その中から今回は、AtomMatrixを選びました。
最終的にはAtomLiteに変えるつもりです。
通信はMQTTを使います。
とにかくこの通信方法を使いたかったのが一番かもしれません。
Open Creation Lab.さんのデモンストレーションが素晴らしかったと思います。
Node-REDがもともとIoTのための通信方法MQTTをより見える化するためのツールとして生まれたこともあると思います。
MQTT brokerは「パレットの管理」から「node-red-contrib-aedes」を追加し、置くだけで使えます。

フローを超えて機能するので、今までBLEで苦労した部分を一足飛びで実装することができてしまいました。
コントローラ部のUIは
こちらもNode-REDの特徴だと思います。dashboard機能を使うことで、とても簡単に実装することができます。
昨年、Google Pixel Watchのアプリを作るために約半年かけてKotlin、AndroidStudio、AndroidOSを勉強し、ようやく基本的なアプリが作れるようになりました。
それと比べると、学習コストが驚安です。
私はこちらを見て勉強をしました。
ダッシュボードの概要と基本操作
ia-cloud/Node-RED スクール
とても分かりやすかったです。
1.「パレットの管理」で「Node-RED dashboard」を追加します。
2.「ダッシュボード」の「配置」で「タブ」と「リンク」を追加します。

3.「button」を追加し、プロパティをセットする。

4.デプロイします。

5.ダッシュボードタブの「ボタン」を押します。

6.ブラウザの別ウインドウが開き、UIの完成です。

道具がそろってきましたので、実際に組んでみたいと思います。


dashboardのコントロールを並べただけです。あまりに簡単で涙が出そうになります。kintoneのCMと同じような感じです。
その後、少し紆余曲折があり、シンプルに考えた結果がこちらです。


今までの苦労があったからできるのか。苦労を知らなくてもできるのかは分かりません。でも簡単なことは間違いありません。
動作の様子を動画にしてみました。
10秒ごとにランダムに水分量が変わります。30より小さいとポンプの状態が0から1へ変化します。
SALZminiMQTTを組んでみる
今度は本体側にチャレンジしてみます。
どこから手を付けてよいのか全く分からなかったので、コメントをちりばめるところから始めました。

MQTTでコマンドを受け、今すぐ水やりしたり、値をセットしたりします。


MQTTで受けたメッセージをとにかくswitchしなければ。。。と思っていました。
従来の手続き型のプログラムのフレームワークにとらわれています。
メッセージの中から、ほしい情報を取り出すために文字列操作を駆使しなければならないかも。。。できるかな。
一晩寝てひらめきました。
msg.payloadをリレーするフローを考えていけばよい。
ひとつのヤマ場でした。
従来の手続き型のプログラムを考えるとき、「START」→「END」のフローチャートを考えます。
「START」、「END」は一つで、そこからさまざまな条件分岐があり、処理を書いていきます。
でもそんなことを考える必要はありませんでした。
イベント駆動型のプログラムを考えるときと同じで、どんなイベントがやってきて、どのように処理するかを考えればよい。
ということに気づいたのです。

MQTTのトピックを細かく分け、今すぐ水やりだったら「SALZMQTT/WN」とすることにしました。
そのメッセージを受け取ってからの処理をとにかく書いていく。
とてもシンプルになりました。
WateringUnitとの接続テストはまだ行っていません。
ですがSALZmini2022での経験から、水分計からの値の取得はanalog入力を使い、ポンプのON/OFFはdigital出力を使えばできることを知っています。
プログラムであれば、
digitalWrite(PIN_NO, 1);
delay(10000);
digitalWrite(PIN_NO, 0);
となりますでしょうか。
Node-REDでは、

こんな感じになると思います。
同時にメッセージをばらまきながら、その一つにdelayをかけて、遅れてメッセージが流れるようにしています。
わかってしまえば、とても斬新で痛快な処理です。
一番肝心な水分計まわりの実装は?
まず、水分計からのデータ取得は

としています。

モックアップなので、randomを用いて、analog値を返してくるようにしています。
1024だったか、4096だったか怪しいのですが、実際に接続テストをしてからでも調整できるので後回しにします。
本番では、上のノードにつなぎぎ変える予定です。
もう少し、前後を見てみます。

injectノードで10秒ごとにメッセージを流しています。
水分計からの数値は0-1024のような値が返ってきますので、これをパーセントに変換する必要があります。
SALZmini2022ではさらにセンサの校正も行っていました。水につけた状態のanalog値と外に出したときのanalog値を元に
パーセンテージを求めます。
値の変換だけでよいのであれば、rangeノードが使用できそうです。
まだrangeノードを知らないときに悩んでいたので、別の方法を採用しました。
ChatGPTに聞いてみた
最近は何でもChatGPTに聞いて試しています。

うわ、かしこ。
行けますね。
試してみたら、結果の桁数が多かったので、四捨五入してもらいました。

これぐらいのコードのひな型があれば、JavaScript音痴の私でもなんとかなります。
そして、その後の処理です。
0-100へ変換された値をMQTT、デバッグ文字列、「乾いているか?」に流します。

この「乾いているか?」をswitchノードで作成しました。

変数flow.WLには水やりレベルの数値が入っています。
どれぐらいの乾きをしきい値にするかは設定できるようにしています。
そして、結果が1だったら、10秒間ポンプを作動させるために、メッセージを流します。
こうしてSALZminiMQTTができました。

LEDのテストはNode-RED-MCUでチェックし、おおよそのフローや連携については、Node-REDでチェックできます。
これで、モックアップの作成は完了してしまいました。
さいごに
思い返せば、昨年の今頃はKotlinを相手に格闘していました。そして今年はNode-REDです。
モックアップを作り終えた今、とても爽快な気分です。
初めて自転車に乗れた時の感じに似ています。
何度もコケながらコツを掴んで自在に走り出せたあの瞬間の喜びです。
今まで様々なプログラミング言語にチャレンジしてきましたが、今回Node-REDに挑戦して、また新たな視野を持つことができました。
メッセージフローを考える。
ここを掴めば、おおよそ何とかなるような気がしてきました。
最後までお付き合いくださり、誠にありがとうございました。
今回作成したフローはこちらにあります。
#RaspberryPi #NodeRED #NodeREDMCU #SALZmini2022 #dashboard #ChatGPT #AtomMatrix #MQTT #IoT #自動水やり装置