ソーラー インバーター (Delta RPI M6A) には、マスター/スレーブ RS485 バスがあります。マスターは、1 秒あたり数回インバーターに応答データ セットを送信するように要求し、インバーターはそれを実行します。合計通信セットは 176 バイトです。Raspberry Pi 3B は、FTDI FT232 USB-Serial (UART) IC コンバーターを使用してこのバスに接続されます。
バス上で送信されるデータの読み取りには、Python プログラムが使用されます。これは、特殊文字として解釈されるバイトがない場合にのみ正常に機能します (少なくとも、それは私が思うことです)。まず、入力を 1 バイトずつ読み取ります。適切な「送信開始」シーケンス (STX の後に ACK が続き、inverterID=1 が続く) が見つかると、160 バイトと終了シーケンスのデータ セットが期待されます。最後に読み取ったバイトは ETX (= ascii 3) である必要があります。
予想される出力は次 のとおりです。予想される出力のスクリーンショット
問題は、一部のバイトがエスケープや改行などの特殊文字に相当する場合、それらのバイトは ser.read() コマンドによって「認識」されないことだと思います。次に、数バイト早く ETX バイトを取得します。これは、途中のいくつかのバイトがキャプチャされなかったことを示しています。
コードの関連部分は次のとおりです。
if bytes_to_read == 1:
raw_data = ser.read()
pos = pos + 1;
# print pos;
if ord(raw_data) == 2: # 2 = start of text character
pos = 1;
print str(pos) + ' ' + str(ord(raw_data))
elif pos == 2 and ord(raw_data) == 6: # 6 = acknowledge character
ack = True;
print str(pos) + ' ' + str(ord(raw_data))
elif pos == 2 and ord(raw_data) != 6: # 6 = acknowledge character
ack = False;
print str(pos) + ' ' + str(ord(raw_data)) + ' ack reset to False'
elif pos == 3 and ack and ord(raw_data) == 1:
bytes_to_read = 164;
print str(pos) + ' ' + str(ord(raw_data))
elif bytes_to_read == 164:
raw_data_byte = ser.read(164)
print len(raw_data_byte);
bytes_to_read = 1;
ack = False;
print 'got to read 164 bytes, first byte is ' + str(ord(raw_data_byte[0])) + ', last byte: ' + str(ord(raw_data_byte[163]));
if ord(raw_data_byte[0]) == 160 and ord(raw_data_byte[163]) == 3: # 160 = data bytes specified by sender
print ('ready to process ' + str(len(raw_data_byte)) + ' bytes')
supplied_power_byte1 = bin(ord(raw_data_byte[101]))[2:].zfill(8)
supplied_power_byte2 = bin(ord(raw_data_byte[102]))[2:].zfill(8)
キャプチャされたバイトは後で処理され、データベースへの書き込みが可能になります。
ser.read() と ser.readline() を試してみましたが、結果は同じでした。
私を正しい方向に向けるヒントがあれば感謝します。
ありがとう、ブラム