トホホな疑問 (27) M5StickC、Uartを使う

Joseph Halfmoon

M5StickCの新製品plusが出たようですが、本投稿はplusの話ではありません。ノーマル版でUARTを使ってみた件。結局使えたのですが、トホホな疑問がいろいろ出てきてしまいました。誰が知っている?どこに書いてある?それって私の手元のデバイス特有の挙動?疑問はつきませぬ。

※「トホホな疑問」投稿順Indexはこちら

M5Stack社のM5StickCは、WiFiとBLEが使えるM5Stack系のデバイスの中では比較的後からでた小型品種であります。無線とLCDパネルが搭載されているのはM5Stackと変わりませんが、小型なだけに拡張性には制限がある上、LCDといっても表示は小さいです。現在では、M5StickCplusという一回り表示が大きくなった新機種も出、一方ATOMの名を冠するLCD無しの品種(小さい癖に拡張端子数がM5StickCより多い)も登場し、ちょっと置いてかれた感もあるのです(個人の感想です。)が、基本は共通するみたいなので(詳しくは確かめてないです)、そいつらに「移行」する前にちょっと復習をしてみました。

過去使用したのは、UIFlowという「ブロック」を積んでWiFi経由でプログラミングする環境ででした(裏でMicroPythonうごいております。)しかし、今回はインストールしてあったUIFlow用の実行環境に上書きする形で ArduinoIDEで作成したオブジェクトコード(ESP32用のgcc処理系でコンパイルされる)を書きこんで確かめています。もしかするとそういう「履歴」が挙動に影響しているのかもしれません。

前置きが長くなりましたが、確かめたかったのはM5StickCと外部のデバイスとのUart通信です。ぶっちゃけ、無線のない外部デバイスがM5StickCと通信できれば、M5StickCはWiFiでネットワークに接続できるので、サーバー上で動いているNode-REDなどと連動させるのが容易、という目論見です。M5StickCは、その一つしかないGroveポートにI2Cの信号がでています。相手がI2CSlaveであれば、I2Cでもよいですが、そうでない相手を想定です。今回使うことができたUARTは、以下の2つです。

    • Serial という名で参照できるUART0、USBポート経由でPCなどとシリアル通信できるもの(ArduinoIDEのシリアルモニタで開けるポート)
    • Serial2という名で参照できるUART2、M5StickC上部のHAT用拡張端子から信号をとりだせるもの(外部デバイス接続するならこちら)

M5StickCに搭載されているESP32-PICO-D4のデータシートにはUartが搭載されている旨の記載がありますが、ペリフェラルについては詳しい記載がなく、ESP32を参照せよと書いてあります。また、PICO-D4の端子機能表を読む限り拡張用の端子にはUARTがアサインされているようにはみえません。ESP32のデータシートをみると3個のUartが搭載されています。そしてESP32のデータシートの4.2 Peripheral Pin Configurationsにはとても?な記述があったのです。ペリフェラル(インタフェース)毎に信号名とそれに結び付けられる端子名が一覧表になっているのですが、UARTの信号には

Any GPIO Pins

と書かれておったのです。Analog関係の信号やEthernetなどの信号名と端子の関係は固定ですが、UARTとかI2Cなどのデジタル的な「信号線の扱いが軽い」ものどもは皆Any GPIO Pinsなのです。普通のマイコンではありえないですが、

もしかして設定さえすればどこでもだせるんじゃね。。。

これが今回の疑問です。もしそうであれば、便利この上ない。拡張性が限られると思っていたM5StickCはとてつもなく拡張性を秘めていたことになります。本当か。。ただ、以下のようなことも想定されました。

    1. これはチップ~モジュールの設計時にAnyなのであって、私らが使うときにはもはやキメウチにコンフィグされている
    2. ハードウエア自体はコンフィグ可能だが、M5StickC用のArduino環境で呼び出されるソフトウエア階層のどこかでキメウチされている

どちらもありそうな話です。やってみるしかありませぬ。幸い、M5StickCで配線を引き出せる端子は以下の5本しかありません。

    • G26、HAT
    • G36、HAT
    • G0、HAT
    • G32、Grove
    • G33、Grove

データシートによると、G36だけは入力専用。他は入出力可能です(G36を入力のRXにしてみましたが駄目でした。)Serial1とSerial2の二つについて適当なピンの組み合わせで動作するものを探してみたところ、動作したのは以下でした(総当たりはしていないので他にも動作する可能性あるかと思います。)結局、全然、Anyではないです。なお、M5StackCのスケマティック(ブロックダイアグラム的な)を見るとG0端子に関しては内蔵I2Sマイクのクロック信号としても使われているようなので、マイクとは両立しませぬ、多分。

#define TXPIN 0
#define RXPIN 26

Serial2.begin(115200, SERIAL_8N1, RXPIN, TXPIN);

そのテストをやっているときの様子がこちら。

M5StickC_DUT

右下に見えるのがポテンショメータで、ついでに行ったアナログ入力のテスト用です。結構時間をつかって分かったことをまとめてておくと

    • USBシリアル以外に使えるUARTはG26(RXD)、G0(TXD)のSerial2
    • analogRead()は0から4095(12ビット)まで読める。10ビットのArduinoUNOより精度良いが、値が異なるので注意。
    • analogWrite()(Arduino環境でのPWM出力関数)は使えない。PWM出力を使うにはESP32のハード固有関数を使う必要があるみたい(未確認)
    • pinModeを出力にすればdigitalWrite()はG26とG0に使える。しかし、同じコードなのにG32とG33については動作しなかった。何が悪い??

使える部分、が多少なりとも明らかになったのでその範囲では確実に使えますです。しかし、返って謎は深まってしまった感じ。トホホ。

(26) Python、WindowsでのShebang行 に戻る

(28) Nucleo、Arduino環境でUartを使う へ進む