一文搞懂物联网Modbus通讯协议
简介: 一般来说,常见的物联网通讯协议众多,如蓝牙、Zigbee、WiFi、ModBus、PROFINET、EtherCAT、蜂窝等。而在众多的物联网通讯协议中,Modbus是当前非常流行的一种通讯协议。它一种串行通信协议,是Modicon公司于1979年为使用可编程逻辑控制器(PLC)通信而制定的,可以说,它已经成为工业领域通信协议的业界标准。
1 概述
随着IT技术的快速发展,当前已经步入了智能化时代,其中的物联网技术将在未来占据越来越重要的地位。根据百度百科的定义,物联网(Internet of things,简称IOT )即“万物相连的互联网”,是互联网基础上的延伸和扩展的网络,物联网将各种信息有机的结合起来,实现任何时间、任何地点,人、机、物的互联互通。物联网从技术上来说,很重要的核心是通讯协议,即如何按约定的通讯协议,把机、物和人与互联网相连接,进行信息通信,以实现对人、机和物的智能化识别、定位、跟踪、监控和管理的一种网络。
一般来说,常见的物联网通讯协议众多,如蓝牙、Zigbee、WiFi、ModBus、PROFINET、EtherCAT、蜂窝等。而在众多的物联网通讯协议中,Modbus是当前非常流行的一种通讯协议。它一种串行通信协议,是Modicon公司于1979年为使用可编程逻辑控制器(PLC)通信而制定的,可以说,它已经成为工业领域通信协议的业界标准。其优势如下:
- 免费无版税限制
- 容易部署
- 灵活限制少
2 ModBus协议概述
Modbus通讯协议使用请求-应答机制在主(Master)(客户端Client)和从(Slave)(服务器Server)之间交换信息。Client-Server原理是通信协议的模型,其中一个主设备控制多个从设备。这里需要注意的是:Modbus通讯协议当中的Master对应Client,而Slave对应Server。Modbus通讯协议的官网为www.modbus.org。目前官网组织已经建议将Master-Slave替换为Client-Server。从协议类型上可以分为:Modbus-RTU(ASCII)、Modbus-TCP和Modbus-Plus。本文主要介绍Modbus-RTU(ASCII)的通讯协议原理。标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口。
通讯示意图如下:
一般来说,Modbus通信协议原理具备如下的特征:
- 一次只有一个主机(Master)连接到网络
- 只有主设备(Master)可以启动通信并向从设备(Slave)发送请求
- 主设备(Master)可以使用其特定地址单独寻址每个从设备(Slave),也可以使用地址0(广播)同时寻址所有从设备(Slave)
- 从设备(Slave)只能向主设备(Master)发送回复
- 从设备(Slave)无法启动与主设备(Master)或其他从设备(Slave)的通信
Modbus协议可使用2种通信模式交换信息:
- 单播模式
- 广播模式
不管是请求报文还是答复报文,数据结构如下:
即报文(帧数据)由4部分构成:地址(Slave Number)+功能码(Function Codes)+数据(Data)+校验(Check) 。其中的地址代表从设备的ID地址,作为寻址的信息。功能码表示当前的请求执行具体什么操作,比如读还是写。数据代表需要通讯的业务数据,可以根据实际情况来确定。最后一个校验则是验证数据是否有误。其中的功能码说明如下:
比如功能码为03代表读取当前寄存器内一个或多个二进制值,而06代表将二进制值写入单一寄存器。为了模拟Modbus通讯协议过程,这里可以借助模拟软件:
- Modbus Poll(Master)
- Modbus Slave
具体的安装过程这里不再赘述。首先这里需要模拟一个物联网传感器设备,这里用Modbus Slave来定义,首先打开此软件,并定义一个ID为1的设备:
此功能码为03。另外,设置连接参数,示例界面如下:
下面再用Modbus Poll软件来模拟主机,来获取从设备的数据。首先定义一个读写报文。
然后再定义一个连接信息:
注意:两个COM口要使用不同的名称。
成功建立通讯后,通信的报文格式如下:
Tx代表请求报文,而Rx代表答复报文。
3 ModBus Java实现
下面介绍一下如何用Java来实现一个Modbus TCP通信。这里Java框架采用Spring Boot,首先需要引入Modbus4j库。Maven依赖库的pom.xml定义如下:
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>
<version>2.1.7</version>
</dependency>
其中的modbus4j库可能在Maven中无法正常下载,可以手动下载后放于项目中,并添加到项目库中。如下图所示:
注意:首次实用串口时,需要进行安装,否则会报 no rxtxSerial in java.library.path的错误。
访问RXTX for Java 下载对应操作系统的库文件,解压后安装如下指导进行拷贝后安装。
For a JDK installation:
Copy RXTXcomm.jar ---> <JAVA_HOME>\jre\lib\ext
Copy rxtxSerial.dll ---> <JAVA_HOME>\jre\bin
Copy rxtxParallel.dll ---> <JAVA_HOME>\jre\bin
另外,需要注意,这里还需要串口支持,这里可以用虚拟串口软件来解决。
下面给出Java核心代码片段。
public static SerialPort open(String portName, Integer baudRate, Integer dataBits,
Integer stopBits, Integer parity) {
SerialPort result = null;
try { CommPortIdentifier identifier = CommPortIdentifier.getPortIdentifier(portName);
// 打开端口
CommPort commPort = identifier.open(portName, 2000);
// 判断是不是串口
if (commPort instanceof SerialPort) {
result = (SerialPort) commPort;
// 设置串口的参数
result.setSerialPortParams(baudRate, dataBits, stopBits, parity);
log.info("打开串口{}成功", portName);
}else{
log.info("{}不是串口", portName);
}
} catch (Exception e) {
log.error("打开串口{}错误", portName, e);
}
return result;
}
首先需要启动Modbus RTU Slave程序,核心代码片段如下:
public static void createRtuSlave(){
// 串口是COM3,波特率是9600
SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM3", 9600,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0);
ModbusFactory modbusFactory = new ModbusFactory();
创建RTU Slave
final ModbusSlaveSet slave = modbusFactory.createRtuSlave(wrapper);
// 寄存器里可以设置线圈状态、离散输入状态、保持寄存器和输入寄存器
//从站设备ID是1
BasicProcessImage processImage = new BasicProcessImage(1);
processImage.setInvalidAddressValue(Short.MIN_VALUE);
slave.addProcessImage(processImage); // 添加监听器,监听slave线圈状态和保持寄存器的写入
processImage.addListener(new MyProcessImageListener());
//设置数据
setCoil(processImage);
setInput(processImage);
setHoldingRegister(processImage);
setInputRegister(processImage); // 开启线程启动
new Thread(() -> {
try {
slave.start();
}
catch (ModbusInitException e) {
e.printStackTrace();
}
}).start();
}
而Modbus RTU Master程序,核心代码片段如下:
private static void createRtuMaster() throws Exception{
//串口是COM4,波特率是9600
SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM4", 9600,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0);
ModbusFactory modbusFactory = new ModbusFactory();
//RTU Master
ModbusMaster master = modbusFactory.createRtuMaster(wrapper);
master.init();
// 从站设备ID是1
int slaveId = 1;
// 读取保持寄存器
readHoldingRegisters(master, slaveId, 0, 3);
// 将地址为0的保持寄存器数据修改为0
writeRegister(master, slaveId, 0, 0);
// 再读取保持寄存器
readHoldingRegisters(master, slaveId, 0, 3);
}
启动后输出如下所示:
//Slave
[Thread-1] INFO cn.wu.demo.modbus4j.util.SerialPortUtils - 打开串口COM3成功
保持寄存器地址=0,旧值=8,新值=0
//Master //////////////////////////////////////////////////////////////////////
[main] INFO cn.wu.demo.modbus4j.util.SerialPortUtils - 打开串口COM4成功
读取保持寄存器=[8, 56, 0]
写保持寄存器成功
读取保持寄存器=[0, 56, 0]
参考开源项目:GitHub - wu-boy/modbus4j: modbus4j demo
原文链接
本文为阿里云原创内容,未经允许不得转载。
一文搞懂物联网Modbus通讯协议的更多相关文章
- 一文搞懂HTTP和HTTPS协议
1.什么是协议? 网络协议是计算机之间为了实现网络通信而达成的一种"约定"或者"规则",有了这种"约定",不同厂商的生产设备,以及不同操作系 ...
- Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!
本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...
- 三文搞懂学会Docker容器技术(中)
接着上面一篇:三文搞懂学会Docker容器技术(上) 6,Docker容器 6.1 创建并启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] --na ...
- 三文搞懂学会Docker容器技术(下)
接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...
- 一文搞懂如何使用Node.js进行TCP网络通信
摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...
- 串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧
串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧 本例程中用51单片机作为Modbus从机,从机的设备地址为2,从机有4个寄存器, ...
- 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质
一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...
- 基础篇|一文搞懂RNN(循环神经网络)
基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...
- 一文搞懂 Prometheus 的直方图
原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...
- Modbus通讯协议
<ignore_js_op> O1CN01P1wxTI1dCdw5nAeMO_!!85243700.jpg (287.43 KB, 下载次数: 0) 下载附件 保存到相册 2019-6- ...
随机推荐
- ViewStub你真的了解吗
目录介绍 01.什么是ViewStub 02.ViewStub构造方法 03.inflate()方法解析 04.WeakReference使用 05.ViewStub为何无大小 06.ViewStub ...
- AsyncTask异步任务类
目录介绍 01.先看下AsyncTask用法 02.AsyncTask源码深入分析 2.1 构造方法源码分析 2.2 看execute(Params... params)方法 2.3 mWorker和 ...
- 三维模型(3D)OBJ格式轻量化云端处理技术方法探讨
三维模型OBJ格式轻量化处理技术方法浅析 维模型的OBJ格式轻量化处理技术方法旨在减小模型文件大小.提高加载性能和优化渲染效果.本文将对三维模型OBJ格式轻量化处理技术方法进行浅析,并探讨其在数据压缩 ...
- Prism框架的用法
今天,我向大家介绍一款WPF后台框架,以及,它的用法. 官网 https://prismlibrary.com/ Prism 框架是一个用于构建松耦合.可维护且可测试的 WPF 和 Xamarin.F ...
- 记录--`ElementUI` 中的奇技淫巧
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 在ElementUI的世界中,不仅有基础的组件和功能,还有一些让你眼前一亮.*得不能再*的高级技巧和窍门.本文将揭示这些技巧,让你在前端开 ...
- druid开启sql监控平台
1.maven导入依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid< ...
- KGIS支持的扩展介绍
1.postgis postgis的基本核心功能,仅支持地理图形(矢量要素),在其他Extension前启用. 2.postgis_raster 对栅格数据的支持. 3.postgis_topolog ...
- Python爬虫爬取京东某商品评论信息存入mysql数据库
1 """ 2 https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_com ...
- MySQL数据过滤和搜索
操作符 AND操作符 mysql> SELECT prod_id,prod_price,prod_name FROM products WHERE vend_id=1003 AND prod_p ...
- Python分组数据并保存到单独的文件中
当处理大型数据集时,通常需要将数据分组,并将每个分组的数据保存到单独的文件中.下面是一个使用 Python 中的 pandas 库来实现这一目标的示例代码. 步骤 1: 导入所需的库 import o ...