繁体   English   中英

Python解析固定格式的串行十六进制字符串

[英]Python parsing serial hex string with fixed format

我已通过一个特定的请求数据包通过串行与一个简单的设备成功通信,并且收到了固定格式的返回数据包。 我从python开始,所以我可以在多种设备上使用它,我只真正习惯了PHP / C。

例如,我将以下内容发送为十六进制:

12 05 0b 03 1f

作为回报,我得到

12 05 0b 03 1f 12 1D A0 03 18 00 22 00 00 CA D4 4F 00 00 22 D6 99 18 00 70 80 00 80 00 06 06 00 00 D9

我知道数据包是如何构造的,前5个字节是发送的数据。 接下来的3个字节是ID,数据包长度和响应代码。 它在我的代码中在这里评论:

import serial, time

ser = serial.Serial(port='COM1', baudrate=9600, timeout=0, parity=serial.PARITY_EVEN,      stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)

while True:
    # Send The Request - 0x12 0x05 0x0B 0x03 0x1F
    ser.write("\x12\x05\x0B\x03\x1F")
    # Clear first 5 bytes (Original Request is Returned)    
    ser.read(5)

    # Response Header (3 bytes)
    # - ID (Always 12)
    # - Packet Length (inc these three)
    # - General Response (a0 = Success, a1 = Busy, ff = Bad Command)
    ResponseHeader = ser.read(3).encode('hex')
    PacketLength = int(ResponseHeader[2:4],16)
    if ResponseHeader[4:6] == "a0":
        # Response Success
        ResponseData = ser.read(PacketLength).encode('hex')
        # Read First Two Bytes        
        Data1 = int(ResponseData[0:4],16)
        print Data1
    else:
        # Clear The Buffer
        RemainingBuffer = ser.inWaiting()
        ser.read(RemainingBuffer)

time.sleep(0.12)

为了简单起见,我只是尝试读取实际响应的前两个字节(ResponseData),应该给我十六进制的0318。然后,我想将其输出为十进制= 792。 该程序应在连续循环中运行。

数据包中的某些变量是一个字节,有些是两个字节。 尽管到目前为止,我只是遇到一个错误:

ValueError: invalid literal for int() with base 16: ''

我猜这是由于我设置的数据/变量的格式,所以不确定我是否正在以正确的方式进行操作。 我只想读取字节形式的返回HEX数据,并能够在单个级别上访问它们,因此我可以根据需要格式化/输出它们。

有一个更好的方法吗? 非常感谢。

我建议使用struct模块读取二进制数据,而不是使用字符串函数将其重新编码为十六进制并尝试解析十六进制字符串。

就像现在的代码一样,您通过网络发送二进制(非十六进制)数据,并从设备接收回二进制(非十六进制)数据。 然后,您将二进制数据转换为十六进制,仅将其再次转换为Python变量。

让我们通过使用struct.unpack跳过额外的转换步骤:

# UNTESTED
import struct
...
while True:
    # Send The Request - 0x12 0x05 0x0B 0x03 0x1F
    ser.write("\x12\x05\x0B\x03\x1F")
    # Clear first 5 bytes (Original Request is Returned)    
    ser.read(5)

    # Response Header (3 bytes)
    # - ID (Always 12)
    # - Packet Length (inc these three)
    # - General Response (a0 = Success, a1 = Busy, ff = Bad Command)
    ResponseHeader = ser.read(3)
    ID,PacketLength,Response = struct.unpack("!BBB", ResponseHeader)
    if Response == 0xa0:
        # Response Success
        ResponseData = ser.read(PacketLength)
        # Read First Two Bytes        
        Data1 = struct.unpack("!H", ResponseData[0:2])
        print Data1
    else:
        # Clear The Buffer
        RemainingBuffer = ser.inWaiting()
        ser.read(RemainingBuffer)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM