Raspberry Piのシリアルポート設定(UART)を分かりやすく解説します。
Raspberry Piで使用できるUARTにはPL011(16550互換)とmini UARTの2種類があります。mini UARTは機能に制限があるUARTになります。
プライマリUARTは、シリアルコンソールとして使うか、汎用シリアルとして使うかの割り当てが可能です。
また、Raspberry Pi 4ではUART2~UART5の4つのPL011が追加されています。
もくじ
準備
Raspberry PiのすべてのUARTは3.3Vで動作します。そのため、通常のシリアルポートに接続する場合や、5Vのシステムに接続する場合には変換アダプターを使用して接続します。
USB to TTLシリアルケーブル
パソコンと接続するために、USB to TTLシリアルケーブルを用意しました。
adafruit製のUSB to TTL Serial Cable(954)にしました。
理由としては、2016/12/21以降の出荷品については、Prolific PL2303HXチップセットから、SiLabs CP2102チップセットに変わっているようです。ドライバの安定性が向上していて、高速通信も安定しているような事が書いてあったのでこれにしました。115200bpsより早い、921600bpsまで設定ができます。
SiLabs CP2102チップセットのドライバーをダウンロードしてインストールします。
SiLabs CP210xチップセットのドライバーをダウンロードページ
ドライバインストール後に、USB to TTLシリアルケーブルを接続すると次のようにデバイスが認識します。
USB to TTLシリアルケーブルをRaspberry Piに接続
今回はプライマリUARTに接続します。
接続先は、Raspberry PiのGPIOの対応を次の図で確認します。
シリアルケーブルの5V電源は接続しません。
シリアルケーブルのGNDは、Raspberry PiのGNDに接続します。(6番PIN)
シリアルケーブルのRXDは、Raspberry PiのTXD(GPIO14)に接続します。(8番PIN)
シリアルケーブルのTXDは、Raspberry PiのRXD(GPIO15)に接続します。(10番PIN)
引用 : Raspberry Pi公式HP GPIO
GPIOの対応は、Raspberry Piのターミナルにて「pinout」コマンドでも確認できます。
シリアルケーブル | Raspberry Pi GPIO |
赤 : 5V出力 | 未接続 |
黒 : GND | GND(6番PIN) |
白 : RXD | GPIO14 TXD(8番PIN) |
緑 : TXD | GPIO15 RXD(10番PIN) |
パソコン側のターミナルソフト(Tera Term)
ターミナルソフトとしての定番のTera Termをダウンロードしてインストールします。
Raspberry Pi側のターミナルソフト(GtkTerm)
Raspberry Pi側での動作確認用のターミナルソフトとしてGtkTermを使います。
次のコマンドにてインストールします。
$ sudo apt install gtkterm
「スタートメニュー」-「アクセサリ」-「Serial Port terminal」が追加されるので、クリックしてGtkTermを起動します。
Raspberry Piのシリアルポート設定
シリアルポートはデフォルトでは無効になっています。そのため、設定で有効にする必要があります。
シリアルコンソールとして使う
Raspberry Pi 4では、シリアルコンソールとしてmini UARTがプライマリポートとして有効になります。(設定で入れ換えない場合)
GUIで設定する場合
「スタートメニュー」-「設定」-「Raspberry Piの設定」でRaspberry Piの設定プロパティを開きます。
「インターフェイス」タブをクリックして、「シリアルポート」・有効、「シリアルコンソール」・有効に設定して、「OK」をクリックします。
再起動確認画面になるので、「はい」をクリックします。再起動するとシリアルコンソールが有効になります。
パソコンとシリアルを接続しておくと、次のようにlogin画面が表示されます。
シリアルポートの設定は次の設定にします。
- ボーレート ・・・ 115200
- データビット ・・・ 8bit
- パリティ ・・・ none
- ストップビット・・・ 1bit
- フロー制御 ・・・ none
raspi-configで設定する場合
Raspberry Piにてターミナルソフトを起動して、次の「sudo raspi-config」コマンドを実行します。
$ sudo raspi-config
「3 Interface Options」を選択します。
「P6 Serial Port Enable/disable」を選択します。
ログインシェルにシリアル経由でアクセスするか確認になるので、「はい」を選択します。
「了解」を選択します。
メニュー画面に戻るので、「Finish」を選択します。
再起動確認になるので「はい」を選択して、Raspberry Piを再起動します。これでシリアルコンソールが有効になります。
汎用シリアルとして使う
Raspberry Pi 4では、汎用シリアルとしてmini UARTがプライマリポートとして有効になります。(設定で入れ換えない場合)
GUIで設定する場合
「スタートメニュー」-「設定」-「Raspberry Piの設定」でRaspberry Piの設定プロパティを開きます。
「インターフェイス」タブをクリックして、「シリアルポート」・有効、「シリアルコンソール」・無効に設定して、「OK」をクリックします。
再起動確認画面になるので、「はい」をクリックします。再起動すると汎用シリアルが有効になります。
パソコンとシリアルを接続して、パソコン側とRaspberry Pi側のシリアルポートの設定を次のようにして通信確認をします。
シリアルポートの設定は次の設定にします。
- ボーレート ・・・ 115200
- データビット ・・・ 8bit
- パリティ ・・・ none
- ストップビット・・・ 1bit
- フロー制御 ・・・ none
Raspberry Pi側のGtkTerm設定
GtkTermを起動して、「Configuration」-「Port」を選択します。
Portの設定は、候補に表示されない時には直接キーボードでLinuxデバイス名を入力します。Baud Rateなど正しい設定にします。
パソコンとRaspberry Piとの通信確認
パソコン側でTera Termでキー入力すると、Raspberry Pi側のGtkTermに入力したキーの文字が表示されます。
反対に、Raspberry Pi側でキー入力すると、パソコン側のTera Termに入力したキーの文字が表示されます。
これで送受信の確認ができます。
raspi-configで設定する場合
Raspberry Piにてターミナルソフトを起動して、次の「sudo raspi-config」コマンドを実行します。
$ sudo raspi-config
「3 Interface Options」を選択します。
「P6 Serial Port Enable/disable」を選択します。
ログインシェルにシリアル経由でアクセスするか確認になるので、「いいえ」を選択します。
シリアルポートのハードウェアを有効にするか確認になるので、「はい」を選択します。
「了解」を選択します。
メニュー画面に戻るので、「Finish」を選択します。
再起動確認になるので「はい」を選択して、Raspberry Piを再起動します。これで汎用シリアルが有効になります。
シリアルポートの構成説明
Raspberry Piで使用できるUARTにはPL011(16550互換)とmini UARTの2種類があります。
設定によってプライマリUARTがどちらになるかが変わります。この入れ替わる機能が分かりにくい部分だと思います。
また、Raspberry Pi 4ではUART2~UART5の4つのPL011が追加されています。
参照 : Raspberry Pi 公式 UART設定のページ
Raspberry Pi Zero、1、2、3は2つのUARTを持っています
名前 | タイプ |
UART0 | PL011 |
UART1 | mini UART |
Raspberry Pi 4は6つのUARTを持っています。
名前 | タイプ |
UART0 | PL011 |
UART1 | mini UART |
UART2 | PL011 |
UART3 | PL011 |
UART4 | PL011 |
UART5 | PL011 |
プライマリUARTとセカンダリUARTの構成
デフォルトでは、UART0のみが有効になっています。次の表はデフォルトでのUARTの割り当てをまとめた物です。
mini UARTは、プライマリまたはセカンダリ関係なく、デフォルトでは無効になっています。
Model | first PL011(UART0) | mini UART |
Raspberry Pi Zero | プライマリ | セカンダリ |
Raspberry Pi Zero W/WH | セカンダリ(Bluetooth) | プライマリ |
Raspberry Pi 1 | プライマリ | セカンダリ |
Raspberry Pi 2 | プライマリ | セカンダリ |
Raspberry Pi 3 | セカンダリ(Bluetooth) | プライマリ |
Raspberry Pi 4 | セカンダリ(Bluetooth) | プライマリ |
プライマリUARTは、GPIO 14 (TXD)とGPIO 15(RXD)に存在するUARTの1つとして選択されます。Linuxシリアルコンソールとして使用した場合には、このプライマリUARTで通信します。
セカンダリUARTは、通常GPIOコネクタにはありません。BluetoothコントローラーがあるModelでは、Bluetoothに接続されています。
シリアルポートのLinuxデバイス名
Linuxデバイス名 | 説明 |
/dev/ttyS0 | mini UART |
/dev/ttyAMA0 | first PL011(UART0) |
/dev/serial0 | プライマリUART0 |
/dev/serial1 | セカンダリUART1 |
「/dev/serial0」と「/dev/serial1」は、「/dev/ttyS0」または「/dev/ttyAMA0」のどちらかを指すシンボリックリンクになっていて、設定によって変わります。
PL011とmini UARTの相違点
mini UARTはPL011に比べて次のような欠点があります。
- PL011より少ないFIFO(送信および受信用の8シンボル深さのFIFO)
- Break信号検出ができない
- フレーミングエラーの検出ができない
- パリティビットが検出できない
- 受信タイムアウト割込みなし
- DCD、DSR、DTR、RI信号なし
mini UARTの詳細については、SoC周辺機器のドキュメントを参照してください。
シリアルポートの設定とGPIOとの対応関係
Raspberry Pi 4を元にシリアルポートの設定とGPIOとの対応関係を説明します。
「/boot/config.txt」の設定パラメータは、「dtoverlay -h uart0」コマンドで確認できます。「uart0」の所をuart1、uart2などに変えれば各ポートのHelpが確認できます。
$ dtoverlay -h uart0
Name: uart0
Info: Change the pin usage of uart0
Usage: dtoverlay=uart0,<param>=<val>
Params: txd0_pin GPIO pin for TXD0 (14, 32 or 36 - default 14)
rxd0_pin GPIO pin for RXD0 (15, 33 or 37 - default 15)
pin_func Alternative pin function - 4(Alt0) for 14&15,
7(Alt3) for 32&33, 6(Alt2) for 36&37
「raspi-gpio」コマンドを使うと、現在のGPIOの設定で有効になっている機能が分かります。
次の例では、シリアルポート(UART1)が有効になっているので、「TXD1」「RXD1」がGPIO 14、GPIO 15に割り当てられています。
$ raspi-gpio get 0-15
GPIO 0: level=1 fsel=0 func=INPUT pull=UP
GPIO 1: level=1 fsel=0 func=INPUT pull=UP
GPIO 2: level=1 fsel=0 func=INPUT pull=UP
GPIO 3: level=1 fsel=0 func=INPUT pull=UP
GPIO 4: level=1 fsel=0 func=INPUT pull=UP
GPIO 5: level=1 fsel=0 func=INPUT pull=UP
GPIO 6: level=1 fsel=0 func=INPUT pull=UP
GPIO 7: level=1 fsel=0 func=INPUT pull=UP
GPIO 8: level=1 fsel=0 func=INPUT pull=UP
GPIO 9: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 10: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 11: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 12: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 13: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
デフォルトのシリアルポート無効
デフォルトの状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 無効 |
Bluetooth | 有効 |
シリアルポート無効設定なので、「/boot/config.txt」の「enable_uart=0」になります。
[all]
enable_uart=0
次の図のように、UART0がBluetoothに接続されていて、UART1は無効になっていて使えない状態です。
Linuxデバイスとしても、「/dev/ttyAMA0」しか有効になっていません。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 7 01:01 /dev/ttyAMA0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 6月 7 01:01 /dev/serial1 -> ttyAMA0
シリアルポート有効、mini UARTがプライマリ
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 有効 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
[all]
enable_uart=1
次の図のように、UART0がBluetoothに接続されていて、UART1が有効になりました。
Linuxデバイスとして、「/dev/ttyAMA0」と「/dev/ttyS0」が有効になり、GPIOの14,15にTXDとRXDが割り当てられます。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 7 21:25 /dev/ttyAMA0
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 7 21:25 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 5 6月 7 21:25 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 6月 7 21:25 /dev/serial1 -> ttyAMA0
$ raspi-gpio get 14-15
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
シリアルポート有効、PL011をプライマリに変更
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 有効 |
PL011 | プライマリに変更 |
mini UART | Bluetoothに変更 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
「vi」や「nano」などのエディタにて次の項目を追記します。
$ sudo nano /boot/config.txt
mini UARTをBluetoothに変更するため、「dtoverlay=miniuart-bt」を追記します。
mini UARTを正常に使うために、クロック設定「core_freq=250」を追記します。(このクロック設定の変わりに、「force_turbo=1」でも大丈夫です。どちらかを設定してください。)
追記したら、Raspberry Piを再起動すると設定が反映されます。
[all]
enable_uart=1
dtoverlay=miniuart-bt
core_freq=250
次の図のように、UART0がシリアルポートになり、UART1にBluetoothが接続されます。また、プライマリとセカンダリが入れ替わります。
Linuxデバイスとして、「/dev/ttyAMA0」と「/dev/ttyS0」が有効になり、プライマリ「/dev/serial0」のリンク先が「ttyAMA0」に変わり、セカンダリ「/dev/serial1」のリンク先が「ttyS0」に変わります。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 7 23:31 /dev/ttyAMA0
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 7 23:31 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 6月 7 23:31 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 6月 7 23:31 /dev/serial1 -> ttyS0
$ raspi-gpio get 14-15
GPIO 14: level=1 fsel=4 alt=0 func=TXD0 pull=NONE
GPIO 15: level=1 fsel=4 alt=0 func=RXD0 pull=UP
シリアルポート有効、Bluetooth無効
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 無効 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
「vi」や「nano」などのエディタにて次の項目を追記します。
$ sudo nano /boot/config.txt
Bluetoothを無効にするため、「dtoverlay=disable-bt」を追記します。
追記したら、Raspberry Piを再起動すると設定が反映されます。
[all]
enable_uart=1
dtoverlay=disable-bt
次の図のように、UART0がシリアルポートになり、UART1は存在するがどこにも接続されなくて、Bluetoothが無効になります。
タスクバーの左側のBluetoothアイコンが消えます。
Linuxデバイスとして、「/dev/ttyAMA0」が有効になり、「/dev/ttyS0」も存在していますが、シリアル通信では使えません。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 7 23:46 /dev/ttyAMA0
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 7 23:46 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 6月 7 23:46 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 6月 7 23:46 /dev/serial1 -> ttyS0
$ raspi-gpio get 14-15
GPIO 14: level=1 fsel=4 alt=0 func=TXD0 pull=NONE
GPIO 15: level=1 fsel=4 alt=0 func=RXD0 pull=UP
「/dev/ttyS0」(UART1)が通信で使えない理由として、UART0とUART1のデフォルトのポートがどちらも同じGPIO14、GPIO15が割り当てられます。
「raspi-gpio get 14-15」コマンドで有効なのは「TXD0」「RXD0」なので、UART0が割り当てられています。
Helpを確認すると、オプションでGIPOの割り当てを変更できるようですが、GPIO32、GPIO33などはRaspberry Piの40PINのコネクタには存在しないため通常の方法では使えません。
$ dtoverlay -h uart0
Name: uart0
Info: Change the pin usage of uart0
Usage: dtoverlay=uart0,<param>=<val>
Params: txd0_pin GPIO pin for TXD0 (14, 32 or 36 - default 14)
rxd0_pin GPIO pin for RXD0 (15, 33 or 37 - default 15)
pin_func Alternative pin function - 4(Alt0) for 14&15,
7(Alt3) for 32&33, 6(Alt2) for 36&37
$ dtoverlay -h uart1
Name: uart1
Info: Change the pin usage of uart1
Usage: dtoverlay=uart1,<param>=<val>
Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14)
rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15)
UART2を有効、シリアルポート有効
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 有効 |
UART2 | 有効 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
「vi」や「nano」などのエディタにて次の項目を追記します。
$ sudo nano /boot/config.txt
UART2を有効にするため、「dtoverlay=uart2」を追記します。
追記したら、Raspberry Piを再起動すると設定が反映されます。
[all]
enable_uart=1
dtoverlay=uart2
次の図のように、UART0はBluetoothに接続され、UART1とUART2が有効になります。
Linuxデバイスとして、「/dev/ttyAMA0」と「/dev/ttyS0」が有効になり、UART0用にGPIOの14,15にTXDとRXDが割り当てられます。さらに「/dev/ttyAMA1」が追加有効になって、UART2用にGPIO0,1にTXDとRXDが割り当てられます。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 8 00:22 /dev/ttyAMA0
crw-rw---- 1 root dialout 204, 65 6月 8 00:22 /dev/ttyAMA1
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 8 00:22 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 5 6月 8 00:22 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 6月 8 00:22 /dev/serial1 -> ttyAMA0
$ raspi-gpio get 0-15
GPIO 0: level=1 fsel=3 alt=4 func=TXD2 pull=NONE
GPIO 1: level=1 fsel=3 alt=4 func=RXD2 pull=UP
GPIO 2: level=1 fsel=0 func=INPUT pull=UP
GPIO 3: level=1 fsel=0 func=INPUT pull=UP
GPIO 4: level=1 fsel=0 func=INPUT pull=UP
GPIO 5: level=1 fsel=0 func=INPUT pull=UP
GPIO 6: level=1 fsel=0 func=INPUT pull=UP
GPIO 7: level=1 fsel=0 func=INPUT pull=UP
GPIO 8: level=1 fsel=0 func=INPUT pull=UP
GPIO 9: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 10: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 11: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 12: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 13: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
UART3を有効、シリアルポート有効(UART4、UART5も同じ)
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 有効 |
UART3 | 有効 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
「vi」や「nano」などのエディタにて次の項目を追記します。
$ sudo nano /boot/config.txt
UART3を有効にするため、「dtoverlay=uart3」を追記します。
追記したら、Raspberry Piを再起動すると設定が反映されます。
[all]
enable_uart=1
dtoverlay=uart3
次の図のように、UART0はBluetoothに接続され、UART1とUART3が有効になります。
Linuxデバイスとして、「/dev/ttyAMA0」と「/dev/ttyS0」が有効になり、UART0用にGPIOの14,15にTXDとRXDが割り当てられます。さらに「/dev/ttyAMA1」が追加有効になって、UART3用にGPIO4,5にTXDとRXDが割り当てられます。
UART2~UART5の1つのポートのみを有効にした場合「/dev/ttyAMA1」が追加されます。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 8 00:37 /dev/ttyAMA0
crw-rw---- 1 root dialout 204, 65 6月 8 00:37 /dev/ttyAMA1
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 8 00:37 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 5 6月 8 00:37 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 6月 8 00:37 /dev/serial1 -> ttyAMA0
$ raspi-gpio get 0-15
GPIO 0: level=1 fsel=0 func=INPUT pull=UP
GPIO 1: level=1 fsel=0 func=INPUT pull=UP
GPIO 2: level=1 fsel=0 func=INPUT pull=UP
GPIO 3: level=1 fsel=0 func=INPUT pull=UP
GPIO 4: level=1 fsel=3 alt=4 func=TXD3 pull=NONE
GPIO 5: level=1 fsel=3 alt=4 func=RXD3 pull=UP
GPIO 6: level=1 fsel=0 func=INPUT pull=UP
GPIO 7: level=1 fsel=0 func=INPUT pull=UP
GPIO 8: level=1 fsel=0 func=INPUT pull=UP
GPIO 9: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 10: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 11: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 12: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 13: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
UART2~UART5を有効、シリアルポート有効
シリアルポートを有効にした状態として、次の設定の時にRaspberry Piがどうなっているか説明します。
ポート | 設定 |
シリアルポート | 有効 |
Bluetooth | 有効 |
UART2 | 有効 |
UART3 | 有効 |
UART4 | 有効 |
UART5 | 有効 |
シリアルポートを有効にしたので、「/boot/config.txt」の「enable_uart=1」になります。
「vi」や「nano」などのエディタにて次の項目を追記します。
$ sudo nano /boot/config.txt
UART2~5を有効にするため、「dtoverlay=uart2」「dtoverlay=uart3」「dtoverlay=uart4」「dtoverlay=uart5」を追記します。
追記したら、Raspberry Piを再起動すると設定が反映されます。
[all]
enable_uart=1
dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5
次の図のように、UART0はBluetoothに接続され、UART1~UART5が有効になります。
Linuxデバイスとして、「/dev/ttyAMA0」と「/dev/ttyS0」が有効になり、UART0用にGPIOの14,15にTXDとRXDが割り当てられます。さらに「/dev/ttyAMA1」「/dev/ttyAMA2」「/dev/ttyAMA3」「/dev/ttyAMA4」が有効になって、UART2用にGPIO0,1、UART3用にGPIO4,5、UART4用にGPIO8,9、UART5用にGPIO12,13それぞれにTXDとRXDが割り当てられます。
$ ls -l /dev/ttyAMA*
crw-rw---- 1 root dialout 204, 64 6月 8 00:51 /dev/ttyAMA0
crw-rw---- 1 root dialout 204, 65 6月 8 00:51 /dev/ttyAMA1
crw-rw---- 1 root dialout 204, 66 6月 8 00:51 /dev/ttyAMA2
crw-rw---- 1 root dialout 204, 67 6月 8 00:51 /dev/ttyAMA3
crw-rw---- 1 root dialout 204, 68 6月 8 00:51 /dev/ttyAMA4
$ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 6月 8 00:51 /dev/ttyS0
$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 5 6月 8 00:51 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 6月 8 00:51 /dev/serial1 -> ttyAMA0
$ raspi-gpio get 0-15
GPIO 0: level=1 fsel=3 alt=4 func=TXD2 pull=NONE
GPIO 1: level=1 fsel=3 alt=4 func=RXD2 pull=UP
GPIO 2: level=1 fsel=0 func=INPUT pull=UP
GPIO 3: level=1 fsel=0 func=INPUT pull=UP
GPIO 4: level=1 fsel=3 alt=4 func=TXD3 pull=NONE
GPIO 5: level=1 fsel=3 alt=4 func=RXD3 pull=UP
GPIO 6: level=1 fsel=0 func=INPUT pull=UP
GPIO 7: level=1 fsel=0 func=INPUT pull=UP
GPIO 8: level=1 fsel=3 alt=4 func=TXD4 pull=NONE
GPIO 9: level=1 fsel=3 alt=4 func=RXD4 pull=UP
GPIO 10: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 11: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 12: level=1 fsel=3 alt=4 func=TXD5 pull=NONE
GPIO 13: level=1 fsel=3 alt=4 func=RXD5 pull=UP
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
動作確認
Raspberry Pi側はGtkTermで、パソコン側はTera Termを使用して以下の組み合わせで動作テストをしました。
2021/6/8現在のRaspberry Pi OSに「upgrade」コマンドにて最新にして動作確認をしています。
$ sudo apt-get update
$ sudo apt-get upgrade
Raspberry Pi OS
Release date: May 7th 2021
Kernel version: 5.10
$ uname -a
Linux raspberrypi 5.10.17-v7l+ #1421 SMP Thu May 27 14:00:13 BST 2021 armv7l GNU/Linux
〇印の所が同時にボートオープンしてテストしています。
ポート | タイプ | 組み合わせ | |||||||
UART0 | PL011 | 〇 | 〇 | ||||||
UART1 | mini UART | 〇 | 〇 | ||||||
UART2 | PL011 | 〇 | 〇 | 〇 | |||||
UART3 | PL011 | 〇 | 〇 | 〇 | |||||
UART4 | PL011 | 〇 | 〇 | 〇 | |||||
UART5 | PL011 | 〇 | 〇 | 〇 |
GtkTermでのテストでは、上記の組み合わせでは問題なく動作しました。
シリアル通信、Pythonサンプルプログラム
Pythonにて、シリアル通信をするサンプルプログラムで「serial_sample.py」を作成します。
プログラムは起動すると、受信スレッドが立ち上がってパソコン側キーボード入力したキーコードを受信して、エコーバックします。
終了するためには、パソコン側で「Enter」キーを入力すると、受信スレッドが終了してプログラムも終了します。
import threading
import serial
import logging
logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')
# シリアル通信ベースクラス
class SerialBase:
def __init__(self):
# commの初期化
self.comm = ''
# ポートオープンフラグ
self.isOpen = False
# タイムアウトフラグ
self.isTimeOut = False
# Threadの終了フラグ
self.isStop = False
# 受信データバッファ
self.receiveBuffer = bytearray()
def IsOpen(self):
return self.isOpen
def IsTimeOut(self):
return self.isTimeOut
def IsStop(self):
return self.isStop
def Stop(self):
self.isStop = True
def Write(self, data):
self.comm.write(data)
def Read(self):
return self.comm.read()
def Open(self, ser, port, baud='115200'):
try:
logging.debug("Serial port open.")
self.comm = ser
self.comm = serial.Serial(port, baud, timeout=0.01)
self.isOpen = True
except Exception as err:
logging.error("Serial port open error.")
logging.error(type(err))
logging.error(err.args)
logging.error(err)
self.isOpen = False
return self.isOpen
def Close(self):
self.Stop()
if self.IsOpen():
logging.debug("Serial port close.")
self.comm.close()
self.isOpen = False
# 受信スレッド
def receiveWorker(ser):
logging.debug("receiveWorker Start.")
# 受信データをエコーバックし、改行したら終了します
while not ser.IsStop():
buff = ser.Read()
if len(buff) > 0:
ser.Write(buff)
if buff==b'\r':
break
logging.debug("receiveWorker Stop.")
def main():
print("Serial sample.")
# シリアルクラス
ser = SerialBase()
ser.Open(ser, '/dev/serial0', '115200')
ser.Write(b'\r\nStart.\r\n')
th = threading.Thread(target=receiveWorker, args=(ser,))
th.start()
th.join()
ser.Close()
if __name__ == "__main__":
main()
作成した「touch_sample.py」を次のコマンドにて実行します。
$ python3 serial_sample.py
プログラムを実行すると「Start.」と表示されるので、適当なキーを入力します。終了する場合は「Enter」を押します。
まとめ
Raspberry Piのシリアルポートは、mini UARTとPL011が設定によって、プライマリとセカンダリ入れ替わったりして分かりにくいと思います。
そういった分かりにくい部分が解消されたら幸いです。
以上、「Raspberry Piのシリアルポート設定(UART)を理解する」の内容でした。