pom.xml配置:

 <!-- 辅助modbus4j:repository id:ias-snapshots id:ias-releases 两个 --><repositories><repository><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots><id>ias-snapshots</id><name>Infinite Automation Snapshot Repository</name><url>https://maven.mangoautomation.net/repository/ias-snapshot/</url></repository><repository><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots><id>ias-releases</id><name>Infinite Automation Release Repository</name><url>https://maven.mangoautomation.net/repository/ias-release/</url></repository></repositories><!-- modbus --><dependency><groupId>com.infiniteautomation</groupId><artifactId>modbus4j</artifactId><version>3.0.3</version></dependency>

modbus配置类:

package org.wingtech.modules.modbus.config;/*** @program:  wingtech-boot-parent* @description: modbus读写工具类* @author:  Ricardo.Liu* @create:  2020-05-08* @since:  JDK 1.8**/import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.ip.IpParameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.wingtech.modules.modbus.mapper.IpControlMapper;import java.util.HashMap;@Configuration
/** 使用@Bean,就不用使用@Import来导入相应的类了,@Bean生成的bean的名字默认为方法名,由于hashMap使用很广泛,* 所以使用@Bean的方式引入依赖,这样在注入的时候可以指定名称,以免注入错误的对象* @Import({java.util.HashMap.class,com.serotonin.modbus4j.ModbusFactory.class})*/
@Import(com.serotonin.modbus4j.ModbusFactory.class)
public class ModbusConfig {@Beanpublic HashMap<String, ModbusMaster> modbusMasterHashMap() {return new HashMap<>();}@AutowiredIpControlMapper ipControlMapper;@Autowiredprivate ModbusFactory modbusFactory;@Autowired@Qualifier("modbusMasterHashMap")private HashMap<String,ModbusMaster> masterMap;/*** @Description:  通过ip获取对应的modbus连接器* @Param:  [ip]* @return:  com.serotonin.modbus4j.ModbusMaster* @throws:  * @Author:  Ricardo.Liu* @Date:  2020/5/8*/public ModbusMaster getMaster(String ip) {ModbusMaster modbusMaster = masterMap.get(ip);if(modbusMaster == null) {setMaster(ip, ipControlMapper.queryControlByIp(ip).getPort());modbusMaster = masterMap.get(ip);}return modbusMaster;}/*** @Description:  设置ip对应的modbus连接器* @Param:  [ip, port]* @return:  void* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/private void setMaster(String ip, Integer port) {ModbusMaster master;IpParameters params = new IpParameters();params.setHost(ip);params.setPort(port);//设置为true,会导致TimeoutException: request=com.serotonin.modbus4j.ip.encap.EncapMessageRequest@774dfba5",//params.setEncapsulated(true);master = modbusFactory.createTcpMaster(params, false);// TCP 协议try {//设置超时时间master.setTimeout(3*1000);//设置重连次数master.setRetries(3);//初始化master.init();} catch (ModbusInitException e) {e.printStackTrace();}masterMap.put(ip, master);}
}

modbus工具类:

package org.wingtech.modules.modbus.util;import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ReadCoilsRequest;
import com.serotonin.modbus4j.msg.ReadCoilsResponse;
import com.serotonin.modbus4j.msg.ReadDiscreteInputsRequest;
import com.serotonin.modbus4j.msg.ReadDiscreteInputsResponse;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.ReadInputRegistersRequest;
import com.serotonin.modbus4j.msg.ReadInputRegistersResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;
import com.serotonin.modbus4j.msg.WriteRegistersResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.wingtech.modules.modbus.config.ModbusConfig;/*** @program:  wingtech-boot-parent* @description: modbus读写工具类* @author:  Ricardo.Liu* @create:  2020-05-08* @since:  JDK 1.8**/
@Component
public class ModbusUtil {//从机默认值private Integer slaveId = 1;@Autowiredprivate ModbusConfig modbusConfig;public boolean[] readCoilStatus(String ip, int offset, int numberOfRegister) throws ModbusTransportException {ModbusMaster master = modbusConfig.getMaster(ip);ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfRegister);ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);boolean[] booleans = response.getBooleanData();return valueRegroup(numberOfRegister, booleans);}/*** @Description:  读取外围设备输入的开关量,相当于功能码:02H-读离散输入状态* @Param:  [ip, offset, numberOfRegister]* @return:  boolean[]* @throws:  * @Author:  Ricardo.Liu* @Date:  2020/5/8*/public boolean[] readInputStatus(String ip, int offset, int numberOfRegister) throws ModbusTransportException {ModbusMaster master = modbusConfig.getMaster(ip);ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId,offset, numberOfRegister);ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);boolean[] booleans = response.getBooleanData();return valueRegroup(numberOfRegister, booleans);}/*** @Description:  读取保持寄存器数据,相当于功能码:03H-读保持寄存器* @Param:  [ip, offset, numberOfRegister]* @return:  short[]* @throws:  * @Author:  Ricardo.Liu* @Date:  2020/5/8*/public short[] readHoldingRegister(String ip, int offset, int numberOfRegister) throws ModbusTransportException {ModbusMaster master = modbusConfig.getMaster(ip);ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfRegister);ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);return response.getShortData();}/*** @Description:  读取外围设备输入的数据,相当于功能码:04H-读输入寄存器* @Param:  [ip, offset, numberOfRegister]* @return:  short[]* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/public short[] readInputRegisters(String ip, int offset, int numberOfRegister) throws ModbusTransportException {ModbusMaster master = modbusConfig.getMaster(ip);ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfRegister);ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);return response.getShortData();}/*** @Description:  写单个(线圈)开关量数据,相当于功能码:05H-写单个线圈* @Param:  [ip, writeOffset, writeValue]* @return:  boolean* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/public boolean writeCoil(String ip, int writeOffset, boolean writeValue) throws ModbusTransportException {ModbusMaster tcpMaster = modbusConfig.getMaster(ip);WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);return !response.isException();}/*** @Description:  写多个开关量数据(线圈),相当于功能码:0FH-写多个线圈* @Param:  [ip, startOffset, data]* @return:  boolean* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/public boolean writeCoils(String ip, int startOffset, boolean[] data) throws ModbusTransportException {ModbusMaster tcpMaster = modbusConfig.getMaster(ip);WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, data);WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);return !response.isException();}/*** @Description:  写单个保持寄存器,相当于功能码:06H-写单个保持寄存器* @Param:  [ip, writeOffset, writeValue]* @return:  boolean* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/public boolean writeHoldingRegister(String ip, int writeOffset, short writeValue) throws ModbusTransportException, ModbusInitException {ModbusMaster tcpMaster = modbusConfig.getMaster(ip);WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);return !response.isException();}/*** @Description:  写多个保持寄存器,相当于功能码:10H-写多个保持寄存器* @Param:  [ip, startOffset, data]* @return:  boolean* @throws:* @Author:  Ricardo.Liu* @Date:  2020/5/8*/public boolean writeHoldingRegisters(String ip, int startOffset, short[] data) throws ModbusTransportException, ModbusInitException {ModbusMaster tcpMaster = modbusConfig.getMaster(ip);WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, data);WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request);return !response.isException();}/*** @Description:  转换工具,将Boolean转换成0,1* @Param:  [numberOfBits, values]* @return:  boolean[]* @throws:  * @Author:  Ricardo.Liu* @Date:  2020/5/8*/private  boolean[] valueRegroup(int numberOfBits, boolean[] values) {boolean[] bs = new boolean[numberOfBits];int temp = 1;for (boolean b : values) {bs[temp - 1] = b;temp++;if (temp > numberOfBits) {break;}}return bs;}
}

ipControlMapper:

package org.wingtech.modules.modbus.mapper;import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import org.wingtech.modules.modbus.entity.IpControl;import java.util.List;/*** @program:  wingtech-boot-parent* @description: modbus读写工具类* @author:  Ricardo.Liu* @create:  2020-05-08* @since:  JDK 1.8**/@Mapper
@Repository
public interface IpControlMapper {@Results(id = "ipControlMap", value = {@Result(column = "ip", property = "ip", javaType = String.class),@Result(column = "port", property = "port", javaType = Integer.class),@Result(column = "ip_type", property = "ipType", javaType = Integer.class),@Result(column = "device_data_gather_cycle", property = "deviceDataGatherCycle", javaType = Integer.class),@Result(column = "device_data_gather_interval", property = "deviceDataGatherInterval", javaType = Integer.class),@Result(column = "note_alarm_data_gather_cycle", property = "noteAlarmDataGatherCycle", javaType = Integer.class),@Result(column = "environment_data_gather_cycle", property = "environmentDataRecordCycle", javaType = Integer.class)})//通过ip查询控制器@Select("select ip, port, ip_type, device_data_gather_cycle, device_data_gather_interval, note_alarm_data_gather_cycle, environment_data_gather_cycle " +"from control " +"where ip = #{ip}")IpControl queryControlByIp(String ip);//通过ip类型(0:区域控制器, 1:八防控制器)查询控制器@Select("select ip " +"from control " +"where ip_type = #{ipType}")List<String> queryAllIpControlIp(String ipType);//插入控制器@Insert("insert into control(ip, port, ip_type, device_data_gather_cycle, device_data_gather_interval, note_alarm_data_gather_cycle, environment_data_gather_cycle) " +"values (#{ip}, #{port}, #{ipType}, #{deviceDataGatherCycle}, #{deviceDataGatherInterval}, #{noteAlarmDataGatherCycle}, #{environmentDataRecordCycle})")void addIpControl(IpControl ipControl);//更新区域控制器@Update("<script>" +"update control " +"<set>" +"<if test='port !=null'>port = #{port},</if>" +"<if test='ipType !=null'>ip_type = #{ipType},</if>" +"<if test='pollInterval !=null'>device_data_gather_cycle  = #{deviceDataGatherCycle}, </if>" +"<if test='deviceInterval !=null'>device_data_gather_interval = #{deviceDataGatherInterval}, </if>" +"<if test='deviceInterval !=null'>note_alarm_data_gather_cycle = #{noteAlarmDataGatherCycle}, </if>" +"<if test='enviInterval !=null'>environment_data_gather_cycle = #{environmentDataRecordCycle}, </if>" +"</set> " +"where ip = #{ip}" +"</script>")void updateIpControl(IpControl ipControl);//通过ip删除相应的控制器@Delete("delete " +"from control " +"where ip = #{ip}")void deleteIpControl(String ip);
}

ipControlMapper:

package org.wingtech.modules.modbus.entity;import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.io.Serializable;/*** @author liuyuancheng@wingtech.com* @version 1.0* @ClassName IpControl* @description* @date 2020/5/8 14:18* @since JDK 1.8*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class IpControl implements Serializable {private static final long serialVersionUID = 7456080427901548044L;private String ip;private Integer port;private Integer ipType;private Integer deviceDataGatherCycle;private Integer deviceDataGatherInterval;private Integer noteAlarmDataGatherCycle;private Integer environmentDataRecordCycle;}

原文地址:https://blog.csdn.net/weixin_43069081/article/details/90048760

modbus tcp通讯 在springboot中的实现相关推荐

  1. 基于STM32和W5500的Modbus TCP通讯

     在最近的一个项目中需要实现Modbus TCP通讯,而选用的硬件平台则是STM32F103和W5500,软件平台则选用IAR EWAR6.4来实现. 1.移植前的准备工作 为了实现Modbus ...

  2. winpcapp配置c++网口通讯_(经验)西门子PLC的Modbus TCP通讯的一些经验

    Modbus是一种协议公开的工业通讯,被广泛使用.通过串口的是Modbus-RTU协议,通过以太网的是Modbus TCP通讯.现在的PLC都开始支持以太网通讯,因此,Modbus TCP也越来越重要 ...

  3. modbus tcp通讯modbus4j使用说明

    一.什么是modbus Modbus是由Modicon(现为施耐德电气公司的一个品牌)在1979年发明的,是全球第一个真正用于工业现场的总线协议. ModBus网络是一个工业通信系统,由带智能终端的可 ...

  4. 三菱PLC FX5U与FX5U 直间modbus tcp 通讯

    三菱PLC FX5U与FX5U 直间modbus tcp 通讯 (与此程序经过设备多次使用,硬件一样可以直接用 id=644700625705&

  5. Labview 和信捷 XDH PLC Modbus tcp通讯

    本文描述Labview 和信捷 XDH PLC Modbus tcp通讯,实际测试. 以XDH-60T4-E为实验. 1.地址 1.1默认IP地址:192.168.6.6,端口号:502 1.2点位地 ...

  6. 客户机和服务器在s7通信中各有什么作用,哪些通信口可以进行 Modbus TCP 通讯,作为 Modbus 服务器的 SIMATIC S7 CPU 可以...

    以下通信端口可用于 Modbus/TCP 协议:在默认情况下,端口号 502 作为 Modbus 服务器的本地端口. 可以在 Modbus 客户机中设置需要的本地端口,通常使用从 2000 开始的端口 ...

  7. c#modbus tcp通讯助手开源_RS485和Modbus知识点汇总

    RS485 RS485 特点: 1.逻辑"1"以两线间的电压差为+(2-6)V表示:逻辑"0"以两线间的电压差为-(2-6)V表示.接口信号电平比RS232降低 ...

  8. 两台codesys设备之间通过modbus TCP通讯案例

    目录 关于modbus TCP server端的设置如下 关于modbus TCP clietn端的设置如下 本案例中N1小白盒codesys作为modbus TCP server端,PC的codes ...

  9. Modbus TCP通讯协议

    一.简介 Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准.1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP. Modbus协议是一项应 ...

最新文章

  1. nginx在linux下安装,Nginx在linux下安装及简单命令
  2. mysql双主数据一致性_mysql双主复制的主备数据一致性知多少
  3. Objective-C学习笔记2013[NSString]字符串[可变字符串中,加用app减用delete]
  4. 40、Power Query-Text.Combine函数进阶
  5. 百度搜索打不开第二页_如何查询百度关键词精准收录位置以及收录量(附代码)...
  6. EOJ_1015_查字典
  7. HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格
  8. Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的
  9. php对象数组转数组_php 数组对象互相转换
  10. Swift多线程:GCD进阶,单例、信号量、任务组
  11. Python基础:集合与文件操作
  12. ORACLE GOLDENGATE: WHAT IS ADD TRANDATA REALLY DOING?
  13. VC++2010Express下载
  14. java 安卓 物联网_面向物联网的Android应用开发与实践
  15. 移动web UI推荐
  16. 软件工程保研成功率_软件工程专业保研还是工作?
  17. 陶哲轩实分析 习题5.5.2
  18. php单页菜单,纯CSS3单页切换导航菜单界面设计
  19. 打字不会学计算机,不会拼音打字怎么学
  20. 计算机主板 也叫系统板或母版,什么是主板

热门文章

  1. 判断h5页面是不是在微信小程序里面打开呢?
  2. 同余定理 逆元 中国剩余定理 费马小定理
  3. BIM建模助手上线一周,已有236支战队参加了这场有奖公测活动!
  4. 这种让你肚子疼的分子机制找到了!西湖大学Cell论文揭示病菌入侵人体“新大门”...
  5. Guis [bib Chats]
  6. Spring系列:java字符串转long类型
  7. WPS如何批量删除隐藏表
  8. Java算法题---查找子串的出现位置
  9. 丹斯克银行排除提供加密货币交易的可能性,但不会阻碍客户使用信用卡购买加密货币
  10. 给你五个理由,在2023年获得CISA认证