首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pySerial (Delta Solar Inverter)读取RS485数据时缺少字节

使用pySerial (Delta Solar Inverter)读取RS485数据时缺少字节
EN

Stack Overflow用户
提问于 2016-09-19 03:42:23
回答 1查看 648关注 0票数 1

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

Python程序用于读取总线上传输的数据。只有当不存在被解释为特殊字符的字节时(至少,我是这么认为的),这种方法才能正常工作。我首先一次读取1个字节的输入。一旦找到了正确的“传输开始”序列(STX、ACK和inverterID=1),则预期160字节的数据集加上结束序列。读取的最后一个字节应为ETX (= ascii 3)。

预期输出为:Screenshot of expected output

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

代码的相关部分是:

代码语言:javascript
复制
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(),都得到了相同的结果。

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

谢谢,布拉姆

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-04 02:01:08

解决方案是使用cli命令将串行接口的所有特殊字符设置为'undefined‘:

代码语言:javascript
复制
pi@raspberrypi:~ $ stty -F /dev/RS-485 intr ^-

其中'/dev/RS-485‘是实际USB端口的符号链接,'intr’是特殊字符名称的示例。当对每个特殊字符执行此操作时(它们都可以添加到上面的cli命令中),端口设置如下所示:

代码语言:javascript
复制
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

要以更友好的格式查看设置,请使用以下命令

代码语言:javascript
复制
pi@raspberrypi:~ $ stty -F /dev/RS-485 -a

所有字节现在都像预期的那样进入。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39561906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档