はじめに
pyserialを使ったBinary送受信について覚えとして記載します。
PyserialでBinaryを送信する方法
参考:pyserial(pythonシリアルポート)を使用したバイナリデータ
この中で、pyserialのSerial.write()メソッドは文字列データのみを送信する。と書かれています。
b"\x00"のような出力になるようにBinary変換したものが送信できます。(「\x」というのは次に続く2文字を16進表記の整数値として解釈することを意味する。)
変換例として
array – データ型固定のシーケンスを使った方法が書かれています。
import serial
import array
# 送信したい Binary Data
b = [0xc0, 0x04, 0x00]
print(b)
# 10進数に直されて表示される
# >>>[192, 4, 0]
# PythonのBinaryに変換 arrayを用いた方法
b_data=array.array('B', [0xc0, 0x04, 0x00]).tostring()
print(b_data)
# >>>b'\xc0\x04\x00'
# PythonのBinaryに変換 bytesを用いた方法
b2_data = bytes(b)
print(b2_data)
# >>>b'\xc0\x04\x00'
# 比較するとどちらも同じ。
print(b_data==b2_data)
# >>>True
bytes()を用いた方が簡単なので、こちらを用います。
前回の記事にあるTWELITEのBinaryモードでやり取りするときに使うことができます。
送信
# 送信 例えば、
senddata=[0xA5,0x5A,0x80,0x07,0x00,0x00,0x00,0x64,0xFF,0xFF,0x02,0x67]
print(senddata)
# print出力すると10進表記になる
# [65, 90, 128, 7, 1, 0, 0, 100, 255, 255, 2, 103]
# Binaryに変換
send_binary =bytes(senddata)
# bytearray()でもよい
# send_binary =bytearray(senddata)
print(send_binary)
# 送信データBinary
# b'\xa5Z\x80\x07\x01\x00\x00d\xff\xff\x02g'
# pyserialで送信
with serial.Serial('COM12', 115200) as ser:
print('---')
ser.write(send_binary)
print('---')
受信
with serial.Serial('COM12', 115200) as ser:
# 読み込むByte数をreadの引数に指定する。
b_reply = ser.read(23)
# 全部読み込む場合
b_reply = ser.read_all()
print(b_reply)
# >>> b'\xa5Z\x80\x04\xdb\xa1\x98\x01\xe3\x04\xa5Z\x80\x07\x01\x04\x00\x013<")\x04'
# structモジュールを使って何Byteの束でどのような型で読み込むか指定する必要がある。
# 今回は、23Byteを1Byteずつの区切りで読み込む
# 23BはBが23個並んでいることと同じ。Bは、C言語のunsigned char型で、Pythonでは整数で1Byte
reply =struct.unpack('23B',b_reply)
print(reply)
# >>> 165, 90, 128, 4, 219, 161, 152, 1, 227, 4, 165, 90, 128, 7, 1, 4, 0, 1, 51, 60, 34, 41, 4
# 最後の4は(EOT) 伝送終了文字( End-of-Transmission character)
# Byteの何番目がどの情報を持っているかの仕様により解析する。