Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 使用pySerial(Delta Solar逆变器)读取RS485数据时缺少字节_Python 2.7_Pyserial_Rs485 - Fatal编程技术网

Python 2.7 使用pySerial(Delta Solar逆变器)读取RS485数据时缺少字节

Python 2.7 使用pySerial(Delta Solar逆变器)读取RS485数据时缺少字节,python-2.7,pyserial,rs485,Python 2.7,Pyserial,Rs485,太阳能逆变器(Delta RPI M6A)具有主从RS485总线。主设备每秒要求逆变器发送几次响应数据集,然后逆变器发送响应数据集。总通信集为176字节。 Raspberry Pi 3B通过FTDI FT232 USB串行(UART)IC转换器连接到此总线 Python程序用于读取总线上传输的数据。只有在没有被解释为特殊字符的字节的情况下(至少,我是这么认为的),这种方法才能很好地工作。 我首先一次读取一个字节的输入。一旦找到正确的“传输开始”序列(STX后接ACK,后接Invertrid=1)

太阳能逆变器(Delta RPI M6A)具有主从RS485总线。主设备每秒要求逆变器发送几次响应数据集,然后逆变器发送响应数据集。总通信集为176字节。 Raspberry Pi 3B通过FTDI FT232 USB串行(UART)IC转换器连接到此总线

Python程序用于读取总线上传输的数据。只有在没有被解释为特殊字符的字节的情况下(至少,我是这么认为的),这种方法才能很好地工作。 我首先一次读取一个字节的输入。一旦找到正确的“传输开始”序列(STX后接ACK,后接Invertrid=1),则需要160字节的数据集加上结束序列。最后读取的字节应为ETX(=ascii 3)

预期产出为:

我认为问题在于,如果某些字节相当于特殊字符,如转义符或换行符,那么这些字节就不会被ser.read()命令“看到”。然后,我会更快地得到ETX字节几个字节,表明中间的某个字节没有被捕获。

守则的有关部分如下:

if bytes_to_read == 1:
    raw_data = ser.read()
    pos = pos + 1;
    # print pos;
    if ord(raw_data) == 2:                                  # 2 = start of text character
        pos = 1;
        print str(pos) + ' ' + str(ord(raw_data))
    elif pos == 2 and ord(raw_data) == 6:                   # 6 = acknowledge character
        ack = True;
        print str(pos) + ' ' + str(ord(raw_data))
    elif pos == 2 and ord(raw_data) != 6:                   # 6 = acknowledge character
        ack = False;
        print str(pos) + ' ' + str(ord(raw_data)) + ' ack reset to False'
    elif pos == 3 and ack and ord(raw_data) == 1:
        bytes_to_read = 164;
        print str(pos) + ' ' + str(ord(raw_data))
elif bytes_to_read == 164:
    raw_data_byte = ser.read(164)
    print len(raw_data_byte);
    bytes_to_read = 1;
    ack = False;
    print 'got to read 164 bytes, first byte is ' + str(ord(raw_data_byte[0])) + ', last byte: ' + str(ord(raw_data_byte[163]));
    if ord(raw_data_byte[0]) == 160 and ord(raw_data_byte[163]) == 3:                     # 160 = data bytes specified by sender
        print ('ready to process ' + str(len(raw_data_byte)) + ' bytes')
        supplied_power_byte1 = bin(ord(raw_data_byte[101]))[2:].zfill(8)
        supplied_power_byte2 = bin(ord(raw_data_byte[102]))[2:].zfill(8)
捕获的字节稍后将被处理以允许写入数据库

我一直在尝试ser.read()和ser.readline(),结果相同

如果有任何能为我指明正确方向的暗示,我将不胜感激

谢谢,
Bram

解决方案是使用cli命令将串行接口的所有特殊字符设置为“未定义”:

pi@raspberrypi:~ $ stty -F /dev/RS-485 intr ^-
其中“/dev/RS-485”是指向真实USB端口的符号链接,“intr”是特殊字符名称的示例。对每个特殊字符执行此操作时(它们都可以添加到上述cli命令),端口设置如下所示:

pi@raspberrypi:~ $ stty -F /dev/RS-485 -g
1400:4:cbe:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
要以更人性化的格式查看设置,请使用命令

pi@raspberrypi:~ $ stty -F /dev/RS-485 -a

所有字节现在都按预期输入。

解决方案是使用cli命令将串行接口的所有特殊字符设置为“未定义”:

pi@raspberrypi:~ $ stty -F /dev/RS-485 intr ^-
其中“/dev/RS-485”是指向真实USB端口的符号链接,“intr”是特殊字符名称的示例。对每个特殊字符执行此操作时(它们都可以添加到上述cli命令),端口设置如下所示:

pi@raspberrypi:~ $ stty -F /dev/RS-485 -g
1400:4:cbe:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
要以更人性化的格式查看设置,请使用命令

pi@raspberrypi:~ $ stty -F /dev/RS-485 -a
所有字节现在都按预期输入