ESP32 で Node-RED flow を動かすのを試してみた

ESP32上でNode-REDで作ったフローが動く！という話を聞いて、UbuntuとESP32 DevKitを使って試してみました。これに使用した、[Node-RED MCU Editionについてはここ](https://github.com/phoddie/node-red-mcu/blob/main/readme.md)をご覧ください。

今回、Lチカ、センサ駆動、クラウド連動を試してみましたが、ここではまず環境構築とLチカをやってみた流れまでを紹介します。センサ駆動やクラウド連動についても、また改めて記事にできればと思います。

#### ソフトウェア環境
Ubuntu: 22.04
Nodejs： 18.12.1
Node-RED: 3.0.2

#### ハードウェア
ESP32-WROOM-32D (DevKitボード)
SHT31 (気温・湿度センサ)
VL6180（照度・近接センサ）
BMP280（ 気温・気圧センサ）
その他：ブレッドボード、LED、タクトSW、抵抗、など

#### こんなことができました。

**1.　Lチカ**
injectノードとRaspberry Pi用のGPIOノードでフローを組みました。
点滅を続ける赤LEDと、ボタンを押したら点灯する青LEDの２つを動かしています。
こういう独立した２つの動きをするものを組むのはちょっと面倒な事が多いですが、Node-REDフローだとシンプルに組むことができますね。
<table>
  <thead>
    <tr>
      <th>Node-RED flow</th> <th>ハードウェアの動作</th>
    </tr>
  </thead>
  <tr>
    <td> <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/a8b29a64-f43f-0633-f297-abc1e16e2a4e.png"> 
    </td>
    <td><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/a63f9a2f-9d39-ab78-170a-a63a543a3b09.gif">
    </td>
  </tr>
</table>

**2. センサ駆動**
node-red-mcuに含まれている、ECMA-419 embedded systems API specification に準拠するsensorノードと、それに対応したドライバを使用しました。
<table>
  <thead>
    <tr>
      <th>Node-RED flow</th> <th>ハードウェアの動作</th>
    </tr>
  </thead>
  <tr>
    <td> <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/a1eb396f-6d38-326f-bddf-a42521dfa47e.png"> 
    </td>
    <td><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/f48142ff-6dee-5aeb-b164-000147fea695.gif">
    </td>
  </tr>
</table>

Moddable SDKのランタイムデバッガxsbugで、センサを接続したdebugノードの出力を見ることができます。
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/25651640-98f6-c460-87d4-1bdbd4082887.png"> 


**3. クラウドサーバ連動**
MQTTノードを使ってクラウドサーバ上のNode-REDと通信しました。
クラウド側のRECボタンでボード上の赤LEDを点灯してセンサデータ送出を開始します。
今回は簡易的にやっているのでリセットかけたりすると状態がずれますが、テスト用なので良しとしておきます。
<table>
  <thead>
    <tr>
      <th>Node-RED flow</th> <th>ハードウェアの動作</th>
    </tr>
  </thead>
  <tr>
    <td> <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/fbf33809-2f25-ce46-1e8b-d3de50c41331.png"> 
    </td>
    <td><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/9dfef87d-cded-4195-1f8b-fee03ac93e33.gif">
    </td>
  </tr>
</table>

クラウドサーバ側のdashboardではこんな感じになりました。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/270677f7-adb0-6938-1e5e-c6e83d160555.jpeg">


#### 使用したソフトウェアと、参考にした記事（感謝）

https://github.com/Moddable-OpenSource/moddable

・Moddable SDK
Javascriptを使ってIoTデバイスを開発することを主なターゲットにしたSDKです。
ESP32やESP8266などの小さなMCU(Micro Controller Unit)で動作する軽量なソフトウェアを、ランタイムデバッガを使って開発できます。Javascriptでセンサのドライバを開発するときなどはこのデバッガが便利です。

https://github.com/phoddie/node-red-mcu

・node-red-mcu
コンピューター上で作成したNode-REDのフローを基にModdable SDK を使ってMCU上で動作する軽量なノードに置き換えて実行可能な状態にします。（このモジュールは次のnode-red-mcu-pluginをインストールすると一緒にインストールされます。sensorノードやドライバを登録するファイルもこの中に含まれています。）

https://github.com/ralphwetzel/node-red-mcu-plugin

・node-red-mcu-plugin
上記の仕組みをコンピュータ上のNode-REDのサイドパネルから利用できるようにしたNode-REDプラグインです。Node-RED フローをデプロイしてBuildボタンを押すと、コンパイルからMCUへの書き込みまでの一連の作業をやってくれます。

また、Qiitaの次の記事を参考にさせて頂きました。

https://qiita.com/kitazaki/items/15cba2f4622bf3682083

https://qiita.com/kitazaki/items/da3a2e4a16b8a971b840

#### 手順
次の手順で進めて行きます。
1. Node-REDのインストール確認とRaspberry Pi GPIOノードのインストール
2. Moddable SDKをインストール
3. ハードウェアごとの追加SDKをインストール
4. node-red-mcu-pluginをインストール
    （これをインストールすることでnode-red-mcuもインストールされます。）
5. ~~sensorノード~~ mcuノードをインストール
~~（step 4で一緒にインストールしたnode-red-mcuに含まれています。）~~
6. ~~使用するセンサのドライバをインストール~~(更新により不要となりました) 
7. Node-REDでフローを作成する
8. node-red-mcu-plugin を使用してビルドする

#### 1. Node-REDのインストール確認とRaspberry Pi GPIOノードのインストール
Node-REDのインストールをしていなければ、先にインストールしておきます。~~node-red-mcuでは今のところGPIOの操作にRaspberry Pi用のノードを使っていますので、これもインストールしておきます。~~ 
以前はRaspberry Pi用のノードでGPIOを操作していましたが、現在はnode-red-mcuにGPIOやPWMを扱うノードが含まれています。

UbuntuやRaspberry Piで新規インストールする場合、[Node-RED User Groupのインストールスクリプト](https://nodered.jp/docs/getting-started/raspberrypi)を使用すれば、インストール中の質問に答えてRaspberry Piノードのインストールも同時にできます。すでにNode-REDをインストールしてある場合は、パレットの管理からnode-red-node-pi-gpioをインストールします。
#### 2. Moddable SDK　インストール
[Moddable SDK – Getting Started](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/Moddable%20SDK%20-%20Getting%20Started.md) のガイドに従ってModdable SDKの本体をインストールします。
#### 3. ハードウェアごとの追加SDK　インストール
ターゲットとするハードウェアごとにメーカーが用意している追加のSDKをインストールします。
必要な手順は[moddableのこちら](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/Moddable%20SDK%20-%20Getting%20Started.md#whats-next-building-and-running-apps-on-development-boards-and-mcus)に掲載されています。
今回はESP32を使用しますので、[ESP32用の環境](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/devices/esp32.md)をインストールしました。
#### 4. node-red-mcu-plugin　インストール
Node-REDのフローエディタを開いたときに右側のサイドパネルに表示されるプラグインをインストールします。
旧：
```
cd ~/.node-red
npm install https://github.com/ralphwetzel/node-red-mcu-plugin
```
新:
```
cd ~/.node-red
npm install @ralphwetzel/node-red-mcu-plugin
```
#### 5. ~~sensorノード~~ mcuノード　インストール
step4でプラグインをインストールすると内部にnode-red-mcuが含まれていますので、それを使用して~~sensorノード~~ mcuノード をインストールします。
旧：
```
cd ~/.node-red
npm install ~/.node-red/node_modules/@ralphwetzel/node-red-mcu-plugin/node-red-mcu/nodes/sensor
```
新:
```
cd ~/.node-red
npm install @moddable-node-red/mcu
```
#### 6. ~~使用するセンサのドライバをインストール~~ (更新により不要となりました) 
~~node-red-mcuの中の、manifest_runtime.jsonを編集して使用するセンサのドライバを追加します。ドライバのコードはmoddable SDKに含まれていますので、そのドライバのmanifest.jsonをmanifest_runtime.jsonに登録する感じです。moddable SDKを更新すれば、センサのサポートが追加や更新されているかもしれません。~~
```
nano ~/.node-red/node_modules/@ralphwetzel/node-red-mcu-plugin/node-red-mcu/manifest_runtime.json
```
 ~~"include"の中に、今回使用した３つのセンサのmanifest.jsonを追加します。~~
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/cf487953-5d99-bb48-fcac-7d4def24d539.png">
```
"$(MODDABLE)/modules/drivers/sensors/bmp280/manifest.json",
"$(MODDABLE)/modules/drivers/sensors/sht3x/manifest.json",
"$(MODDABLE)/modules/drivers/sensors/vl6180/manifest.json",
```
以上で準備は完了です。
#### 7.　Node-REDでフローを作成する
Node-REDのフローエディタを開くと、右側のサイドパネルに「MCU」タブが追加されています。左側のパレットにはMCUにsensorノード、Raspberry PiにGPIOのノードがあります。これらを使用してフローを作成します。
![noderedscreen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/25394d0c-89ac-5d19-6530-f85892ae7add.png)
参考に、Lチカ(blink)のflowは以下のとおりです。
```
[{"id":"e75645bd8805533a","type":"inject","z":"5519d7142b1c86c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","_mcu":{"mcu":true},"x":170,"y":180,"wires":[["bb02f711a993bdf7"]]},{"id":"bb02f711a993bdf7","type":"trigger","z":"5519d7142b1c86c8","name":"","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"500","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"_mcu":{"mcu":true},"x":340,"y":180,"wires":[["fcb8dba9f6f02caa"]]},{"id":"fcb8dba9f6f02caa","type":"rpi-gpio out","z":"5519d7142b1c86c8","name":"GPIO 27 out","pin":"27","set":true,"level":"1","freq":"","out":"out","bcm":true,"_mcu":{"mcu":true},"x":550,"y":180,"wires":[]},{"id":"0aa1d8a644a96fc9","type":"rpi-gpio in","z":"5519d7142b1c86c8","name":"GPIO 22 in","pin":"22","intype":"up","debounce":"25","read":true,"bcm":true,"_mcu":{"mcu":true},"x":320,"y":120,"wires":[["3d9e0d466b752596"]]},{"id":"3d9e0d466b752596","type":"rpi-gpio out","z":"5519d7142b1c86c8","name":"GPIO 26 out","pin":"26","set":"","level":"0","freq":"","out":"out","bcm":true,"_mcu":{"mcu":true},"x":550,"y":120,"wires":[]}]
```
#### 8.　node-red-mcu-plugin を使用してビルドする
プラグインを使用すると、ターゲットデバイスを設定し、対象のフローをnode-red-mcuに渡し、ビルドオプションを設定してビルド後にターゲットデバイスへの転送、といった一連の操作を簡単に行ってくれます。詳しくは[node-red-mcu-pluginの解説](https://github.com/ralphwetzel/node-red-mcu-plugin/blob/main/README.md)をご覧ください。

・Node-REDのフローをタブで分けている場合は、プラグインでビルドする対象をチェックボックスで選択することができます。チェックボックスを切り替えた場合は改めてデプロイが必要です。
・「+Add Config」のボタンを押して、設定を追加します。
・ターゲットのハードウェアを選択します。今回はESP32のグループからesp32/nodemcuを選択します。
・USBポートにESP32を接続し、シリアルポートを選択します。
・これで[Build...]ボタンを押すと、ビルドが開始されます。Console Monitorから様子を見ることができます。
![pic_consoleMon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/0e6115b4-35aa-23a3-aad8-dc3177102da0.png)
・ビルド中にModdable SDKのランタイムデバッガ、xsbug が起動します。
　ビルドが完了すればdebugノードの内容やGPIOポートの状態が変化すれば表示してくれます。もしビルド中に起動しない場合は、ターミナルからxsbugと叩いて起動しておきます。
#### 動作確認
・ビルドが完了して転送が終了するとハードウェアがイニシャライズされて動作がスタートします。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/a63f9a2f-9d39-ab78-170a-a63a543a3b09.gif">
このように小さなデバイスでNode-REDというグラフィカルなプログラミングができるローコードツールが使えるのは面白いですね。ローコードと言ってもmessage drivenで、しかもcooperative multi-taskingで動作するのはセンサの値を扱うような用途にはちょうど適していると思います。これもModdable SDKのJavascriptが小さなMCUでの製品開発に向けた開発ツールとして非常に軽量で効率の良い動作ができることが大きな理由かと思います。今後もいろいろと試してみたいと思います。