1

Pythonのシリアルモジュール(および光学読み取りヘッドを備えたUSBからシリアルへのコンバーター(FTDI)。IEC 62056-21で説明されているプロトコルを使用)を使用してユーティリティメーターを読み取ろうとしました。セットアップは、他のソフトウェアで動作することが知られています。

b'/?!\r\n' を 300bit/s で送信した後、メーターはメーカー、ファームウェアのバージョン、および通信速度を切り替えるための提案で応答します。したがって、プログラムは速度を認識し、5 が速度 9600 である「データ読み取りモード」を要求します<ack>050<CR><LF>。次に、プログラムはボーレートを切り替えます。

ボーレートが切り替わるまでは問題ありません。<STX>通常の動作では、メーターは で始まり で終わり、 で終わる<ETX>数行のテキストを含むデータのフレームを送信し<CR><LF>ます。
しかし、約 9 行のテキストが欠落しています。プログラムは 9 行目または 10 行目の途中で追いつきます。代わりに、Null バイトの長い文字列が表示されることがあります。
コードは次のとおりです (テストで残ったコメントの一部を残しました)。

import serial
import re
from time import sleep

def readframe():
    buf=b''
    while (buf == b'' or buf[-1] != b'\x03'):
        buf+=ser.read(1)
        print(buf)  
    return buf

ser =serial.Serial(port=PORT,baudrate=300,bytesize=serial.SEVENBITS,parity=serial.PARITY_EVEN,stopbits=serial.STOPBITS_ONE,timeout=5)

repeat=True
while repeat:
    ser.setBaudrate(300)
    sleep(1)    
    ser.write(b'/?!\r\n')
    response=ser.readline()
    print(response)
    pattern = re.compile(r'/(...)(\d)\\@(.*)')
    m=pattern.match(response.decode("ASCII"))
    if not m:
        repeat= True
    else: repeat=False

manufacturer,speed,version=m.group(1,2,3)
speedcode=int(speed)
baudrates=(300,600,1200,2400,4800,9600,19200)
s=bytes([6,48,48+speedcode,48,13,10])  #option request data readout mode
print(s)
ser.write(s)
sleep(1)
ser.flush()
#ser.close()
#ser =serial.Serial(port=PORT,baudrate=baudrates[speedcode],bytesize=7,parity='E',stopbits=1,timeout=5)
ser.setBaudrate(9600)
#sleep(1)
#ser.setTimeout=None
frame=readframe()


ser.close()

バッファのフラッシュ、さまざまな速度でのクローズと再オープン、一時停止の挿入、バイトの代わりに行の読み取り、inWaiting() の使用など、多くのことを試しました。しばらくの間、ボーレートを切り替えるときに何もバッファリングされないのではないかと思うので、データが失われます。ところで、私は Windows で使用しています。Winpython ディストリビューション (私の職場ではそのため) のシリアル モジュールのバージョンは 2.7 です。

以下は、コミュニケーションのあり方の例です (タイミングと方向が部分的にドイツ語で記載されたコミュニケーションのトランスクリプト)。私のプログラムでは、0.2.0 がオンになっている行からのみ受信します。

Komm: 11:29:57,62 -- Teilnehmer-Name = Lokale Schnittstelle
Komm: 11:29:58,34 -- Schnittstelle   = SERIELL über COM-Port Nr: 4
Komm: 11:29:58,35 -- Komm Settings   = 300,7,E,1
Send: 11:29:58,57 -- /?!<CR><LF>
Recv: 11:29:59,80 -- /ABB5\@V4.50         <CR><LF>
Send: 11:30:00,01 -- <ACK>050<CR><LF>
Komm: 11:30:00,31 -- Komm Settings   = 9600,7,E,1
Recv: 11:30:00,57 -- <STX>0.0.0(00491465)<CR><LF>
Recv: 11:30:00,60 -- 0.9.1(112957)<CR><LF>
Recv: 11:30:00,66 -- 1.6.1(0000.00*kW)(0000000000)<CR><LF>
Recv: 11:30:00,73 -- 1.6.1*04(0000.00)(0000000000)<CR><LF>
Recv: 11:30:00,79 -- 1.6.2(0000.00*kW)(0000000000)<CR><LF>
Recv: 11:30:00,88 -- 1.6.2*04(0000.00)(0000000000)<CR><LF>
Recv: 11:30:00,91 -- 1.8.1(00000000*kWh)<CR><LF>
Recv: 11:30:00,94 -- 1.8.1*04(00000000)<CR><LF>
Recv: 11:30:00,97 -- 1.8.2(00000000*kWh)<CR><LF>
Recv: 11:30:01,02 -- 1.8.2*04(00000000)<CR><LF>
Recv: 11:30:01,05 -- 0.2.0(05F1)<CR><LF>
Recv: 11:30:01,08 -- !<CR><LF>
Recv: 11:30:01,09 -- <ETX>i Soll: i
Komm: 11:30:01,41 -- Seriell-Status  = Geschlossen

読んでくれてありがとう。どんな助けでも大歓迎です!

4

2 に答える 2

1

メーターは新しいボーレートにすばやく切り替えていると思います-ボーレート変更コマンドの5文字の送信にはおそらく0.2秒かかりますが、スリープ(1)は、メーターがおそらくすでに新しいレートで送信を開始し、データが失われるまで失われることを意味します次に、ボーレートを 9600 に変更しました。これを短くしてみてください。

于 2015-11-27T15:49:10.437 に答える