MicroPython的午睡(21) ラズパイPico、M5AtomLiteとUART通信

Joseph Halfmoon

今回はハードウエアの周辺機能の利用に戻りたいと思います。毎度毎度「お世話になっている」のに取り上げてこなかったUART(調歩同期方式シリアル通信)であります。当然、通信する相手なければ使ってみることができませぬ。そこで今回用意いたしましたのは、M5Stack社の超小型デバイスATOM Liteであります。Raspberry Pi Picoに比べても小さいです。機能的には相互補完的?

※「MicroPython的午睡」投稿順 Indexはこちら

(末尾にラズパイPicoのMicroPythonコードと、ATOM Liteのスケッチ( .ino) cppコードを掲げました。)

最近のほとんどのマイコンボードは、開発用のUSBコネクタを備えています。そしてこのUSB接続を利用して、マイコンと開発ホストとの間でUART(Universal Asynchronous Receiver Transmitter)によるシリアル接続をサポートしているものがほとんどだと思います。

Raspberry Pi Picoでもその仕組みは同様で、UARTの一つはUSB経由でも通信できるようになっています。MicroPythonでは、毎度お世話になっている REPL(Read-Eval-Print Loop)はそのUART0を利用するようになっています。MicroPythonスクリプトの中でのprint()などの出力の行き先も同じです。Raspberry Pi Pico Python SDK から該当箇所を引用させていただきます。

USB serial is available from MicroPython, but the REPL is also available over UART0 by default.

ラズパイPicoとATOM Liteの結線

ま、しかし、ラズパイPicoは、UARTを2チャンネル搭載しているので、UART1の方は手付かずで使用出来るはずです。今回はこちらを使用してみました。端子のアサインは

  • UART1_TX GP4
  • UART1_RX GP5

です。一方、対向機となる M5Stack ATOM Liteの方も同様な理由で Serial2 という名で呼び出せるUARTを以下の端子にアサインしました。

  • TX G21
  • RX G25

ATOM Liteについて詳しくは、以下の記事をご覧ください。

鳥なき里のマイコン屋(118) M5ATOM Lite、UART、I2C接続

2台をUART接続したときの結線は以下のとおりです。

Pico_Uart1_DUTATOM Liteを接続相手に選んだのは、この2台、相互補完的だな、と勝手に思ったためであります。ラズパイPicoは端子数もそこそこ多く、インタフェースIPやPIO(プログラマブルIO)など周辺接続機能も強力です。しかし、ネットワークへの接続機能は今のところオンボード上にはありません(そのうち搭載?)それに対して、小さなATOM LiteはWiFi、BLEが使えます。しかし、上の回路図の通りで端子数は少ないです。この2台を接続すればネットワーク機能あり、かつ、合計3個のCPUをユーザープログラムで外界とのインタフェースに使用可能なシステムの出来上がり、と。ま、UART接続の確認はその第一歩ですかね。

MicroPythonでのUART接続

標準的なMicroPythonでのUART制御は以下のドキュメントが参考になるじゃないかと思います。ただしラズパイPicoのMicroPythonは以下に書かれている情報の「サブセット」的な実装であるようです。全部のメソッドがあるわけでないので、例によってREPLからhelp()を使って、実装されているメソッドを確認しながら記述するのが良さそうです。

クラス UART — 二重シリアル通信バス

今回はとりあえずラズパイPicoとATOM Liteの間で双方向にUART通信ができる、という確認だけなので以下のようなプログラムになっています。

  1. ボーレート115200、8ビット、ストップ1ビット
  2. ハードウエア的には全二重だけれど、ソフト的には半二重的に送受信制御
  3. ラズパイPicoから “ABC改行” とUART1経由で送信(改行はnew lineキャラクタ)
  4. ATOM LiteはSerial2から受信した文字列をそのまま自身のUSBシリアルに送る(パソコン上の仮想端末に表示される)
  5. ATOM Liteは”OK改行”とSerail2経由で送信
  6. ラズパイPicoは、上記をUART1から受信すると自分のUSBシリアルに送る(Python IDEのREPL端末に表示される)
  7. 3へ戻って同じことの繰り返し

2台の間を接続するUARTに加えて、双方結果のモニタ用にUSBシリアルも使っているので、合計4個のUART(PC側のUARTまで数えれば6個)がここで動いていることになります。

まず、動作時のATOM Liteの仮想端末画面です。Arduino IDEでコードを書いたのでArduinoロゴの輝く「シリアルモニタ」画面のキャプチャです。ATOM Liteは “ABC”を延々と受信しつづけていることが確認できます。

M5ATOM_Serial次に、ラズパイPico側です。Thonny IDEをつかってMicroPythonのコードをラズパイPicoに送り込んでいるので、そのキャプチャです。下の Shell というタブがREPLのための仮想端末相当部分で、そこに Bytes型文字列で ATOM Liteから返信されてきた ”OK改行” が延々と表示されています。

Pico_Uart1以上のように、意図した双方向のUART通信がラズパイPicoとATOM Liteの間で行えていることが確認できました。この「ルート」を使ってラズパイPicoから ATOM Liteを経由し、ネットワークに出ていくのはまた後で。

MicroPython的午睡(20) ラズパイPico、PIO操作は最大8ビット? へ戻る

MicroPython的午睡(22) ラズパイPico、AQM1602 LCDパネル接続 へ進む

ラズパイPico上のMicroPythonによるUARTテストプログラム
from machine import Pin, Timer, UART
import time

uart1 = UART(1, 115200, tx=Pin(4), rx=Pin(5))

buf = b"ABC\n"

for i in range(100):
    uart1.write(buf)
    ret = uart1.readline()
    if ret is not None:
        print(ret)
    time.sleep_ms(500)
M5ATOM Lite上のArduino形式 “スケッチ” cppプログラム
#include "M5Atom.h"
#define TXPIN  (21)
#define RXPIN  (25)

const bool LCDEnable = false;
const bool PowerEnable = false;
const bool SerialEnable = true;

bool ledOn;

void setup() {
  M5.begin(LCDEnable, PowerEnable, SerialEnable);
  Serial.begin(115200); 
  while(!Serial) {};
  Serial.println("1> Start Serial:");
  Serial2.begin(115200, SERIAL_8N1, RXPIN, TXPIN);
  while(!Serial2) {};
  Serial2.println("2> Start Serial2:");
  ledOn = true;
}

void loop() {
  if (ledOn) {
    M5.dis.drawpix(0, 0x100000); //G=0x10
    ledOn = false;
  } else {
    M5.dis.drawpix(0, 0x001000); //R=0x10
    ledOn = true;    
  }
  if (Serial2.available() > 0) {
    String temp = Serial2.readStringUntil('\n');
    Serial.println(temp);
    Serial2.print("OK\n");
  }
  delay(50);
}