2016-09-18 222 views
1

太阳能逆变器(Delta RPI M6A)具有主从RS485总线。主站每秒要求变频器发送一次响应数据组,然后由变频器进行响应。总的通讯组为176字节。 使用FTDI FT232 USB串行(UART)IC转换器将Raspberry Pi 3B连接到此总线。使用pySerial读取RS485数据时丢失字节(Delta Solar Inverter)

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(),结果相同。

我将不胜感激任何暗示将指向正确的方向。

谢谢, 的Bram

回答

0

的解决方案是设置串行接口到 '未定义' 的所有特殊字符,使用CLI命令:

[email protected]:~ $ stty -F /dev/RS-485 intr ^- 

其中 '的/ dev/RS-485'是一个真正的USB端口的符号链接,'intr'是特殊字符名称的例子。当这对每个特殊字符进行(他们都可以添加到上述CLI命令),端口设置是这样的:

[email protected]:~ $ 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 

要看到更人性化的格式设置,使用命令

[email protected]:~ $ stty -F /dev/RS-485 -a 

所有字节现在按预期进入。