【问题标题】:Missing bytes when reading RS485 data using pySerial (Delta Solar Inverter)使用 pySerial(Delta Solar Inverter)读取 RS485 数据时缺少字节
【发布时间】:2016-09-18 19:42:23
【问题描述】:

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

Python 程序用于读取总线上正在传输的数据。仅当没有被解释为特殊字符的字节时(至少,我认为),这才有效。 我首先一次读取输入 1 个字节。一旦找到了正确的“传输开始”序列(STX 后跟 ACK 后跟inverterID=1),那么就需要 160 字节的数据集加上一个结束序列。最后读取的字节应该是 ETX (= ascii 3)。

预期的输出是: Screenshot of expected output

我认为问题在于,如果某些字节相当于转义或换行等特殊字符,那么 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(),结果相同。

如果有任何提示可以为我指明正确的方向,我将不胜感激。

谢谢, 布拉姆

【问题讨论】:

    标签: python-2.7 pyserial rs485


    【解决方案1】:

    解决方案是使用 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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 2018-09-14
      • 2013-01-04
      • 1970-01-01
      相关资源
      最近更新 更多