今天讲一讲modbus

身为一只电子狗,竟然在最近的实验室项目中才第一次接触modbus通信协议,甚是惭愧。在此把自己一点学习的心得分享一下。

 

如果你上百度去查modbus,你会查到这样一段话:ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。

 

看不懂吧?没事我也不懂。

 

我觉得modbus最奇葩的一点,就是我在百度上打开了数十个网页,还是看不懂这个通信协议的原理。应该不是我傻吧?于是我为了证明自己不傻,转头求助google,终于了解了modbus最精髓的几点:

(1)它是一个串口通信协议

    哦,串口啊,这就有个底了。

(2)它是一个应用层协议。

    说到应用层,这就需要复习一下ISO提出的OSI模型。呃,其实也不用记得太清楚,至少应用层和物理层差的很远还是得记住。

今天讲一讲modbus

这个图大致体现了不同协议在网络架构中的地位。所谓的modbus协议,是在最高的应用层,也就是在两个应用之间交换数据,而底层如何传输,它完全不管。在最低的物理层,可以采用RS232协议,也可以采用RS485协议,或者采用以太网传输协议。在这里采用什么具体的物理协议,都跟应用层的modbus协议细节无关。

很多网页上把modbus, RS485还有TCP/IP混在一起,让人无法理解。

在我实验室的项目中,用到了两种modbus连接,一种是modbus tcp,就是通过以太网连接进行数据传输,而另一种是modbus rtu,物理层通过RS485协议传输。所以modbus tcp中利用的是socket和网线连接,而modbus rtu则使用了ttyUSB0接口和USB转485接线。

 

(3)它是一个总线协议,连接Master和Slave。

这里注意,一般在较高的应用层,我们会用Client/Server模型来描述两个连接的应用,而在底层设备上,我们则会用Master/Slave,就是主从来区分底层连接中的主动与否。在ICS课上讲过,Client/Server的区别仅在谁发起连接,而在通信过程中两者完全对等。Master/Slave有点相似又有点不同——Master对应Client,负责发起连接;但在整个连接中,Master都处在绝对的主导地位,Slave对Master发出的命令进行响应。

这一点在百度相关网页上也少有说清楚的。

 

总线,主从,这就让我们联想到熟悉的SPI和I2C协议。毕竟,在一条总线上连接多个设备,想把通信做的高效,协议都长的差不多——读写寄存器嘛。

modbus协议也是这样。它的报文结构大致如下:

今天讲一讲modbus

Address field用来“点名”——呼唤哪个Slave。Function code则是表明来意,比如是要下达指令还是要看看Slave的状态。而Data部分就是有用的数据了,比如读取寄存器的起始地址,读取信息的数量等。最后跟CRC或者LRC校验。CRC和LRC的区别还没有搞懂,就不在这里装逼了。

 

与网络协议中的数据包头和尾相似,只有中间的部分是实际有用的数据,而头尾都是用来辅助传输的。

 

(4)读写寄存器

至于具体的寄存器地址,不同设备不同,需要仔细阅读技术手册。这就是为什么计算机系的室友在读paper的时候我抱着一堆技术手册,大家都生无可恋。

 

具体实现:

如前所述,实验室项目中用到的是modbus tcp和modbus rtu,用来控制ur3机械臂。幸而,google上都能查到这两种连接的python代码,我所做的只是把python改成C,移植到Linux平台上而已。

注意modbus rtu中,虽然linux有提供modbus.h的库,但不是很必要。可以直接模仿串口通信进行了通信速率、停止位、校验位等设定,只是有些设定比如注释掉的options.c_cflag |= CLOCAL | CREAD需要去掉,否则不能正常通信。

 

系统环境:Ubuntu 16.04

可以查看我的Github源代码https://github.com/Orienfish/cautious-palm-tree

 

参考网页:

1、ur3通过modbus tcp读取寄存器python代码

http://www.zacobria.com/universal-robots-knowledge-base-tech-support-forum-hints-tips/knowledge-base/modbus-registers-input-and-output-handling-via-port-502/

2、ur3控制面板上配置

https://www.universal-robots.com/how-tos-and-faqs/how-to/ur-how-tos/modbus-communication-16357/

3、ur3 modbustcp指令和寄存器详解

https://www.universal-robots.com/how-tos-and-faqs/how-to/ur-how-tos/modbus-server-16377/

4、Modbus RTU入门介绍

http://blog.csdn.net/doyoung1/article/details/49804311

5、Linux下的串口通信

http://blog.csdn.net/u013485792/article/details/51006790

6、ur3 Gripper通过modbus rtu控制python源码

https://blog.robotiq.com/controlling-the-robotiq-2f-gripper-with-modbus-commands-in-python