UARTのRTS/CTSを使ったハードウェアフロー制御を試してみました。
接続方法・プログラムから実際に測定した波形まで紹介します。
ラズパイとUSBシリアルでテストしていますので、誰でも同様に実施可能です。
UARTでRTS/CTSのフロー制御をしてみた
UARTでRTS/CTSのハードウェアフロー制御をしてみました。
ラズベリーパイとUSBシリアル通信ケーブルで接続しています。
実際にオシロスコープでRTS/CTSの波形まで確認しています。
ラズパイの設定方法からUSBシリアルへの接続方法まで紹介します。
Pythonでプログラムして、ラズべリーパイからフロー制御を実施しています。
(ハードウェア/ソフトウェアの両方のフロー制御が出来るようにプログラムしています)
動画でも一連の流れを紹介していますので、一緒にご覧ください。
UART(シリアル)通信のフロー制御
UART(シリアル)通信はデータ線の2本(TxD,RxD)だけでも接続可能です。
送受信のデバイスは自由なタイミングで通信することができます。
単純にTx,Rxをループバックさせて、UARTシリアル通信のRead/Writeも可能です。
下記記事で紹介しています。(リンク先はこちら)
Pythonでserial(シリアル)通信!Read/Writeの波形を見てみた
但し、接続先が送信許可した場合のみに通信する「フロー制御」も対応可能です。
「フロー制御」によりデータの取りこぼしを防いで、信頼性高い通信が可能となります。
フロー制御はハードウェアとソフトウェアの両方で対応できます。
(今回はハードウェアフロー制御をメインに紹介しています。)
- ハードウェアフロー制御…RTS/CTSの制御信号を使用
- ソフトウェアフロー制御…Xon/Xoffのコードを使用
USBシリアル通信ケーブル
今回は「ラズベリーパイ」と「USBシリアル通信ケーブル」でUARTを接続します。
ハードウェアフロー制御を行うには、RTS/CTSの制御線がある通信ケーブルが必要です。
- RTS…Request to Send(送信要求)
- CTS…Clear to Send(送信可)
今回テストに使ったケーブルは下記記事で紹介しています。(リンク先はこちら)
USBシリアル通信ケーブルをWindows10用に購入してみた
ラズベリーパイでハードウェアフロー制御を行う
ラズベリーパイはUARTが使えますが、デフォルト(UART0)ではRTS/CTSは使えません。
通常とは違うUARTを設定して、ハードウェアフロー制御を使えるようにします。
UART0~5がありますが、UART4(GPIO8-11)でRTS/CTS含めて設定します。
- GPIO8…TxD
- GPIO9…RxD
- GPIO10…CTS
- GPIO11…RTS
UART0~5のピンが何処にあるのかは下記コマンドで分かります。
ラズベリーパイ4でのuart0とuart4の結果を貼り付けておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
pi@raspberrypi:~ $ 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 |
1 2 3 4 5 6 7 8 |
pi@raspberrypi:~ $ dtoverlay -h uart4 Name: uart4 Info: Enable uart 4 on GPIOs 8-11. BCM2711 only. Usage: dtoverlay=uart4,<param> Params: ctsrts Enable CTS/RTS on GPIOs 10-11 (default off) |
ラズパイでUARTを複数使えるように設定
「設定」→「Raspberry Piの設定」からシリアルポートを有効にしておきます。
ただこの状態だとデフォルトのUART0しか使えません。
/bootのフォルダにあるconfig.txtを編集します。
筆者はVimで編集していますが、各好きな方法で編集してもらえれば構いません
下記例のようにUART4をctsrtsのパラメータ含めて追記します。
一番最後の行に記載すればOKです。
編集後はラズパイの再起動をお願いします。
下記コマンドを入力するとUART4のデバイスファイルの「ttyAMA1」が確認できます
PythonでUARTのフロー制御
ラズパイとPythonからフロー制御を切り替えれるようにプログラムします。
Pythonで簡単にハードウェア/ソフトウェアのフロー制御をON/OFF可能です。
- ソフトウェアフロー制御…xonxoff
- ハードウェアフロー制御…rtscts
実際のプログラムは下記です。
必要に応じてフロー制御箇所のTrue/Falseを切り替えればOKです。
1 2 3 4 |
import serial ser = serial.Serial('/dev/ttyAMA1', 115200, xonxoff=False, rtscts=False) ser.write(b'Hello World') ser.close() |
プログラム内容としては、UARTでシリアル通信で「Hello World」を出力します。
ラズパイから送信して、USBシリアル通信ケーブル経由でPCのTeraTermで受信します。
ラズパイでPythonのプログラムは作成することができます。
初心者の方でも簡単に作れます。下記記事を参考にしてください。(リンク先はこちら)
ラズベリーパイでプログラミング入門!Pythonの簡単な始め方
ハードウェアフロー制御の接続
テストしたラズベリーパイとUSBシリアルの配線は下記となります。
(ラズパイ(ホスト側)視点で信号名を記載しています。)
TX⇔RX、CTS⇔RTSの接続をテレコにして通信させています。
オシロスコープで各信号を測定できるように、プローブ接続しています。
オシロの使い方に関しては下記記事でも紹介しています。
オシロスコープの使い方!初めての人向けに多くの測定事例を紹介
シリアル通信でフロー制御のテスト
テスト環境も整いましたので、下記3パターンでUART(シリアル)通信を測定してみました。
- フロー制御無し(Tx,Rxのみ)
- ハードウェアフロー制御
- ソフトウェアフロー制御
冒頭でも紹介しましたが、ハードウェアフロー制御に関しては動画でも紹介しています。
通信・動作時の波形の切り替わりが分かりやすいです。是非一緒にご覧ください。
フロー制御無し(Tx,Rxのみ)
通常のTxD,RxDのデータ線だけでも問題なくUART(シリアル)通信できます。
プログラム上、フロー制御はハード・ソフトともにOFF(False)にしています。
1 2 3 4 |
import serial ser = serial.Serial('/dev/ttyAMA1', 115200, xonxoff=False, rtscts=False) ser.write(b'Hello World') ser.close() |
また通信速度の115200bpsも確認しています。
通信速度を変えた場合、またUART⇔RS232Cの違いに関しても別記事で紹介しています。
USBシリアル通信のボーレートの最大は?通信速度(bps)をオシロで確認
ハードウェアフロー制御
ハードウェアフロー制御では相手先のCTS(送信可)信号が来ていた場合に通信可能です。
測定した波形ですが、CTSがActive Lowでデータが送信できています。
ラズパイから「Hello World」が出力されています。
Pythonのプログラムでは、フロー制御はハードをON(True)にしています。
1 2 3 4 |
import serial ser = serial.Serial('/dev/ttyAMA1', 115200, xonxoff=False, rtscts=True) ser.write(b'Hello World') ser.close() |
CTS/RTSはプルアップされている
動画でも紹介していますが、Tera termを設定中の時はCTSはプルアップされています。
RTSに関しても同様で、プログラム動作前はプルアップされています。
波形を確認しても、通信プルアップされて常にHigh状態になっています。
CTSはTertermが設定完了するとActive Lowになります。
RTSに関してはホスト側(ラズパイ+Python)から通信するとActive Lowになります。
また今回はUART通信であることにご注意下さい。
下記記事でも紹介しましたが、RS232C通信だとUART通信と信号極性が逆になります。
CTS/RTSを短絡させる
もしシリアル通信機器のハードウェアフロー制御を強制的にOFF(無視)したい場合です。
その際はCTS/RTSを短絡させます。相手先のCTSを無視してデータを送信できます。
ソフトウェアフロー制御
一緒にソフトウェアフロー制御もテストしてみました。
ただし、わざとバッファを詰まらせてXon/Xoffのコード発生まではさせていません。
そのため、データ内容としては通常のデータと同じになります。
Pythonのプログラムでは、フロー制御はソフトをON(True)にしています。
1 2 3 4 |
import serial ser = serial.Serial('/dev/ttyAMA1', 115200, xonxoff=True, rtscts=False) ser.write(b'Hello World') ser.close() |
別記事でわざとXon/Xoffを発生させて、ソフトウェアフロー制御を確認しています。
是非一緒にご覧ください。(リンクはこちら)
CTS信号ピンがActiveでない場合
折角なのでCTS信号が異常な(Activeでない)場合も確認します。
環境としてはRTS/CTSの配線はしていますが、わざと相手先のTeratermを起動しません。
その状態でハードウェアフロー制御をしてみます。
CTSが送信可でない場合に、ホスト側でPythonのプログラムを動かしました。
その結果、データ(Hello World)が送信されない形になりました。
今回の環境ではプログラム終了時に、若干波形は確認できました。
ただし最初の一文字目の「H」だけで不完全なデータとなります。
まとめ
今回はUART(シリアル)通信のRTS/CTS信号に関して紹介させていただきました。
記事をまとめますと下記になります。
USBシリアル通信ケーブルはデバッグ時に非常に便利なツールです。
RTS/CTS信号も使えるケーブルを購入することをおススメします。
コメント