RaspberryPi Zero WとRaspberryPi Picoを、GPIOでシリアル通信(UART)させました。
簡単だろうと思っていたら、ジャストな情報源がなくて、意外と時間がかかりました。終わってみれば、簡単なんですが。どっちもPythonを使いました(PicoはMicroPython)。
<目次>
・RaspberryPi Zeroの設定
・RaspberryPi Zeroの設定の確認
・GPIO配線
・PicoからZeroにテキスト送信
・ZeroからPicoにテキスト送信
■ RaspberryPi Zeroの設定
シリアルポートはデフォルトでは無効になっているので、設定で有効にする必要があります。
設定には、Serial ConsoleとSerial Portとありますが、Serial Consoleは無効にして、Serial Portを有効にします。
ちなみにSerial Consoleはシリアル通信でラズパイを操作(ログインシェルにアクセス)するための機能です。
SSHでの設定の仕方は、
$ sudo raspi-config
→「3 Interface Options」を選択
→「P6 Serial Port」を選択
→「Would you lik alogin shell to be accessible over serial?」には、”いいえ”を選択
→「Would you like the serial port hardware to be enabled?」には、”はい”を選択
→再起動
シリアル通信を行うためのデバイス・規格のことをUARTと呼ぶのですが、ラズパイには2種類のUARTがあって、PL011とmini UARTとがあります(よくわかってませんが)。Zeroは2つのUARTがあって(ラズパイ4は6つ)、UART0がPL011、UART1がmini UARTとの事です。
そんでもって、プライマリUARTとセカンダリUARTという概念があって、BluetoothもUART0(PL011)を使うので、Bluetoothとシリアルポートとシリアルコンソールの3つの設定如何で、このプライマリ、セカンダリが入れ替わります。この辺がややこしい。
Raspberry Piのシリアルポート設定(UART)を理解する
https://toki-blog.com/pi-serial/
今回はPL011でもmini UARTでもどっちでもいいやって感じでBluetoothを無効にしてません。多分mini UARTを使ってます。PL011を使いたい場合は、Bluetoothを無効にする必要があると思われます。
ちなみにBluetooth無効の方法は、/boot/config.txt をnano等で開いて、次の一行を書き加え保存、再起動します
dtoverlay=pi3-disable-bt
■ RaspberryPi Zeroの設定の確認
Picoに接続する前にZeroの設定がちゃんとできているか確認したい場合は、Zeroの8番ピンと10番ピンを直結して、送ったデータがそのまま受信できるか確かめます。これをループバックテストというそうです。
Raspberry PiのGPIOを使ってシリアル通信する方法
上記サイトで紹介されているループバックスクリプトをそのまま走らせると、プライマリUARTとPL011を確認します。
接続先のデバイス名については、後述しますが、今回はプライマリUART(/dev/serial0)でmini UART(/dev/ttyS0)を使いますので、今回の設定では、プライマリUARTは成功しますが、PL011(/dev/ttyAMA0)は失敗します。
(それでもOK)
■ GPIO配線
以下の配線をします。
・Zeroの8番ピン(GP14)を、Picoの7番ピン(GP5)に
・Zeroの10番ピン(GP15)を、Picoの6番ピン(GP4)に
・Zeroの14番ピン(GND)を、Picoの8番ピン(GND)に
最後のはどのGNDでもOKですし、電源を共有していたら不要です。
■ PicoからZeroにテキスト送信
Picoの送信スクリプト
import utime from machine import UART, Pin uart1 = UART(1, 115200, tx=Pin(4), rx=Pin(5)) while True: uart1.write(b'Hello Zero! Im Pico.') utime.sleep(1)
Zeroの受信スクリプト
import serial ser = serial.Serial('/dev/serial0', 115200, timeout=2) a = ser.read(1) while ser.in_waiting: a += ser.read(1) print(a.decode('utf-8')) ser.close()
データはバイト型で送るので、エンコード・デコードが要ります。
b””や文字列.encode('utf-8')
でバイト型に変換しますが、しなくても送信時は自動で変換してくれるようです。
シリアル通信する時に第一引数にデバイス名を指定しますが、他のサイトのサンプルコードでは、「/dev/ttyAMA0」とか「/dev/ttyS0」とかだったりします。「/dev/ttyAMA0」はPL011(UART0)のことで、「/dev/ttyS0」はmini UART(UART1)のことです。
「/dev/serial0」と「/dev/serial1」は、リンクで「/dev/ttyAMA0」と「/dev/ttyS0」のどちらかを指しており、設定によって変わります。
「/dev/serial0」はプライマリUART、「/dev/serial1」はセカンダリURATです。
多分、上記サンプルは「/dev/ttyS0」でも動く、はず。
■ ZeroからPicoにテキスト送信
Picoの受信スクリプト
import utime from machine import UART, Pin uart1 = UART(1, 115200, tx=Pin(4), rx=Pin(5)) while True: rxData = bytes() while uart1.any() > 0: rxData += uart1.read(1) if len(rxData) > 0: print(rxData.decode('utf-8')) utime.sleep(1)
Zeroの送信スクリプト
import serial ser = serial.Serial('/dev/serial0', 115200) ser.write(b'Hello Pico! Im Zero.') ser.close()