簡體   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