7839

雑草魂エンジニアブログ

【Python】pySerial を用いたシリアル通信(ループバック試験)

前回の記事で、Raspberry Piでの開発環境のセットアップまでを Pipenv で完了させた。そこで、最初にUSBのシリアル通信をしてみたので、備忘録として残しておく。

概要

今回は、Raspberry PiとPCなどを接続してシリアル通信をするのではなく、ループバック試験を実行することでシリアル通信の基本を確認した。つまり、Raspberry PiのOUT(Tx)から信号を出し、その信号を自分のIN(Rx)に入れて信号を確認するテストを実施した。

f:id:serip39:20200630003830p:plain

準備物

シリアル通信とは

シリアル通信とは、1つのデータ伝送路を使い、HIGH/LOWの電圧レベルを連続的(=シリアル)に変化させて、1ビットずつデータを送信する方式である。反対に、パラレル通信は、複数のデータ伝送路を使い、1度に複数のデータを並行(=パラレル)に送信する方式である。

シリアル通信の中には様々な規格がある。よく使われる3種類を列挙する。

  • SPI
  • I2C
  • UART

シリアル通信の代表的なものにUSBがある。USBは「Universal Serial Bus」(ユニバーサル・シリアル・バス)の頭文字を取った規格である。 今回、USBシリアル通信ドングルを用いて試験を行った。

pySerialとは

Pythonでシリアル通信をする為のモジュールである。このモジュールを用いることで、Pythonでシリアルポートへのアクセスが可能となる。WindowsOSXLinuxなどのOSで動作する。

pythonhosted.org

実装方法

Pythonの仮想環境をつくり、開発をすることをオススメする。以下は、Pipenv を想定する。

インストール

$ pipenv install pyserial

今回、私がインストールした Python3.7.3 にはプリインストールされていたので、インストールする必要はなかった。

使用方法

基本的には、以下を使用する。

API 用途
Serial 初期設定(シリアル通信の設定)
write バイナリーデータ( bytes 型)を送信する
readline データを受信する
open ポート開く
close ポート閉じる
flush データを送信するまで待機する

pySerial API — pySerial 3.0 documentation

ループバック試験

import serial
import struct

use_port = '/dev/ttyUSB0'

_serial = serial.Serial(use_port)
_serial.baudrate = 9600
_serial.parity = serial.PARITY_NONE
_serial.bytesize = serial.EIGHTBITS
_serial.stopbits = serial.STOPBITS_ONE
_serial.timeout = 5 #sec

commands = [ 0xB6, 0x01, 0x02, 0x00 ]

for cmd in commands:
    data = struct.pack("B", cmd)
    print("tx: ", data)
    _serial.write(data)

_serial.flush()

rx = _serial.readline()
print("rx: ", rx)

_serial.close()

結果表示:

(pyserial) pi@raspberrypi:~/projects/pyserial $ python test.py 
tx:  b'\xb6'
tx:  b'\x01'
tx:  b'\x02'
tx:  b'\x00'
rx:  b'\xb6\x01\x02\x00'

バイト配列を順番に送信して、きちんと受信することができていることを確認できた。

おまけ(struct)

struct モジュールを使うことで、フォーマットを指定して、バイナリデータを作成したり、バイナリデータから数値等に変換を行うことができる。バイナリデータは Python で bytes 型で表現され、センサーや制御機器への入出力で多く用いられる。

# 値 → バイナリーデータ
pack(フォーマット, 値)

# バイナリーデータ → フォーマットの型の値
unpack(フォーマット, バイナリデータ)
フォーマット C言語の型 Pythonの型 サイズ
b signed char 整数 1
h short 整数 2
l long 整数 4

struct --- バイト列をパックされたバイナリデータとして解釈する — Python 3.8.3 ドキュメント

まとめ

今回は、Raspberry Pi で Pyserial を用いてシリアル通信のループバック試験を行うことができた。

それでは、ステキな開発ライフを。