【问题标题】:Protocol for Serial Communication in binary - getting unexpected response二进制串行通信协议 - 得到意外响应
【发布时间】:2020-01-06 20:48:13
【问题描述】:

我正在尝试在 Raspberry 上使用 Python3 与串行设备进行通信。协议如下:

  1. 主机发送命令字节(包含地址和数据类型)
  2. 设备回显命令字节
  3. 主机发送操作数字节(更多数据类型信息)
  4. 设备回显操作数字节以及数据的第一个字节
  5. 主机回显数据的第一个字节。设备发送第二个字节的数据。重复直到 5 个总数据字节

设备应该只接收和发送二进制文件(根据我一直在参考的过时手册),但是当我要求第二个数据字节时,我得到“\t”或其他一些奇怪的字符。命令、操作数和第一个数据字节似乎都可以正常工作。但在那之后,我开始得到一些意想不到的角色。

设备实际上是否以二进制以外的方式进行通信?

我的编码天赋仍处于初级阶段,因此请忽略过度使用打印命令。我是新手,请随意挑剔..

import serial
import time
import binascii

ser = serial.Serial(
    port='/dev/ttyUSB0',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
    timeout = 2)

command=b"\x92"
operand =b"\x02"
sleepy = 0.2
data = bytearray()



while True:
    ser.write(command) #send command byte
    time.sleep(sleepy)
    print(ser.read(1)) #recieve command byte
    time.sleep(sleepy)


    ser.write(operand) #send operand byte
    time.sleep(sleepy)
    echo = ser.read(2)#recieve operand byte & first data byte
    print(echo)        
    time.sleep(sleepy)
    data.append(echo[1])

    ser.write(bytearray([echo[-1]])) #send first data byte echo
    time.sleep(sleepy)
    echo = ser.read(10) #recieve second data byte
    print(echo)
    time.sleep(sleepy)
    data.append(echo[-1])
    print(echo[-1])

    ser.write(bytearray([echo[-1]]))    #send second data byte echo
    time.sleep(sleepy)
    echo = ser.read(10) #recieve third data byte
    print(echo)
    time.sleep(sleepy)
    data.append(echo[-1])
    print(echo[-1])

    ser.write(bytearray([echo[-1]]))    #send third data byte echo
    time.sleep(sleepy)
    echo = ser.read(10) #recieve fourth data byte
    print(echo)
    time.sleep(sleepy)
    data.append(echo[-1])
    print(echo[-1])

    ser.write(bytearray([echo[-1]]))    #send fourth data byte echo
    time.sleep(sleepy)
    echo = ser.read(10) #recieve 5th data byte
    print(echo)
    time.sleep(sleepy)
    data.append(echo[-1])
    print(echo[-1])
    print(data)




ser.close()

例如,当我运行它时,我得到数据数组“(b'\x04\x08hT^')”。 我总是得到第一个 \x04 但之后的字符是随机的。

【问题讨论】:

    标签: python raspberry-pi binary pyserial serial-communication


    【解决方案1】:

    我已经让这个程序工作了。我仍在获取包含一些意外字符的数据,但使用 binascii.hexlify 后跟 "{:08b}".format(int(c[1], base=16)) 将其转换为我需要的 8 位二进制文​​件。下面来看看似乎有效的方法。就上下文而言,该程序从水分分析仪收集数据。所以底部的数学是将 40 位二进制转换为浮点值。

    def get_h20():
    data = bytearray()
    echo = bytearray()
    command=bytearray([146])
    operand =bytearray([1])
    sleepy = 0.02
    
    ser = serial.Serial(
    port='/dev/ttyUSB1',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
    timeout = 0)
    
    data = bytearray()
    ser.write(command) #send command byte
    time.sleep(sleepy)
    echo = ser.read(1) #recieve command byte
    data = data + echo
    
    
    ser.write(operand)
    time.sleep(sleepy)
    echo = ser.read(2)
    data = data + echo
    
    ser.write(bytearray([echo[-1]]))
    time.sleep(sleepy)
    echo = ser.read(1)
    data = data + echo
    
    ser.write(bytearray([echo[-1]]))
    time.sleep(sleepy)
    echo = ser.read(1)
    data = data + echo
    
    ser.write(bytearray([echo[-1]]))
    time.sleep(sleepy)
    echo = ser.read(1)
    data = data + echo
    
    
    ser.write(bytearray([echo[-1]]))
    time.sleep(sleepy)
    echo = ser.read(1)
    data = data + echo
    return(data)
    
    ser.close()
    

    将原始 h2o 数据转换为 ppb

    def raw_to_ppb(数据):

    raw_hex = str(binascii.hexlify(data[2:]))
    c = [raw_hex[i:i+2] for i in range (0, len(raw_hex), 2)]
    try:
        byte1 = "{:08b}".format(int(c[1], base=16))
        byte2 = "{:08b}".format(int(c[2], base=16))
        byte3 = "{:08b}".format(int(c[3], base=16))
        byte4 = "{:08b}".format(int(c[4], base=16))
        byte5 = "{:08b}".format(int(c[5], base=16))
    
        h20_bin = byte1+byte2+byte3+byte4+byte5
    
        m1 = h20_bin[14:16]
        m2 = h20_bin[17:24]
        m3 = h20_bin[25:32]
        m4 = h20_bin[33:40]
        m = m1+m2+m3+m4
    
        mantissa =      (int(m[0])*2**22+int(m[1])*2**21+int(m[2])*2**20+int(m[3])*\
                    2**19+int(m[4])*2**18+int(m[5])*2**17+int(m[6])*2**16+int(m[7])*\
                    2**15+int(m[8])*2**14+int(m[9])*2**13+int(m[10])*2**12+int(m[11])*\
                    2**11+int(m[12])*2**10+int(m[13])*2**9+int(m[14])*2**8+int(m[15])*\
                     2**7+int(m[16])*2**6+int(m[17])*2**5+int(m[18])*2**4+int(m[19])*\
                     2**3+int(m[20])*2**2+int(m[21])*2**1+int(m[22])*2**0)/8388608
    
        e1 = h20_bin[5:8]
        e2 = h20_bin[9:14]
        e = e1+e2
        exponent = int(e,2)
        sign = (-1)**(int(h20_bin[4],2))
    
        h20_ppb = sign*(2**(exponent-127))*(1+mantissa)
    
        return(str(h20_ppb))
    except:
        pass
    

    我仍然想进一步了解从分析仪收到的数据格式。如果我从 get_h2o 函数打印数据变量,那么我仍然会得到奇怪的 "b'\x04\x08hT^" 响应......但 python 似乎知道如何处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2012-01-21
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      相关资源
      最近更新 更多