Raspberry Pi Zero 2を使ってみる その4(マイコンとのシリアル通信、Node-RED、XIAO ESP32C3)
はじめに
今回はRaspberry Pi Zero 2とXIAO ESP32C3で、シリアル通信をしてみました。
以前Node-RED MCUのSerialノードを開発していたときは、USB変換機でRaspberry Pi 400とESP32のシリアル通信を行っていました。今回はUSB変換機を使わずに、Raspberry Piのピンでシリアル通信を行っています。
さらにNode-REDで受信したコマンドをもとに処理を分岐してみました。
▼以前の記事はこちら
Raspberry Pi側の設定
Node-REDでシリアル通信を行うためのノードがインストールされていない場合は、パレットの管理から追加しておきます。
▼node-red-node-serialportを追加しました。
事前にシリアル通信を有効化していない場合はどうなるのか確認してみたのですが、ピンで通信するときのポートが表示されていませんでした。
▼serial inノードのシリアルポートの欄を確認してみました。
▼/dev/ttyAMA0が表示されていますが、この後通信できるポートではありませんでした。
sudo raspi-configを実行して、シリアル通信を有効化しておきます。SSHで接続して設定しました。
▼System Options→Serial Portを選択します。
▼シリアル通信でのシェルのログインはNo、ハードウェアのシリアルポートはYesを選択しました。
▼設定されました。
▼その後、再起動するか聞かれたので再起動しました。
再起動後マイコンと接続して確認すると、表示されるポートが増えていました。
▼/dev/ttyS0が表示されていました。
▼ボーレートはマイコン側と同じく、115200にしました。
serial in/outノードで通信できるのかを確認するため、フローを作成しました。
▼ポートは表示されていたものが試せるようにしておきました。
マイコン側の設定
▼マイコンはXIAO ESP32C3を利用しました。小型で低価格であり、愛用しています。
マイコン側はRaspberry Piほど複雑な設定は無く、プログラムを書き込むだけです。書き込めないときは、ブートボタンを押しながらリセットボタンを押して、書き込みモードにしてから書き込んでください。
▼プログラムはこちら。ChatGPTに相談しました。
void setup() {
// Windows PCと通信するためのデフォルトUART(USB経由)
Serial.begin(115200);
Serial.println("ESP32シリアルモニタ初期化完了");
// Raspberry Piと通信するためのUART1
Serial1.begin(115200, SERIAL_8N1, 8, 9); // RX,TX
Serial.println("UART1初期化完了");
}
void loop() {
// Windows PCからのデータをRaspberry Piに送信
if (Serial.available() > 0) {
String dataFromPC = Serial.readStringUntil('\n');
Serial.println("PCから受信: " + dataFromPC); // デバッグ用
Serial1.println(dataFromPC); // Raspberry Piに送信
}
// Raspberry PiからのデータをWindows PCに送信
if (Serial1.available() > 0) {
String dataFromPi = Serial1.readStringUntil('\n');
Serial.println("Raspberry Piから受信: " + dataFromPi); // デバッグ用
}
delay(100); // 安定動作のための短い遅延
}
最初はマイコンのTX、RXピンを利用してシリアル通信をしようとしていたのですが、プログラムを書き込むPCでデバッグをしたかったので別のポートを利用するようにしました。
PCとマイコンの通信はSerial、Raspberry Piとマイコンの通信はSerial1を利用しています。
シリアル通信を試してみる
マイコンのD8がRX、D9がTXになっています。Raspberry PiのTXにD8、RXにD9を接続しました。電源は5VとGNDを共有しています。
▼Raspberry Piのピン配置はこちら
▼XIAO ESP32C3のピン配置はSwitch Scienceの販売ページにもありました。
▼以下のように配線しました。
プログラムを書き込んだPCのシリアルモニタで、文字の送受信を行いました。
▼Arduino IDEの右上にシリアルモニタのボタンがあります。
実際に通信してみました。
▼シリアルモニタで文字の送受信ができました!
▼Node-REDでも送受信することができました。
1文字のコマンドを送信する
PCから1文字のコマンドを送信して、Raspberry Piで分岐するようにしてみました。
▼フローはこちら
▼switchノードで、A~Dを受信した場合とそうでない場合で分岐しています。
先程受信したデータを見ると、改行が入っているのが分かります。シリアルモニタで送信するときは改行文字を指定できるのですが、変更して送信してみました。
▼4種類あります。
▼それぞれ送信してみました。
▼改行の入り方が異なっています。
送信するコマンドは1文字だけなので、stringの0番目にアクセスしてみました。
▼changeノードを追加しています。
▼msg.payload[0]をmsg.payloadに代入するようにしています。
実際に通信してみました。
▼コマンドによって処理を分岐させることができました!文字ごとにdebugノードの番号が異なっています。
最後に
Node-RED側で受信したデータをもとに処理するときのデータ形式を気にしていたのですが、改行文字だけ気を付ける必要がありそうです。
今回のやり方だとコマンドは1文字だけですが、1文字あればいろいろ分岐できそうです。本当はchangeノードで改行文字を置き換えたかったのですが、デバッグノードに表示されていないので1文字目だけ取得するのが分かりやすいかな?と思います。
2文字以上の文字列を扱うのであれば、functionノードにJavaScriptのコードを書いて扱うほうが簡単になりそうです。