刚来公司上班一个月,任职协议开发。经理着手让我写什么电总协议,UPS协议,电源柜协议等等,这些产品协议有时格式是差不多的,只是不同厂家会根据标准协议,在现实自己产品的功能时方式有点不一样。看的不是很多,照我自己的理解,协议,简单来说就是通讯的双方之间约定的一种规则。即是以什么的数据格式进行询问和回应,出错之后又以什么方式处理。上面提到的几个协议相对来说是上层,其会基于什么样的物理层传输,物理层也有它本的协议,主要用来规定机械的,电气等特性。这些厂家都会在通讯协议书中说明。
最近要求根据ModBus协议写个精密空调的数据采集程序,因为客户的空调最近升级了,原有的程序不能正常工作,要求修改程序。本以为有原程序代码来看,谁知原程序不是公司写的。打电话要求空调代理商发个协议说明书过来,一看只是一个Execl样的表格,密密麻麻十几页。我看了知道这不是原样的通讯协议说明书,只是个简洁的寄存器地址和功能码表。如果是已经知道他们厂家的空调通讯协议采用的实现方式,现在这个表就够了。但我才开始。打电话再要,他们也不懂。上网找,空调是德国产的,没找到。
最后我找来了ModBus标准协议说明来看,再找其它空调厂家的协议来参考。知道个大概了。但是要真正能完整的采样数据,还得去现场调试。好在客户的空调就是在市区内的。以下我简要的介绍一下ModBus协议:
MODBUS 是MODICON公司最先倡导的一种的通讯规约,Modbus可在编程控制器之间可相互通讯,也可与不同网络上的其他设备进行通讯。常用的MODBUS 通讯规约有两种,一种是MODBUS ASCII,一种MODBUS RTU。一般来说,通讯数据量少而且主要是文本的通讯则采用MODBUS ASCII规约,通讯数据数据量大而且是二进制数值时,多采用MODBUS RTU规约。
在传输信息时,尽管网络通讯方法是对等的,但Modbus协议仍采用主从方式,若一台控制器作为主机设备发送一个信息,则可从一台从机设备返回一个响应,类似,当一台控制器接受信息时,它就组织一个从机设备的响应信息,并返回至原发送信息的控制器。
查询响应周期:
以下我介绍的是MODBUS RTU规约格式:
一 格式:
查询命令格式:
这里我说明一下:
根据我现场调试发现,每个寄存器值对应二个字节数据。上面命令格式“读取数据个数”应该是指读取寄存器个数,因为值是存放在寄存器的,状态量通常用0,1表示。读一个就够了。如果是功能码03,04返回的值有int,float型,刚需要读取2个寄存器,2×2=4就刚好。
正常回应格式:
异常应答返回
注:ModBus异常响应的异常码值表示如下:
异常码 描述 响应解释
01 无效功 变送器不允许执行收到的功能
02 无效地址 数据栏中的地址是不允许的
03 无效数据 数据栏中的数据是不允许的
06 忙 收到的消息没错,但从机正在执行一个长的程序命令 .
二 功能码解释:
从机会根据收到的功能码执行相应动作之后返回响应数据。ModBus的功能码如下:
根据我现场调试后,我才能比较正确的理解命令格式:其01,02功能码读取的响应信息是比特值位,03,04功能是int,float..等值,要最后取得这些值还得处理。比如是float型的,是由4个Byte的数据构成的,而要得到这个float型的正确值,你得根据所在的系统大端或小端方式进行转换才正确。
例如:
例一:
我要查询空调现在的开关机状态,要知道的是:空调设备地址(0x01),开关机是状态位(0表示关,1表示开),所以用功能码01或02.读取寄存器地址(假设是1013),读取的数据位数01(1位就可以了)。以上这个值厂家都会有说明的,就像我上面提到的Excel表类似一样。
发送的查询命令:(都是十六进制)
01 02 03 F5 00 01 ― ― (后面的――表示CRC值,自己计算。)
假设空调是处于开机状态,能正确执行的响应就是如下:
01 02 01 01 ――
例二:
我要读取当前空调的显示温度(float值型)。
功能码03或04.寄存器地址从2340-2341(2个寄存器就对应2*2=4个字节)。
发送查询命令:
01 04 09 7E 00 02 ――
假设空调温度是21摄氏度。能正确执行的响应就是如下:
01 04 04 41 A8 00 00 ――
把4个数据值:41 A8 00 00 按照小端方式(VC下)倒序一下就可以强行用float型读取就可以了得到值21了。
调试这次ModBus协议,我和同事Z一共去了三次,好在老板不存,要不就被K了。
第一次去,用我自己猜测空调厂家的Modbus协议的程序来执行。结果有问题,上来的数据全是0.之后我一条条测试,根据其返回的数据码,我知道执行是正确。但采上来的温度数据是0。空调是开机状态,但采上来的状态位值也是0(0表示关机)。我对照了资料检查几次,是没错。之后我们再测试另外一台,情况也一样。时间不停的流逝,急了,打电话给代理厂家反应问题。他最后的回答是不可能,升级完后他们测试有值出来的。我又打电话回公司请求帮忙,可惜公司里只有一个同事以前接触过,也爱莫能助。折腾了之后无奈,最后没结果还是回去了。
第二次去之前,我反醒一下,返回数据码显示能正确执行。却没有数据。说明程序的整体思路是可以的。问题应该是其它方面。经过同事Z的对代理厂家施压并强烈要求之下,代理厂家给了他们的测试软件。
用他们软件去现场测试,温度数据也是0,和上次结果一样。同事Z 急了问我是否确定他空调有问题,我只说大有可能。于是打电话质问代理厂家,说他设备有问题。经过对那两台大型空调设置参数后再重起。数据上起来,采样也OK了。只是后来轮到我们设备有问题。也快下班了,只好改天再来一次。
第三次,经理本来说程序既然可以就不用我去了。但在同事Z要求下还是一起去。去了才知道,我的程序还不完善,有些数据采样上来没有正确处理,上报到监控台会出错。主要表现在,对读取数据的个数没有正确理解,还有一个就是转成float型出现错误。最后我要求自己冷静下来逐步测试终于可以了。但接下来又出错问题,导致我们俩连中年饭都没有吃,因为客户要求今天下午5点前完成,第二天就是国庆节了。问题就是厂家空调的第二台监控电路板有问题,通过它自己的接口采样上来的数据不稳定,在变化很大。我们询问厂家工程师后,解决方法通过正常第一台的空调以级联方式采样。设备这方面工作是同事Z处理,整个下午在请求帮助的过程中把我们俩的电话卡都快打光了,最后换了设备芯片,对RS485/RS232接口转换。客户验收后总算完成了。马上闪人到楼下的真功夫饱食了一顿。
经过这个现场调试后明白了一些。
1:要做好充分准备,一些对应小调试工具要准备后,或自己编写或到网上去查找。
2:遇到问题要冷静下来。必要的打话电话去询问设备情况。这涉及到几个公司的合作问题,谈话有点技巧。
3:这次拿到厂家的调试软件来测试后,就更能肯定设备存在异常。通过询问他们工程师就可以在异常的设备中找到另一种方法来解调他们设备的问题。
4:良好的沟通可以让进度加快很多。
---小结工作知识点