使用MODBUS协议与传感器、工控屏对接时碰到的问题
当控制器作为可编程逻辑器件用于工控系统时,其需要与各种不同的传感器对接,
同时需要与工控屏对接,以提供人机界面与用户进行交互;
对接的传感器功能多种多样,
有检测环境的温、湿度、二氧化碳、光照等的传感器。
有检测电压、电流、功率等的智能电表。
有用于智能灌溉用于检测雨量和水量的传感器。
...
控制器与MODBUS设备的连接框图
从传感器读取的数据的数据格式
不同功能的传感器,其数据类型也可能不相同的。
控制器作为MODBUS主模式从作为从模式的传感器读取到数据之后,需要考虑采用什么样的数据格式对读取到的数据进行解析、处理、判断。
大部分情况下,数据是16位的无符号,但是也有一些特别的,比如:
- 温度是16位的有符号数,一般温度会保留一位小数,比如从温度传感器读到的数据为65526时。‘温度并不是6552.6°C,转为16位有符号数为-10,对应温度为-1°C。
- 有一次,帮客户对接RS485智能电表时,从智能电表读取到的有功功率出现了6000多kw的情况。
经排查,也是因为把本该是有符号数当作无符号数处理,另外智能电表在计算有功功率时没有做下限判断或者取绝对值处理,当小于0时置为0。没有取绝对值处理,万一用户将电缆穿过电流互感器时,穿错了方向,导致读到的数据都是负数。需要采集数据方做取绝对值的处理。
- 环境光照的动态范围很大,最低可能到1lux,最高可能到10*9次方lux,如下:
黑夜:0.001—0.02lux;
月夜:0.02—0.3lux;
阴天室内:5—50lux;
阴天室外:50—500lux;
晴天室内:100—1000lux;
夏季中午太阳光下的照度:约为10*9次方;
因此,光照的数据格式为32位的无符号数。
- 有些水量传感器的数据为16位或者32位的BCD数。
以上,从传感器读取到的数据需要根据传感器的数据格式定义进行数据转换。
工控屏和传感器接到同一个RS485总线
一般情况下,控制器工作于MODBUS主模式,传感器工作于MODBUS从模式。
控制器定时按照地址轮流查询传感器,读取数据并进行格式转换处理。
而在与工控屏对接时,工控屏需要工作于MODBUS主模式,控制器工作于MODBUS从模式。
工控屏定时查询控制器的数据进行显示,同时当用户进行参数设置时,通过MODBUS的写操作命令06或16向控制器写数据。
由于一个RS485总线只允许存在一个MODBUS主设备,
当控制器需要同时对接传感器和工控屏时,需要控制器提供两个RS485总线,一个RS485总线连接传感器,另一个RS485总线连接工控屏。
选择带两个RS485接口的控制器会增加客户的成本。
因此,我对控制器做了一些改造,让工控屏也工作于MODBUS的从模式。
主要步骤为:
1) 将工控屏设置为MODBUS从模式。
2) 通过MODBUS的读命令03定时读取一段地址的数据
比如0x0000-0x0009共10个地址的数据。
读取的数据主要是用户通过屏幕的设置参数,比如温控器的启动温度,LED灯光控制的启动光照值等。
虽然,屏幕可能也有对设置数据的断电记忆功能,但是我还是利用其中一个地址的数据来判断是否被初始化,实现通过控制器对设置数据永久断电存储。
比如从屏幕读到的地址0x0000的变量值不为0xAA55,则把控制器存储的地址0x0000-0x0009的数据通过0x10命令写到屏幕,其中0x0000 地址的数值为0xAA55,实现对屏幕数据的初始化;
3) 通过MODBUS的批量写命令0x10定时将控制器的状态,从传感器读到的数据等写入到工控屏,供工控屏显示使用。
采用这种方法实现的功能,有两个弊端,
实时性
跟工控屏进行数据交换,是跟其它传感器一起轮询实现的,实时性稍微差点,特别是当接了比较多的传感器时,实时性会受比较大的影响。
我最多帮客户连接过5个传感器,将波特率设置到19200bps,超时时间按3.5个字符时间处理,大概做到了1s以内响应,也基本上不影响客户体验。
数据冲突
当屏幕和用户程序同时要控制一个变量就有问题,
因为控制器定时从屏幕读取设置值,而不知道道是否为用户的真实操作。
在控制器对变量值改写之后,又从屏幕读取到旧的设置值,控制器无法判断是否为用户通过屏幕改写,而只能将旧的设置值覆盖控制器的改写值,所以造成了冲突。
如果屏幕是主的话,只有用户操作了,才会往控制器写数据,则不会有冲突的问题。
两个RS485接品的系统框图