3

私は Python プログラマーではなく、むしろ電子回路設計者ですが、今回はマイクロコントローラーから RS232 ポート経由で Python スクリプト (PHP スクリプトによって呼び出される) に送信される生データを処理する必要があります。

Pythonを使用してシリアル(RS232)ポートから生のバイトを読み取る最良の方法を決定するためにかなりの時間を費やしましたが、結果が得られました-しかし、調査中に気づいた特定の不一致を誰かが明確にしてほしいと思います。それは:

1:
同様の質問をした多くの人が、serialまたはpySerialモジュールを使用しているかどうか、およびシリアルライブラリをどのようにインストールしたかを尋ねられているのを見ることができます。モジュールがすぐに使えるので、どのモジュールを使用しているのか本当にわからないとしか言​​えません。どこかで読んだのserialpySerial同じことですが、それが本当かどうかはわかりません。私が知っているのは、Raspbian OS で Python 2.7.9 を使用していることだけです。

2:シリアルポートから読み取るためのメソッドがあることを読みましたが、pySerial
APIドキュメントにはメソッドについての言及がありません。さらに、「読み取るバイト数」引数をメソッドだけでなくメソッドにも渡すことができることを発見しました(同じように機能し、読み取るバイト数を制限します)が、それを文書化することはできません。read()readline()readline()readline()read()

3: RS232 バッファからのすべて
のデータが読み取ら れたかどうかを判断する方法を検索すると、次のコードが見つかりました

read_byte = ser.read()
while read_byte is not None:
    read_byte = ser.read()
    print '%x' % ord(read_byte)

しかし、その結果は次のとおりです。

Traceback (most recent call last):
  File "./testread.py", line 53, in <module>
    read_all()
  File "./testread.py", line 32, in read_all
    print '%x' % ord(read_byte)
TypeError: ord() expected a character, but string of length 0 found

バッファから最後のバイトを読み取ると、次のコードでのみ空のバッファを検出できました。

while True:
    c = rs232.read()
    if len(c) == 0:
        break
    print int(c.encode("hex"), 16), " ",

そのため、私にとってうまくいかなかったコードが、私のもの以外のシリアル ライブラリ用のものかどうかはわかりません。ポートを開くための私のコードはBTWです:

rs232 = serial.Serial(
    port = '/dev/ttyUSB0',
    baudrate = 2400,
    parity = serial.PARITY_NONE,
    stopbits = serial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1
)

4:
µC から受信しているデータの形式は次のとおりです。

0x16 0x02 0x0b 0xc9 ... 0x0d 0x0a

それはsome raw bytes + \r\nです。「生のバイト」には が含まれ0x00ている可能性があるため、バイトをPython文字列変数に読み込むことに関して問題がないことを誰かが確認できますか? 私が理解しているように、それはうまくいくはずですが、100%確実ではありません。

4

1 に答える 1

3

PySerial は、Pi では使用していませんが、私にとっては機能します。

3: Read() は文字列を返します - データが読み取られない場合、これは長さがゼロになるため、新しいバージョンが正しいです。文字列は文字ではないため、たとえば ord(read_byte[0]) を使用して、最初の文字に対応する数値を出力する必要があります (文字列の長さが >0 の場合) 関数:

while True:
    c = rs232.read()
    if len(c) == 0:
        break
    print int(c.encode("hex"), 16), " ",

読み取ったデータを蓄積するために何かを追加する必要があります。それ以外の場合は破棄されます

rcvd = ""
while True:
    c = rs232.read()
    if len(c) == 0:
        break
    rcvd += c
    for ch in c:
        print ord(ch), " ",

4: はい、ヌル (0x00) バイトを受け取って文字列に入れることができます。例えば:

a="\x00"
print len(a)

長さ1を出力します

于 2016-10-22T10:01:40.567 に答える