Node-RED MCUを使ってみる その2(カメラノード、XIAO ESP32S3 Sense)

はじめに

 今回はNode-RED MCU用に開発されたmcu_cameraノードを試してみました。

 Node-RED MCUの書籍の執筆者メンバーであるkitazakiさんが、ひと月ほど前に開発されたノードです。

▼ポストされていました。

▼Qiitaにもまとめられていました。

https://qiita.com/kitazaki/items/011cbd2bc894238a6301

 マイコンとNode-REDで通信して画像を取得できるようになると、さらに他のノードとつなげて使えそうです。

▼YOLOの物体検出と組み合わせたいなと思っています。

YOLOで物体検出 その4(GPUの設定、CUDA 12.6)

はじめに  今回はGPUを利用したYOLOの物体検出を試してみました。  Ultralyticsのドキュメントではオプションで切り替えることができるようでしたが、GPUだとエラーが出…

▼以前の記事はこちら

加速度センサーを使ってみる その2(MPU6050、Node-RED MCU)

はじめに  前回はESP32と加速度センサーのMPU6050を使いました。プログラムはArduino IDEで書き込みましたが、今回はNode-RED MCUで書き込みます。Node-REDで作成したプ…

Node-RED MCUを使ってみる その1(Node-RED、M5Stack)

はじめに  今回はNode-RED MCUを使って、M5Stackにプログラムを書きこんでみました。以前の記事で少し紹介していたのですが、Makerが終わってからはNode-RED MCUばかり使…

▼Node-REDとNode-RED MCUの簡単な紹介はこちら

書籍紹介:『はじめてのNode-RED』/『はじめてのNode-RED MCU Edition』

Node-REDとは  一言でいうと、Node-REDはプログラミングが簡単にできるツールです。ビジュアルプログラミングの一種で、視覚的にわかりやすくなっています。 ▼百聞は一見…

環境を構築する

 Node-RED MCUは予めインストールしておいてください。

▼最近Windows 11で環境を構築しました。

Node-RED MCUの環境を構築する(Moddable SDK 5.4.1、ESP-IDF v5.3.1対応版、Windows 11)

はじめに  今回はNode-RED MCUの環境を構築してみました。  PCを買い替えたので、久々にインストールしました。カメラへの対応も進んでいるようなので、試したいなと思…

 つい最近、Moddable公式からNode-RED MCUの開発者向けにアップデートしたというポストがありました。

▼一週間前です。

 GitHubで見ていると、node-red-mcuのリポジトリが更新されたようでした。そのため、node-red-mcu-pluginを再インストールすることにしました。

▼Node-REDのパレットの管理の画面で、一度削除しました。

▼もう一度インストールしました。

 この後カメラを利用するためにXIAO ESP32S3 Sense用にビルドすると、エラーが起きることがありました。

▼ビルドに失敗していました。

 Macでは実行できるという話をkitazakiさんから聞いていました。

 Node-RED MCUの書籍の執筆者メンバーであるNWLabさんから、Windowsのパスの最大長に関する問題について教えてもらいました。

▼以下のページに、パスの最大長の制限に関して書かれています。

https://learn.microsoft.com/ja-jp/windows/win32/fileio/maximum-file-path-limitation?tabs=registry

 長いパスを有効にするため、Power Shellを管理者権限で起動して以下のコマンドを実行しました。

New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force

▼LongPathsEnabledが1になっています。

 この状態だと、この後のビルドに成功しました。

ノードを追加する

 mcu_cameraノードを追加します。

▼npmのページはこちら

https://www.npmjs.com/package/@kitazaki/node-red-contrib-mcu-camera

▼GitHubのページはこちら

https://github.com/kitazaki/node-red-contrib-mcu-camera#readme

 Node-REDのパレットの管理から、ノードを追加しました。

▼@kitazaki/node-red-contrib-mcu-cameraを追加しました。

▼ノードが追加されました!

撮影してみる

サンプルフローを試してみる

 Node-REDのノードは、ノードの開発に関するドキュメントに準拠していればexamplesフォルダにサンプルフローがあります。

 今回もGitHubにサンプルフローがあったので、まずはそのフローを試してみました。

▼こちらのページにありました。

https://github.com/kitazaki/node-red-contrib-mcu-camera/blob/main/examples/flows.json

▼ノードが追加されました。

 マイコンで撮影した画像を、HTTP通信で送信するようになっています。ビルドしてフローを書き込みます。

▼マイコンはXIAO ESP32S3 Senseを使いました。

▼ビルド対象はesp32/xiao_esp32s3_senseにしています。

 http in/outノードで通信するので、Wi-Fiの設定も行います。Buildの横にあるShow more optionsから設定できます。

▼WiFiのSSIDとパスワードも設定しました。

 ビルドして実行してみました。

▼実行が開始すると、xsbugにIPアドレスが表示されます。

 http://<IPアドレス>/cameraにアクセスすると、カメラの画像が表示されます。

▼撮影できました!ブラウザからアクセスできます。

▼サンプルフローでは画像のサイズが176×144なので小さいです。

▼1280×720に変更してみました。

▼サイズを大きくしても撮影できました!

 なお、動作中はマイコンがかなり熱くなります。Wi-Fiの環境によっては接続が不安定にもなっていました。

マイコンから画像を一定の時間間隔で送信する

 サンプルフローでは、マイコンがブラウザからのHTTPリクエストを受け取ったときに撮影を行っていました。

 逆にマイコン側が一定の時間間隔で撮影を行い、PCに画像を送信するようにしてみました。

▼フローはこちら

[{"id":"04c5ba2d08c7584a","type":"inject","z":"f59b6baa4bc2bd8d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"test","payloadType":"str","x":2510,"y":840,"wires":[["ad7479e8d98ef636"]]},{"id":"ad7479e8d98ef636","type":"debug","z":"f59b6baa4bc2bd8d","name":"debug 1","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2670,"y":840,"wires":[]},{"id":"58a1ec4dc4e83e06","type":"http request","z":"f59b6baa4bc2bd8d","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://172.20.10.5:8000/api/camera","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":2850,"y":900,"wires":[[]]},{"id":"8daab312d588877b","type":"inject","z":"f59b6baa4bc2bd8d","name":"","props":[],"repeat":"5","crontab":"","once":true,"onceDelay":"1","topic":"","x":2510,"y":900,"wires":[["3a28a436e1ab05ce"]]},{"id":"3a28a436e1ab05ce","type":"mcu_camera","z":"f59b6baa4bc2bd8d","name":"","imagetype":"jpeg","width":"176","height":"144","moddable_manifest":{"include":"manifest.json"},"x":2670,"y":900,"wires":[["58a1ec4dc4e83e06"]]}]

▼injectノードで5秒間隔で送信するようにしています。

▼PC側のIPアドレスのURLに送信するようにしています。

 PC側で受信してからファイルに保存するようにしました。

▼フローはこちら

[{"id":"872898ee66e043f8","type":"http in","z":"f59b6baa4bc2bd8d","name":"","url":"/camera","method":"post","upload":true,"swaggerDoc":"","x":2370,"y":600,"wires":[["a7eb1f4de951f444","c446183e39799944"]]},{"id":"6c39d239fd867d0a","type":"http response","z":"f59b6baa4bc2bd8d","name":"","statusCode":"","headers":{},"x":2750,"y":600,"wires":[]},{"id":"8ffb1be549b3e0f2","type":"file","z":"f59b6baa4bc2bd8d","name":"","filename":"filename","filenameType":"msg","appendNewline":false,"createDir":false,"overwriteFile":"false","encoding":"none","x":2720,"y":720,"wires":[[]]},{"id":"2bd0c597aaafaa54","type":"change","z":"f59b6baa4bc2bd8d","name":"","rules":[{"t":"set","p":"filename","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":2770,"y":660,"wires":[["3a58751e1cde2cb0"]]},{"id":"a7eb1f4de951f444","type":"change","z":"f59b6baa4bc2bd8d","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"OK","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2580,"y":600,"wires":[["6c39d239fd867d0a"]]},{"id":"3a58751e1cde2cb0","type":"template","z":"f59b6baa4bc2bd8d","name":"","field":"filename","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{filename}}.jpeg","output":"str","x":2560,"y":720,"wires":[["8ffb1be549b3e0f2"]]},{"id":"c446183e39799944","type":"function","z":"f59b6baa4bc2bd8d","name":"function 13","func":"let data = msg.payload; // JSONの10進数データ\nlet buffer = Buffer.from(Object.values(data)); // 10進数データをバイナリに変換\n\nmsg.payload = buffer;\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2570,"y":660,"wires":[["2bd0c597aaafaa54"]]}]

▼受信したデータを画像ファイルの形式で保存できるように、ChatGPTにfunctionノードのコードを書いてもらいました。

▼ファイル名は時間の数値を利用しています。

▼templateノードで.jpegを付け足しています。

 実際に撮影を行ってみました。

▼大量に保存されています。

▼ちゃんと表示できる形式で保存されていました。

 なお、撮影間隔が短いと処理が追い付かないのか、エラーが起きていました。

▼撮影が1秒間隔だと、途中で以下のエラーが起きました。

最後に

 IoT用途の定点観測とかであれば、簡単に使えると思います。ロボットのようにリアルタイム性が求められる用途では、マイコンのカメラは性能不足のような気がしています。

 2年前に、Node-RED MCUのノードを誰かが作って、ノードが増えるともっと使いやすくなるという記事を書いていました。その後、少しずつノードが増えているようです。

▼こちらの記事でNode-RED MCU用のmcu_servoノードについて書いていました。

https://qiita.com/background/items/9b820251aa9dda5a3167

 なお、カメラノードを複数配置するとエラーが起きるようだったのでご注意ください。

▼camera init failedというエラーが起きます。

追記

 私が修正したコードのPull Requestがマージされたので、複数のノードを置いても実行できるようになりました。ただし、現状では幅と高さが同じでないとエラーが出るのでご注意ください。

▼こちらのPull Requestです。

https://github.com/kitazaki/node-red-contrib-mcu-camera/pull/1

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です