读取python中具有未知数据长度的串口

时间:2016-07-11 12:56:37

标签: python

您好我正在尝试从配置为串口的pic32微控制器读取数据。

pic32发送长度为“二进制”的数据变量(长度为14到26个字节)。我想读入数据并将这些位分开,然后将它们转换为十进制等效值。

import serial
import csv

#open the configuartion file
with open('config.txt') as configFile:
   #save the config parameters to an array called parameters
   parameters = configFile.read().split()

#Function to Initialize the Serial Port
def init_serial():
    global ser
    ser = serial.Serial()
    ser.baudrate = 9600
    ser.port = 'COM7'
    ser.timeout = 10
    ser.open()
    if ser.isOpen():
        print ('Open: ' + ser.portstr)

#call the serial initilization function
init_serial()

#writes the lines from the config file to the serial port
counter = 0
while counter<4:
    ser.write(chr(int(parameters[counter])).encode('utf-8') + chr(int(parameters[counter+1])).encode('utf-8'))
    counter = counter + 2

#opens the csv file to append to 
resultsFile = open('results.csv', 'wt')

#writes the titles of the four columns to the csv file
resultsFile.write("{} {} {} {}\n".format('ChannelAI', 'ChannelAQ', 'ChannelBI', 'ChannelBQ')) 


count=0
while count < 10:    

    #read from serial port
    incoming = ser.read(26)

    #decodes incoming bytes to a string
    incoming = incoming.decode('cp1252')


    #will select element 4, 5 & 6 from incoming data
    channelAIstr = incoming[4:6]
    #converts slected elements to an integer
    channelAI=int(channelAIstr, 16)

    channelAQstr = incoming[7:10]
    #channelAQ=int(channelAQstr, 16)

    channelBIstr = incoming[10:13]
    #channelBI=int(channelBIstr, 16)

    channelBQstr = incoming[13:16]
    #channelBQ=int(channelBQstr, 16)

    #writes to csv file
    resultsFile.write("{} {} {} {}\n".format(str(channelAI), str(channelAQ), str(channelBI), str(channelBQ)))             

    count = count + 1

#close the file to save memory
resultsFile.close()

我在读取和转换串口的位时遇到了一些麻烦。如何做任何帮助将不胜感激。

我知道我正在正确读取串口,并且正在获取类似于“\ x00 \ x7f \ x7f”的数据作为示例。然后我想将这个3字节长的字符串转换为整数。

1 个答案:

答案 0 :(得分:0)

我不确定您如何确定数据是14或26字节长还是介于两者之间。

在所有情况下,您可能希望使用包装IO的包装类。

在每次数据请求时,您可以让包装器读取一定数量的字节或所有可用的字节,直到您有足够的数据进行解码。然后包装器对它们进行解码并将它们作为元组返回。

这是关于如何进行的第一个猜测;我没看到你的代码在哪里遇到麻烦。

但这只是一种合成糖和一种更高级的程序状态。

首先,让我们找出更明显的事情:你似乎以错误的方式将数据分开。你的代码

#will select element 4, 5 & 6 from incoming data
channelAIstr = incoming[4:6]

不适合彼此:索引[4:6]表示4包含到6独占。如果你真的想要4,5和6,你必须写[4:7]

下一步是将其转换为整数。如果你有\x00\x7f\x7f,这可能意味着很多事情:

  • 如果是24位整数,则可以是小端或大端。在第一种情况下,它是0x7F7F00,在第二种情况下是0x007F7F

    可以处理这些案件

    >>> a='\x00\x7f\x7f'
    >>> import struct
    >>> struct.unpack("<I", a+"\x00")[0]
    8355584
    >>> 0x7f7f00
    8355584
    >>> struct.unpack(">I", "\x00"+a)[0]
    32639
    >>> 0x7f7f
    32639
    
  • 如果它是一种不同类型的数据格式(可能是一些浮点?),那么你必须更详细地了解这些数据的含义。

所以,如果我对整数解决方案是正确的,只需执行

中的任何一个
channelAI = struct.unpack(">I", "\x00" + channelAIstr)[0]
channelAI = struct.unpack("<I", channelAIstr + "\x00")[0]