modbusj例子
modbus报文实例

modbus报文实例Modbus报文实例Modbus是一种用于在工业自动化系统中进行通信的协议。
它是一种简单、可靠且广泛使用的协议,被广泛应用于监控、控制和数据采集等领域。
在Modbus通信中,数据是通过报文进行传输的。
本文将以Modbus报文实例为标题,介绍Modbus报文的结构和常见的实例。
一、Modbus报文结构Modbus报文由不同的字段组成,每个字段都有特定的含义和作用。
一个完整的Modbus报文包括以下几个字段:1. 起始符:Modbus报文以起始符开始,用于标识报文的开始。
2. 地址:地址字段用于标识Modbus设备的地址,用于指定通信的目标设备。
3. 功能码:功能码用于指示报文的目的和操作类型。
不同的功能码对应不同的操作,例如读取数据、写入数据等。
4. 数据:数据字段用于存储报文中传输的数据。
根据不同的功能码,数据可以是读取的数据、写入的数据或其他操作所需要的参数。
5. 校验码:校验码用于验证报文的完整性和正确性。
校验码的计算通常使用CRC或LRC算法。
6. 结束符:结束符用于标识报文的结束。
二、Modbus报文实例下面以几个常见的Modbus报文实例来说明报文的结构和用法。
1. 读取线圈状态(功能码:0x01)读取线圈状态是Modbus中常用的操作之一,用于读取远程设备中的线圈状态。
下面是一个读取线圈状态的Modbus报文实例:起始符地址功能码起始地址数据长度校验码结束符0x01 0x01 0x01 0x0000 0x0001 0x1D 0x0D 0x0A在这个报文中,起始符为0x01,地址为0x01,功能码为0x01,起始地址为0x0000,数据长度为0x0001,校验码为0x1D,结束符为0x0D 0x0A。
2. 写入单个线圈(功能码:0x05)写入单个线圈用于控制远程设备中的单个线圈状态。
下面是一个写入单个线圈的Modbus报文实例:起始符地址功能码线圈地址数据校验码结束符0x01 0x01 0x05 0x0000 0xFF00 0x8C 0x0D 0x0A在这个报文中,起始符为0x01,地址为0x01,功能码为0x05,线圈地址为0x0000,数据为0xFF00,校验码为0x8C,结束符为0x0D 0x0A。
Modbus通讯功能码及实例

功能码名称作用01 读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)02 读取输入状态取得一组开关输入的当前状态(ON/OFF)03 读取保持寄存器在一个或多个保持寄存器中取得当前的二进制值04 读取输入寄存器在一个或多个输入寄存器中取得当前的二进制值05 强置单线圈强置一个逻辑线圈的通断状态06 预置单寄存器把具体二进值装入一个保持寄存器07 读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定08 回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴09 编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑10 控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送11 读取事件计数可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时12 读取通信事件记录可是主机检索每台从机的ModBu s事务处理通信事件记录。
如果某项事务处理完成,记录会给出有关错误13 编程(184/384 484 584)可使主机模拟编程器功能修改PC从机逻辑14 探询(184/384 484 584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送15 强置多线圈强置一串连续逻辑线圈的通断16 预置多寄存器把具体的二进制值装入一串连续的保持寄存器17 报告从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态18 (884和MI CRO 84)可使主机模拟编程功能,修改PC状态逻辑19 重置通信链路发生非可修改错误后,是从机复位于已知状态,可重置顺序字节20 读取通用参数(584L)显示扩展存储器文件中的数据信息21 写入通用参数(584L)把通用参数写入扩展存储文件,或修改之22~64 保留作扩展功能备用65~72 保留以备用户功能所用留作用户功能的扩展编码73~119 非法功能120~127 保留留作内部作用128~255 保留用于异常应答实例在这些功能码中较长使用的是1、2、3、4、5、6号功能码,使用它们即可实现对下位机的数字量和模拟量的读写操作。
modbus协议通信实例

modbus协议通信实例Modbus协议是一种常用的工业通信协议,它可以实现不同设备之间的数据交换。
下面将介绍一个Modbus协议通信的实例。
在这个实例中,我们需要将一个温度传感器的数据传输到PLC控制器上。
首先,我们需要选择一个支持Modbus协议的温度传感器和PLC 控制器。
在这个实例中,我们选择了一个支持Modbus RTU协议的温度传感器和PLC控制器。
接下来,我们需要配置温度传感器和PLC控制器的Modbus通信参数。
在这个实例中,我们选择了9600波特率、8数据位、无校验位和1停止位。
我们还需要为温度传感器和PLC控制器分配Modbus地址。
在这个实例中,我们将温度传感器的Modbus地址设置为1,将PLC控制器的Modbus地址设置为2。
现在,我们可以开始编写PLC控制器的程序。
在这个实例中,我们使用了一个Modbus RTU通信模块来实现PLC控制器与温度传感器之间的通信。
我们需要在PLC控制器的程序中添加Modbus RTU通信模块,并配置通信参数和Modbus地址。
然后,我们需要编写一个读取温度传感器数据的程序,并将数据存储到PLC控制器的内存中。
在温度传感器和PLC控制器之间建立通信后,我们可以使用Modbus 调试工具来测试通信是否正常。
在这个实例中,我们使用了一个Modbus调试工具来读取温度传感器的数据。
我们需要在Modbus调试工具中设置通信参数和Modbus地址,并发送读取数据的命令。
如果通信正常,我们将能够读取到温度传感器的数据。
最后,我们可以在PLC控制器的HMI界面上显示温度传感器的数据。
在这个实例中,我们使用了一个数码管来显示温度传感器的数据。
我们需要在PLC控制器的程序中添加一个数码管,并将温度传感器的数据显示在数码管上。
总之,Modbus协议是一种常用的工业通信协议,它可以实现不同设备之间的数据交换。
在这个实例中,我们使用了Modbus RTU协议来实现温度传感器和PLC控制器之间的通信,并将温度传感器的数据显示在PLC控制器的HMI界面上。
Modbus通讯 功能码及实例

功效码名称作用之五兆芳芳创作01 读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)02 读取输入状态取得一组开关输入的当前状态(ON/OFF)03 读取保持存放器在一个或多个保持存放器中取得当前的二进制值04 读取输入存放器在一个或多个输入存放器中取得当前的二进制值05 强置单线圈强置一个逻辑线圈的通断状态06 预置单存放器把具体二进值装入一个保持存放器07 读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定08 回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴09 编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑10 控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操纵任务,仅在含有功效码9的报文发送后,本功效码才发送11 读取事件计数可使主机收回单询问,并随即判定操纵是否成功,尤其是该命令或其他应答产生通信错误时12 读取通信事件记实可是主机检索每台从机的ModBus事务处理通信事件记实.如果某项事务处理完成,记实会给出有关错误13 编程(184/384 484 584)可使主机模拟编程器功效修改PC从机逻辑14 探询(184/384 484 584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操纵,仅在含有功效13的报文发送后,本功效码才得发送15 强置多线圈强置一串连续逻辑线圈的通断16 预置多存放器把具体的二进制值装入一串连续的保持存放器17 陈述从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态18 (884和MICRO 84)可使主机模拟编程功效,修改PC状态逻辑19 重置通信链路产生非可修改错误后,是从机复位于已知状态,可重置顺序字节20 读取通用参数(584L)显示扩展存储器文件中的数据信息21 写入通用参数(584L)把通用参数写入扩展存储文件,或修改之22~64 保存作扩展功效备用65~72 保存以备用户功效所用留作用户功效的扩展编码73~119 不法功效120~127 保存留作内部作用128~255 保存用于异常应答实例在这些功效码中较长使用的是1、2、3、4、5、6号功效码,使用它们便可实现对下位机的数字量和模拟量的读写操纵.1、读可读写数字量存放器(线圈状态):计较机发送命令:[设备地址] [命令号01] [起始存放器地址高8位] [低8位] [读取的存放器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]例:[11][01][00][13][00][25][CRC低][CRC高]意义如下:<1>设备地址:在一个485总线上可以挂接多个设备,此处的设备地址暗示想和哪一个设备通讯.例子中为想和17号(十进制的17是十六进制的11)通讯.<2>命令号01:读取数字量的命令号固定为01.<3>起始地址高8位、低8位:暗示想读取的开关量的起始地址(起始地址为0).比方例子中的起始地址为19.<4>存放器数高8位、低8位:暗示从起始地址开始读多少个开关量.例子中为37个开关量.<5>CRC校验:是从开头一直校验到此之前.在此协议的最后再作介绍.此处需要注意,CRC校验在命令中的凹凸字节的顺序和其他的相反.设备响应:[设备地址] [命令号01] [前往的字节个数][数据1][数据2]...[数据n][CRC校验的低8位] [CRC校验的高8位] 例:[11][01][05][CD][6B][B2][0E][1B][CRC低][CRC高]意义如下:<1>设备地址和命令号和上面的相同.<2>前往的字节个数:暗示数据的字节个数,也就是数据1,2...n中的n的值.<3>数据1...n:由于每一个数据是一个8位的数,所以每一个数据暗示8个开关量的值,每一位为0暗示对应的开关断开,为1暗示闭合.比方例子中,暗示20号(索引号为19)开封闭合,21号断开,22闭合,23闭合,24断开,25断开,26闭合,27闭合...如果询问的开关量不是8的整倍数,那么最后一个字节的高位部分无意义,置为0.<4>CRC校验同上.2、读只可读数字量存放器(输入状态):和读取线圈状态类似,只是第二个字节的命令号不再是1而是2.3、写数字量(线圈状态):计较机发送命令:[设备地址] [命令号05] [需下置的存放器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]例:[11][05][00][AC][FF][00][CRC低][CRC高]意义如下:<1>设备地址和上面的相同.<2>命令号:写数字量的命令号固定为05.<3>需下置的存放器地址高8位,低8位:标明了需要下置的开关的地址.<4>下置的数据高8位,低8位:标明需要下置的开关量的状态.例子中为把该开封闭合.注意,此处只可以是[FF][00]暗示闭合[00][00]暗示断开,其他数值不法.<5>注意此命令一条只能下置一个开关量的状态.设备响应:如果成功把计较机发送的命令原样前往,不然不响应.4、读可读写模拟量存放器(保持存放器):计较机发送命令:[设备地址] [命令号03] [起始存放器地址高8位] [低8位] [读取的存放器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]例:[11][03][00][6B][00][03][CRC低][CRC高]意义如下:<1>设备地址和上面的相同.<2>命令号:读模拟量的命令号固定为03.<3>起始地址高8位、低8位:暗示想读取的模拟量的起始地址(起始地址为0).比方例子中的起始地址为107.<4>存放器数高8位、低8位:暗示从起始地址开始读多少个模拟量.例子中为3个模拟量.注意,在前往的信息中一个模拟量需要前往两个字节.设备响应:[设备地址] [命令号03] [前往的字节个数][数据1][数据2]...[数据n][CRC校验的低8位] [CRC校验的高8位] 例:[11][03][06][02][2B][00][00][00][64][CRC低][CRC高] 意义如下:<1>设备地址和命令号和上面的相同.<2>前往的字节个数:暗示数据的字节个数,也就是数据1,2...n中的n的值.例子中前往了3个模拟量的数据,因为一个模拟量需要2个字节所以共6个字节.<3>数据1...n:其中[数据1][数据2]辨别是第1个模拟量的高8位和低8位,[数据3][数据4]是第2个模拟量的高8位和低8位,以此类推.例子中前往的值辨别是555,0,100.<4>CRC校验同上.5、读只可读模拟量存放器(输入存放器):和读取保管存放器类似,只是第二个字节的命令号不再是2而是4.6、写单个模拟量存放器(保持存放器):计较机发送命令:[设备地址] [命令号06] [需下置的存放器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]例:[11][06][00][01][00][03][CRC低][CRC高]意义如下:<1>设备地址和上面的相同.<2>命令号:写模拟量的命令号固定为06.<3>需下置的存放器地址高8位,低8位:标明了需要下置的模拟量存放器的地址.<4>下置的数据高8位,低8位:标明需要下置的模拟量数据.比方例子中就把1号存放器的值设为3.<5>注意此命令一条只能下置一个模拟量的状态.设备响应:如果成功把计较机发送的命令原样前往,不然不响应.。
j2mod 的案例

j2mod 的案例j2mod是一个Java实现的Modbus协议库,用于在计算机网络中实现Modbus通信。
它提供了Modbus协议的主站和从站实现,以及与Modbus设备进行通信的API接口。
j2mod具有灵活、易用、可扩展的特点,被广泛应用于工业自动化、能源管理、楼宇自控等领域。
在以下的案例中,我将介绍j2mod在不同场景下的应用。
1. 工业自动化控制系统:以一个工业自动化控制系统为例,该系统包含多个从站设备,如温度传感器、压力传感器、阀门控制器等。
通过j2mod库,主站可以与这些从站设备建立连接,并实时获取温度、压力等数据。
主站可以通过j2mod库发送指令控制从站设备,如打开或关闭阀门,调节温度等。
2. 能源管理系统:j2mod可以应用于能源管理系统中,用于实时监测和控制能源设备,如发电机、变压器、电表等。
主站可以通过j2mod库与这些设备进行通信,获取电能消耗数据、电压数据等。
主站可以根据这些数据进行能源管理,如优化能源分配、降低能耗等。
3. 楼宇自控系统:在楼宇自控系统中,j2mod可以用于实现主站与从站设备之间的通信。
主站可以通过j2mod库与从站设备进行连接,实时获取温度、湿度、照明等数据。
主站可以根据这些数据进行楼宇自控,如调节空调温度、控制照明亮度等。
4. 数据采集系统:j2mod可以用于实现数据采集系统,主站可以通过j2mod库与多个从站设备进行连接,实时获取各个设备的数据。
主站可以将这些数据保存到数据库中,供后续分析和处理。
5. 远程监控系统:j2mod可以应用于远程监控系统中,主站可以通过j2mod库与远程设备进行通信。
主站可以实时获取设备的状态和数据,并对设备进行控制。
6. 智能家居系统:在智能家居系统中,j2mod可以用于实现主站与从站设备之间的通信。
主站可以通过j2mod库与从站设备进行连接,实时获取温度、湿度、照明等数据。
主站可以根据这些数据进行智能家居控制,如自动调节室内温度、控制照明等。
超实用,非常典型的Modbus通讯项目案例,十分钟学会

超实用,非常典型的Modbus通讯项目案例,十分钟学会本文主要介绍两部分,1.简单介绍Modbus通讯相关知识。
2.通讯案例详解。
一.Modbus通讯介绍1.通讯概述Modbus具有两种串行传输模式:分别为ASCII和RTU。
Modbus是一种单主站的主从通信模式,Modbus网络上只能有一个主站存在,主站在Modbus网络上没有地址,每个从站必须有唯一的地址,从站的地址范围为0 - 247,其中0为广播地址,从站的实际地址范围为1 - 247。
Modbus RTU 使用主/从站网络,其中整个通信仅由一个主站设备触发,而从站只能响应主站的请求。
主站将请求发送到一个从站地址,并且只有该地址上的从站做出响应。
Modbus RTU是用于网络中通信的标准协议,使用RS232 或RS422/485 连接在网络中的 Modbus 设备之间进行串行数据传输。
l 注: Modbus 从站地址为 0 时会向所有从站发送广播帧(从站均不响应)。
2.Modbus 通讯协议Modbus的通讯协议可在网上查阅相关详细资料,这里简单说明:数据传送帧结构顺序是,主站和从站/从站和主站之间的数据通信从从站地址开始,接下来是功能代码。
随后传输数据。
数据字段的结构取决于使用的功能代码。
帧的最后传送的是校验和 (CRC)。
二.通讯案例详解案例背景:一套以西门子S7_1200PLC作为控制器的控制系统(带HMI面板),与一套加湿器控制系统(单片机)进行Modbus RTU通讯,读取和写入加湿器数据,并通过控制面板进行显示和设置加湿器参数,以及通过HMI面板手动控制加湿机的充水、排水、加湿和停机。
(与除湿机的通讯只是该项目中的一部分,这里只介绍与加湿机的通讯部分,其他控制部分未说明)加湿器的参数如下图l 注:PLC的控制系统作为主站,加湿器控制系统为从站1. 硬件及软件需求硬件:CPU 1215C AC/DC/Rly(订货号:6ES7 215-1BG40-0XB0)CM 1241 (RS422/485)(订货号:6ES7 241-1CH32-0XB0)HMI面板KTP1200 Basic PN(订货号:6AV2 123-2MB03-0AX0)屏蔽电缆(用于通讯)l 注:本项目采用RS485接线方法, 3号针脚--RS485信号 B(+) ;8号针脚--RS485信号A(-);5号针脚--接屏蔽等电位点。
java对接modbus协议实例代码

java对接modbus协议实例代码Modbus是一种串行通信协议,常用于工业自动化系统中。
在Java中,可以使用第三方库如`j2mod`或`Modbus4J`来实现Modbus协议的对接。
这里是一个使用`Modbus4J`的简单示例:首先,你需要添加Modbus4J的依赖到你的项目中。
如果你使用Maven,你可以添加以下依赖:```xml<dependency><groupId></groupId><artifactId>modbus4j</artifactId><version></version> <!--请检查是否有更新的版本--></dependency>```然后,以下是一个简单的Modbus客户端代码示例:```javaimport ;import ;import ;import ;import ;public class ModbusClient {public static void main(String[] args) {ModbusFactory factory = new ModbusFactory(); IpParameters params = new IpParameters();(""); //设置Modbus服务器IP地址(502); //设置端口号(1); //设置重试次数(1000); //设置超时时间(毫秒)(1); //设置从设备IDModbusMaster master = (params, true);();try {// 读取保持寄存器int registerAddress = 0x0000; //寄存器地址int numRegisters = 1; //寄存器数量ReadHoldingRegistersResponse response = (new ReadHoldingRegistersRequest(registerAddress, numRegisters));("Value: " + ());} catch (Exception e) {();} finally {(); // 关闭主站连接}}}```这是一个非常基础的Modbus客户端示例,仅用于读取一个保持寄存器的值。
modbus协议例子

modbus协议例子Modbus协议是一种通信协议,用于在工业自动化系统中传输数据。
它被广泛应用于监控和控制设备之间的通信。
下面是一些使用Modbus协议的实际例子:1. 工业自动化控制系统:Modbus协议常用于连接PLC(可编程逻辑控制器)和其他设备,如传感器、执行器和人机界面。
通过Modbus 协议,PLC可以与其他设备进行数据交换,实现自动化控制。
2. 太阳能发电系统监控:Modbus协议可以用于监控太阳能发电系统中各个组件的状态和性能。
例如,通过Modbus协议,可以实时获取太阳能电池板的电压、光照强度和输出功率等信息,以便进行系统优化和故障排除。
3. 能源管理系统:Modbus协议可以用于监控和控制能源管理系统中的各个设备,如电表、电池、逆变器等。
通过Modbus协议,可以实时获取能源消耗情况、电池状态和逆变器运行状态等信息,以便进行能源优化和节能管理。
4. 智能家居系统:Modbus协议可以用于智能家居系统中各个设备之间的通信。
例如,通过Modbus协议,可以实现智能灯控制器与智能开关、智能窗帘控制器和智能温控器之间的数据交换,实现智能家居的自动化控制。
5. 智能交通系统:Modbus协议可以用于智能交通系统中的信号灯控制器和交通监控设备之间的通信。
通过Modbus协议,可以实时获取交通信号灯的状态和交通流量等信息,以便进行交通管理和优化。
6. 智能农业系统:Modbus协议可以用于智能农业系统中的各个设备之间的通信。
例如,通过Modbus协议,可以实时获取温室中的温度、湿度和光照强度等信息,以便进行温室控制和作物生长管理。
7. 智能楼宇系统:Modbus协议可以用于智能楼宇系统中各个设备之间的通信。
例如,通过Modbus协议,可以实现楼宇自动化控制器与空调、照明和安防设备之间的数据交换,实现楼宇的智能化管理和节能优化。
8. 工业设备监控系统:Modbus协议可以用于监控工业设备的状态和性能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
package com.modbus;import java.nio.ByteBuffer;import com.serotonin.modbus4j.ModbusFactory; import com.serotonin.modbus4j.ModbusMaster; importcom.serotonin.modbus4j.exception.ModbusInitExcept ion;importcom.serotonin.modbus4j.exception.ModbusTransportE xception;import com.serotonin.modbus4j.ip.IpParameters; import com.serotonin.modbus4j.msg.ModbusRequest; import com.serotonin.modbus4j.msg.ModbusResponse;importcom.serotonin.modbus4j.msg.ReadHoldingRegistersRe quest;importcom.serotonin.modbus4j.msg.WriteRegistersRequest; importcom.serotonin.modbus4j.msg.WriteRegistersResponse ;import com.serotonin.util.queue.ByteQueue;/*** modbus 处理类* @author ?**/public class ModbusHandler {static ModbusFactory modbusFactory;static {if (modbusFactory == null) {modbusFactory = new ModbusFactory();}}/*** 得到 WriteRegistersRequest** @param ip* @param port* @param slaveId* @param start* @param values*/public static WriteRegistersRequest getWriteRegistersRequest(int slaveId,int start, short[] values) {WriteRegistersRequest request = null;try {request = newWriteRegistersRequest(slaveId, start, values);} catch (ModbusTransportException e) {e.printStackTrace();}return request;}/*** 得到 WriteRegistersRequest** @param ip* @param port* @param slaveId* @param start* @param values*/public static WriteRegistersResponse getWriteRegistersResponse(ModbusMaster tcpMaster, WriteRegistersRequest request) {WriteRegistersResponse response = null;try {response = (WriteRegistersResponse) tcpMaster.send(request);} catch (ModbusTransportException e) {e.printStackTrace();}return response;}/*** 写入** @param ip* @param port* @param slaveId* @param start* @param values*/public static int modbusWTCP(String ip, int port, int slaveId, int start,short[] values) {ModbusMaster tcpMaster = getTcpMaster(ip, port, slaveId);if (tcpMaster == null){System.out.println("tcpMaster is null ");return 0;}tcpMaster = initTcpMaster(tcpMaster);WriteRegistersRequest request = getWriteRegistersRequest(slaveId,start, values);WriteRegistersResponse response = getWriteRegistersResponse(tcpMaster,request);if (response.isException()) {return 0;} else {return 1;}}/*** 初始化?tcpMaster** @param tcpMaster* @return*/public static ModbusMaster initTcpMaster(ModbusMaster tcpMaster) { if (tcpMaster == null)return null;try {tcpMaster.init();return tcpMaster;} catch (ModbusInitException e) { return null;}}/*** 得到 ModbusRequest** @param salveId* @param start* @param readLenth* @param tcpMaster*/public static ModbusRequest getRequest(int salveId, int start,int readLenth, ModbusMaster tcpMaster) { ModbusRequest modbusRequest = null;try {modbusRequest = new ReadHoldingRegistersRequest(salveId,start,readLenth);return modbusRequest;} catch (ModbusTransportException e) {e.printStackTrace();return null;}}/*** 得到 ModbusResponse** @param salveId* @param start* @param readLenth* @param tcpMaster*/public static ModbusResponse getModbusResponse(ModbusMaster tcpMaster,ModbusRequest request) {ModbusResponse modbusResponse = null;try {modbusResponse = tcpMaster.send(request);return modbusResponse;} catch (ModbusTransportException e) {e.printStackTrace();return null;}}/*** 获取设备数据* @param ip* 信息机地址ip* @param port* 端口默认端口502* @param salveId* 从站地址* @param start* 数据报文的起始位置* @param readLenth* 读取的长度* @return结果*/public static ByteQueue modbusRTCP(String ip, int port, int salveId,int start, int readLenth) {ModbusMaster tcpMaster = getTcpMaster(ip, port, salveId);// 得到tcpMasterif (tcpMaster == null){System.out.println("tcpMaster is null ");return null;}return modbusRTCP0(ip, port, salveId, start, readLenth, tcpMaster);}/*** 获取 tcp master** @param ip* @param port* @param salveId*/public static ModbusMaster getTcpMaster(String ip, int port, int salveId) {IpParameters params = new IpParameters();params.setHost(ip);// 设置ipif(port == 0)params.setPort(502);// 设置端口,默认为502else params.setPort(port);ModbusMaster tcpMaster =modbusFactory.createTcpMaster(params, true);// 获取ModbusMaster对象return tcpMaster;}/*** modbus 读取** @param ip* @param port* @param salveId* @param start* @param readLenth* @param tcpMaster* @return*/public static ByteQueue modbusRTCP0(String ip, int port, int salveId,int start, int readLenth, ModbusMaster tcpMaster) {if (tcpMaster == null){System.out.println("tcpMaster is null");return null;}tcpMaster = initTcpMaster(tcpMaster);// 初始化tcpmasterif (tcpMaster == null){System.out.println("tcpMaster is null");return null;}ModbusRequest modbusRequest =getRequest(salveId, start, readLenth,tcpMaster);// 得到requst 对象if (modbusRequest == null){System.out.println("request is null");return null;}ModbusResponse response = getModbusResponse(tcpMaster, modbusRequest);// 发送请求,得到ResponseByteQueue byteQueue = new ByteQueue(12);response.write(byteQueue);System.out.println("功能" + modbusRequest.getFunctionCode());System.out.println("从站地址:" + modbusRequest.getSlaveId());System.out.println("收到的响应信息大小" + byteQueue.size());System.out.println("收到的响应信息小:" + byteQueue);return byteQueue;}/* ** Convert byte[] to hex* string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串 * @param src byte[] data* @return hex string*/public static String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder("");if (src == null || src.length <= 0) {return null;}for (int i = 0; i < src.length; i++) {int v = src[i] & 0xFF;String hv = Integer.toHexString(v);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}/**************************************************** *** 起始位置15,响应数据:从站|data包含的传感器个数|data length|data*************************************************** **** @param bq*/public static void ansisByteQueue(ByteQueue bq) {byte[] result = bq.peekAll();System.out.println("从站地址==="+ result[0]);System.out.println("data 个数===" +result[1]);System.out.println("data 长度===" +result[2]);byte[] temp = null;ByteBuffer buffer = ByteBuffer.wrap(result, 3, result.length - 3);//直接获取 datawhile (buffer.hasRemaining()) {temp = new byte[2];buffer.get(temp, 0, temp.length);System.out.print(Integer.parseInt(bytesToHexSt ring(temp), 16)+" ");}}public static void main(String[] args) { ByteQueue result =ModbusHandler.modbusRTCP("169.254.48.188", 502, 2, 15, 3);ansisByteQueue(result);short[] shor = new short[1];shor[0] = 0x33;ModbusHandler.modbusWTCP("169.254.48.188", 502, 2, 15, shor);}}。