从PySerial中读取/转换类似字节的十六进制对象

时间:2018-05-16 11:25:29

标签: python serial-port hex pyserial

我一直试图从各种相关的线程中拼凑出这个问题的解决方案,但我似乎无法让他们一起工作。我发现很多帖子似乎都在处理ascii /二进制值,而我的问题与翻译十六进制值有关。我是Python的新手,而且我一直在努力学习语法。

系统:Windows 10. Python 3.6。 IDE是Spyder。

问题:我通过仅以十六进制通信的RS232串口与设备通信。我已经设法使用pySerial模块成功地向设备发送命令并收到回复,但我无法弄清楚如何将回复转换为可解析的格式,以用于我工作流程的下一步。 / p> 到目前为止

代码:

import serial
import sys

port = "COM3"
baud = 9600
bytesize=8
parity='N'
stopbits=1
timeout=10 # this timeout is large due to another problem I'm having, but 
             didn't want to complicate this post with.

# Commands

# open the serial port
ser = serial.Serial(port, baud, bytesize, parity, stopbits, timeout)

if ser.isOpen():
    print(ser.name + ' is open...')

# Query. This sends an 'are you awake' message to the device.
ser.write(bytearray.fromhex("23 00 00 80 B0 00 00 01"))        

上述命令作为类似字节的对象被发送到设备"根据Python,它显示为格式:b' \ x23 \ x00 \ x00 \ x80 \ xb0 \ x00 \ x00 \ x01'

print('Receiving...')

# wait for timeout before displaying what was read. The device returns a 
variable number of bytes each time it communicates, and I haven't figured 
out a way to handle that yet.
    out = ser.read()

print(out)
ser.close()
print(port+' is closed.')

这就是我的问题所在。 ser.read()返回另一个类似字节的对象。例如,从上面的ser.write()命令:b' \ x13 \ x11'。这些实际上是我期望从这个命令中得到的值(" 13"" 11"的十六进制值),我只是不知道如何处理它们现在

我想要做的是解析返回的十六进制字符的长字符串(当我发送一个非查询命令时,这将是250多个字符,由" \ x"分隔)到单个数组元素中然后我可以操纵/替换/转换回十进制整数值。我最终想要将这些十六进制值转换为十进制等值并将这些十进制值写入CSV文本文件,以便稍后我可以绘制值。

我已尝试过(这些不是顺序命令,它是尝试命令的列表):

out = ser.readline()    

out.split("\x")
out.split("\")
out.split("\\")

out_string = out.decode("utf-8")

binascii.hexlify(out)
binascii.hexlify(bytearray(out))

...and others I can't remember.  

请您提供任何帮助,我们将不胜感激。这感觉应该是一件简单的事情,而我糟糕的计算机内存不足,我打开了所有标签。提前感谢任何回复的人。

1 个答案:

答案 0 :(得分:0)

你的输出是一个字节序列。 如果您只想读出特定数量的字节,可以使用

out = ser.read(n) # where n is the number of bytes you want e.g. n = 8

你的出局应该是这样的:

out = b'\x21\x45\xed\xca\xfe' # I chose random values here

所以要获得你可以做的int列表:

for b in out:
  int_list.append(b)

int_list = [b for b in out]

如果你想要字节对,你可以做(​​不确定这是否是最好的方法):

for i in range(0,len(out),2): # loop to every second value
  pair = out[i].to_bytes(1,'little')+out[i+1].to_bytes(1,'little') # the first argument refers to the number of bytes and the second to the endianess.
  print(pair)

这为我产生了以下内容:

>>> b = b'\x32\x34\xe8\x90\x32\xab'
>>> for i in range(0,len(out),2):
...     pair = out[i].to_bytes(1,'little')+out[i+1].to_bytes(1,'little')
...     print(pair)
...
b'24'
b'\xe8\x90'
b'2\xab'

如果您搜索特定的错误字节,例如你可以做e = b'\ xff'

if e in out:
  do_substitute(e with your byte value)