M5Stack と 他のマイコン間をシリアル(UART)でつなげて双方向通信ができるようにしました。
以下は Wio LTE JP Version (以下 Wio LTE) と M5Stack Gray (以下 M5Stack) をつなげた様子です。<<Send>>:
で送られたデータが別のウィンドウ側で Recv:
として受信できています。
(クリックすると大きい画像で見られます)
3.3V な UART デバイスであれば通信できるので、Wio LTE だけでなく Raspberry Pi 等の UART ターミナルデバイスとして M5Stack が利用可能となります。
※ここでは Gray か Basic を想定しています。FIRE や Go で同様のことができるのかは、未調査です。
M5Stack の Grove A ポートで SoftwareSerial を使う
M5Stack には側面に 1 つ Grove コネクタ ("Grove A" と呼ばれているようです) があるので、そこにケーブルを挿すだけで他のマイコンと通信できるようにしたというのがゴールです。
ちなみに: M5Stack には HardwareSerial があり、GPIO 16,17 で Serial2 として使うことができますが、これは M5-BUS にピンなどを挿して利用することになるため、ちょっとダサいなあと思っています。
Grove A のピンアサイン
Grove A は GPIO 21 と 22 に割り当たっていて I2C として使えるようにもなっていますが、 DIO としても利用可能ですので SoftwareSerial としても使えます。
EspSoftwareSerial
EspSoftwareSerial は arduino-esp32 プラットフォームで SoftwareSerial が使えるようにするライブラリです。
[スケッチ] > [ライブラリをインクルード] > [ライブラリを管理] から EspSoftwareSerial
を探してインストールできます。
基本のコードは以下の通りです。
#include <M5Stack.h>
#include <SoftwareSerial.h>
SoftwareSerial GroveA(21, 22);
setup () {
M5.begin();
GroveA.begin(57600);
}
あとは GroveA
で write
や read
などのメソッドを使ったシリアルポートプログラミングをしていきます。
サンプルスケッチ
5秒毎に millis()
を UART から送出しつつ、その間に UART で受信したデータを LCD と M5Stack のシリアルモニタ(ややこしいな)へ表示するスケッチです。
※ M5Stack のシリアルモニタは define
で CONSOLE
と名称定義しています(ややこしいから)
#include <M5Stack.h>
#define CONSOLE Serial
#include <SoftwareSerial.h> /* EspSoftwareSerial */
/* rxPin, txPin | https://github.com/plerup/espsoftwareserial/blob/master/src/SoftwareSerial.h#L93 */
SoftwareSerial GroveA(21, 22);
void setup() {
M5.begin();
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(M5.Lcd.color565(255, 255, 255));
CONSOLE.begin(57600); /* ref: https://qiita.com/inouetai/items/a4f8b134be7cc40bc42e */
GroveA.begin(57600); /* ref: https://github.com/plerup/espsoftwareserial/blob/master/src/SoftwareSerial.h#L118 */
delay(5000);
CONSOLE.println("-- HELLO (baud rate = 57600)");
}
void loop() {
M5.Lcd.fillScreen(M5.Lcd.color565(0, 0, 0));
M5.Lcd.setCursor(0, 0);
while (GroveA.available()) {
String recv_str = GroveA.readStringUntil('\n');
CONSOLE.print("Recv: ");
CONSOLE.println(recv_str);
M5.Lcd.print("Recv: ");
M5.Lcd.println(recv_str);
}
unsigned long uptime_ms = millis();
GroveA.println(uptime_ms);
CONSOLE.print("<<Send>>: ");
CONSOLE.println(uptime_ms);
delay(5000);
}
注意点
SoftwareSerial の通信速度は最大で 57600bps にしておくのが良さそう
通信速度は 57600 を最大としておいた方が良さそうです。
115200 だと化けることがありました。おそらく処理が間に合わないことがあるのかもしれません。(74880 は未調査ですがわかりづらいのでパスしました)
スケッチ内では CONSOLE
側も同じ 57600 にしていますが、ここは CONSOLE.begin(115200)
でも問題ありません (開発 PC と M5Stack 間の通信速度であるため)
M5.Power.** が使えなくなります
M5Stack の電源関連の制御は GPIO 21,22 を通じて行われています。そのため SoftwareSerial で GPIO 21,22 を占有してしまうと M5.Power.getBatteryLevel()
などが全般的に使えなくなります。
回避方法は現状見いだせていません。
入力可能な電圧レベルは 3.3V です
M5Stack が使っている ESP32 の GPIO は 3.3V です。 5V トレラントではない ので、信号出力が 3.3V 以外のデバイスと接続する際には電圧レベル変換をしてください。
Wio LTE や Raspberry Pi は 3.3V ですのでそのまま接続が可能です。
Wio LTE とつなげる
Wio LTE JP Version での UART ポート操作 を参考にしています。
こちらは 2秒毎に millis()
を UART から送出しつつ、その間に UART で受信したデータを Wio LTE のシリアルモニタ(ややこしいな)へ表示するスケッチです。
#include <WioLTEforArduino.h>
WioLTE Wio;
#define CONSOLE SerialUSB
#define GroveUART Serial
void setup() {
Wio.Init();
Wio.PowerSupplyGrove(true);
CONSOLE.begin(57600);
GroveUART.begin(57600);
delay(5000);
CONSOLE.println("-- HELLO (baud rate = 57600)");
}
void loop() {
while (GroveUART.available()) {
String recv_str = GroveUART.readStringUntil('\n');
CONSOLE.print("Recv: ");
CONSOLE.println(recv_str);
}
unsigned long uptime_ms = millis();
GroveUART.println(uptime_ms);
CONSOLE.print("<<Send>>: ");
CONSOLE.println(uptime_ms);
delay(2000);
}
M5Stack と Wio LTE を Grove ケーブルでつなげる
M5Stack の Grove A と Wio LTE の Grove UART を Grove ケーブルで接続すると、双方でデータの送受信がされるようになります。これは双方の TX と RX がクロスするように M5Stack 側のスケッチの SoftwareSerial GroveA(21, 22);
で指定しているからです。
注意点: 電源(赤) は結線しないように切断してください!
写真の通り、赤線(電源)を切断した改造を行っています。電源をそれぞれ接続すると最悪壊れますのでご注意を。
Raspberry Pi とつなげる
あとでかく (LGTM をもらったら気合が入るよ!)
あとがき
今後考えられるアップデートは ...
- LCD でスクロールできるようにする (e.g. https://mae8bit.hatenablog.com/entry/2019/11/27/232308)
- M5Stack のボタンに応じてコマンドをマイコン側に送出
-
M5Stack 用 3G 拡張ボード を使って
- 受信データをクラウドに送出
- SORACOM Napter を使ってクラウド側から M5Stack を経由してコマンド文字列をマイコン側へ送出
こんなところでしょうか。どなたか、時間をください。
「お詫び」
M5Stack用3G拡張ボードを使う際、PIN(16,17)を利用するデバイスの対応 で
※ ちなみに arduino-esp32 では SoftwareSerial が利用できません
と偉そうに書いていたのですが "ESP32でSoftwareSerial接続する" に「EspSoftwareSerial が使えるよ」と書いてあるじゃないですか!
良く調べもせずに書いてスミマセンでした、謹んで反省してまーす。
EoT