RaspberryPi ZeroとPicoのシリアル通信

RaspberryPi Zero WとRaspberryPi Picoを、GPIOでシリアル通信させました。

簡単だろうと思っていたら、exactlyな情報源がなくて、意外と時間がかかりました。終わってみれば、簡単なんですが。どっちもPythonを使いました。

 

<目次>
・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()

 

データはバイト型で送るので、エンコード・デコードが要ります。
文字列変数.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()

コメントを残す

メールアドレスが公開されることはありません。