参考上章节(java实现modbus rtu协议与 modscan等工具_weixin_42240941的博客-CSDN博客)最后连接的java代码

新增0x06 与 0x10的测试。试对接数码人u位条(v5型)

package com.willservice.cmdb.rtu;import java.util.Arrays;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.*;
import com.serotonin.modbus4j.serial.SerialPortWrapper;/*** 通过串口解析MODBUS协议*/
public class CollectionMain {// 设定MODBUS网络上从站地址private final static int SLAVE_ADDRESS = 1;//串行波特率private final static int BAUD_RATE = 38400;public static void main(String[] args) {SerialPortWrapper serialParameters = newSerialPortWrapperImpl("COM2", BAUD_RATE, 8, 1, 0, 0, 0);/* 创建ModbusFactory工厂实例 */ModbusFactory modbusFactory = new ModbusFactory();/* 创建ModbusMaster实例 */ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);/* 初始化 */try {master.init();
//            readHoldingRegisters(master, SLAVE_ADDRESS, 0, 24);writeSingleHoldingRegister(master, SLAVE_ADDRESS, 1, 1);
//            writeMultipleHoldingRegisters(master, SLAVE_ADDRESS, 0, (short)1,(short)1);} catch (ModbusInitException e) {e.printStackTrace();} finally {master.destroy();}}/*** 0x03* 读保持寄存器上的内容* @param master 主站* @param slaveId 从站地址* @param start 起始地址的偏移量* @param len 待读寄存器的个数*/private static void readHoldingRegisters(ModbusMaster master, int slaveId, int start, int len) {try {ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request);System.out.println(response.toString());if (response.isException()) {System.out.println("Exception response: message=" + response.getExceptionMessage());} else {System.out.println(Arrays.toString(response.getShortData()));short[] list = response.getShortData();for (int i = 0; i < list.length; i++) {System.out.print(list[i] + " ");}}} catch (ModbusTransportException e) {e.printStackTrace();}}// 0x06 写单个保持寄存器// 线圈寄存器是coil,所以保持寄存器method-name非holding修饰private static void writeSingleHoldingRegister(ModbusMaster master, int slaveId, int offset, int value){try {WriteRegisterRequest request = new WriteRegisterRequest(slaveId, offset, value);WriteRegisterResponse response =(WriteRegisterResponse)master.send(request);if (response.isException()) {System.out.println("Exception response: message=" + response.getExceptionMessage());} else {System.out.println("RunRight reponse: messgae="+"no-response-data");}} catch (ModbusTransportException e) {e.printStackTrace();}}// 0x10 写多个保持寄存器//private static void writeMultipleHoldingRegisters(ModbusMaster master, int slaveId, int offset, short... sdata){try {WriteRegistersRequest request = new WriteRegistersRequest(slaveId, offset, sdata);WriteRegistersResponse response =(WriteRegistersResponse)master.send(request);if (response.isException()) {System.out.println("Exception response: message=" + response.getExceptionMessage());} else {System.out.println("RunRight reponse: messgae="+"no-response-data");}} catch (ModbusTransportException e) {e.printStackTrace();}}
}

用上章节方式,得到

写单保持寄存器 offset =0 value =1

输出码01 06 00 00 00 01 48 0A

测试发送,用modsim接收

此次创建两窗口,address不同。得以明白modsim的多窗口与address的含义。

可见40001 数据被修改,40003被修改是因为又调用了一次 其他的 输出码

注:功能码0x06 单写保持寄存器 需要modsimType03:Holding Register

功能码0x10的已经写在代码里了。连续型写入,没大的差别。

==================================================

2022-3-29

补充一些代码,如果任然有缺失,不足以运行,只能去上一篇文章末尾给的参考链接里找

package com.willservice.cmdb.rtu;import com.serotonin.modbus4j.serial.SerialPortWrapper;
import jssc.SerialPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import jssc.SerialPortException;/****/
public class SerialPortWrapperImpl implements SerialPortWrapper {private static final Logger LOG = LoggerFactory.getLogger(SerialPortWrapperImpl.class);private SerialPort port;private String commPortId;private int baudRate;private int dataBits;private int stopBits;private int parity;private int flowControlIn;private int flowControlOut;public SerialPortWrapperImpl(String commPortId, int baudRate, int dataBits, int stopBits, int parity, int flowControlIn,int flowControlOut) {this.commPortId = commPortId;this.baudRate = baudRate;this.dataBits = dataBits;this.stopBits = stopBits;this.parity = parity;this.flowControlIn = flowControlIn;this.flowControlOut = flowControlOut;port = new SerialPort(this.commPortId);}@Overridepublic void close() throws Exception {port.closePort();//listeners.forEach(PortConnectionListener::closed);LOG.debug("Serial port {} closed", port.getPortName());}@Overridepublic void open() {try {port.openPort();port.setParams(this.getBaudRate(), this.getDataBits(), this.getStopBits(), this.getParity());port.setFlowControlMode(this.getFlowControlIn() | this.getFlowControlOut());//listeners.forEach(PortConnectionListener::opened);LOG.debug("Serial port {} opened", port.getPortName());} catch (SerialPortException ex) {LOG.error("Error opening port : {} for {} ", port.getPortName(), ex);}}@Overridepublic InputStream getInputStream() {return new SerialInputStream(port);}@Overridepublic OutputStream getOutputStream() {return new SerialOutputStream(port);}@Overridepublic int getBaudRate() {return baudRate;//return SerialPort.BAUDRATE_9600;}//    @Overridepublic int getFlowControlIn() {return flowControlIn;//return SerialPort.FLOWCONTROL_NONE;}//    @Overridepublic int getFlowControlOut() {return flowControlOut;//return SerialPort.FLOWCONTROL_NONE;}@Overridepublic int getDataBits() {return dataBits;//return SerialPort.DATABITS_8;}@Overridepublic int getStopBits() {return stopBits;//return SerialPort.STOPBITS_1;}@Overridepublic int getParity() {return parity;//return SerialPort.PARITY_NONE;}
}
package com.willservice.cmdb.rtu;/**** Copyright (c) 2009-2020 Freedomotic Team http://www.freedomotic-iot.com** This file is part of Freedomotic** This Program is free software; you can redistribute it and/or modify it under* the terms of the GNU General Public License as published by the Free Software* Foundation; either version 2, or (at your option) any later version.** This Program is distributed in the hope that it will be useful, but WITHOUT* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more* details.** You should have received a copy of the GNU General Public License along with* Freedomotic; see the file COPYING. If not, see* <http://www.gnu.org/licenses/>.*/import jssc.SerialPort;
import jssc.SerialPortException;import java.io.IOException;
import java.io.OutputStream;/*** Class that wraps a {@link SerialPort} to provide {@link OutputStream}* functionality.* <br>* It is instantiated by passing the constructor a {@link SerialPort} instance.* Do not create multiple streams for the same serial port unless you implement* your own synchronization.*** Attribution: https://github.com/therealchalz/java-simple-serial-connector**/
public class SerialOutputStream extends OutputStream {SerialPort serialPort;/*** Instantiates a SerialOutputStream for the given {@link SerialPort} Do not* create multiple streams for the same serial port unless you implement* your own synchronization.** @param sp The serial port to stream.*/public SerialOutputStream(SerialPort sp) {serialPort = sp;}@Overridepublic void write(int b) throws IOException {try {serialPort.writeInt(b);} catch (SerialPortException e) {throw new IOException(e);}}@Overridepublic void write(byte[] b) throws IOException {write(b, 0, b.length);}@Overridepublic void write(byte[] b, int off, int len) throws IOException {byte[] buffer = new byte[len];System.arraycopy(b, off, buffer, 0, len);try {serialPort.writeBytes(buffer);} catch (SerialPortException e) {throw new IOException(e);}}
}
   package com.willservice.cmdb.rtu;/** To change this template, choose Tools | Templates* and open the template in the editor.*/import jssc.SerialPort;import java.io.IOException;
import java.io.InputStream;/*** Class that wraps a {@link SerialPort} to provide {@link InputStream}* functionality. This stream also provides support for performing blocking* reads with timeouts.* <br>* It is instantiated by passing the constructor a {@link SerialPort} instance.* Do not create multiple streams for the same serial port unless you implement* your own synchronization.*** Attribution: https://github.com/therealchalz/java-simple-serial-connector**/
public class SerialInputStream extends InputStream {private SerialPort serialPort;private int defaultTimeout = 0;/*** Instantiates a SerialInputStream for the given {@link SerialPort} Do not* create multiple streams for the same serial port unless you implement* your own synchronization.** @param sp The serial port to stream.*/public SerialInputStream(SerialPort sp) {serialPort = sp;}/*** Set the default timeout (ms) of this SerialInputStream. This affects* subsequent calls to {@link #read()}, {@link #blockingRead(int[])}, and* {@link #blockingRead(int[], int, int)} The default timeout can be 'unset'* by setting it to 0.** @param time The timeout in milliseconds.*/public void setTimeout(int time) {defaultTimeout = time;}/*** Reads the next byte from the port. If the timeout of this stream has been* set, then this method blocks until data is available or until the timeout* has been hit. If the timeout is not set or has been set to 0, then this* method blocks indefinitely.*/@Overridepublic int read() throws IOException {return read(defaultTimeout);}/*** The same contract as {@link #read()}, except overrides this stream's* default timeout with the given timeout in milliseconds.** @param timeout The timeout in milliseconds.* @return The read byte.* @throws IOException On serial port error or timeout*/public int read(int timeout) throws IOException {byte[] buf = new byte[1];try {if (timeout > 0) {buf = serialPort.readBytes(1, timeout);} else {buf = serialPort.readBytes(1);}return buf[0];} catch (Exception e) {throw new IOException(e);}}/*** Non-blocking read of up to buf.length bytes from the stream. This call* behaves as read(buf, 0, buf.length) would.** @param buf The buffer to fill.* @return The number of bytes read, which can be 0.* @throws IOException on error.*/@Overridepublic int read(byte[] buf) throws IOException {return read(buf, 0, buf.length);}/*** Non-blocking read of up to length bytes from the stream. This method* returns what is immediately available in the input buffer.** @param buf The buffer to fill.* @param offset The offset into the buffer to start copying data.* @param length The maximum number of bytes to read.* @return The actual number of bytes read, which can be 0.* @throws IOException on error.*/@Overridepublic int read(byte[] buf, int offset, int length) throws IOException {if (buf.length < offset + length) {length = buf.length - offset;}int available = this.available();if (available > length) {available = length;}try {byte[] readBuf = serialPort.readBytes(available);
//            System.arraycopy(readBuf, 0, buf, offset, length);System.arraycopy(readBuf, 0, buf, offset, readBuf.length);return readBuf.length;} catch (Exception e) {throw new IOException(e);}}/*** Blocks until buf.length bytes are read, an error occurs, or the default* timeout is hit (if specified). This behaves as blockingRead(buf, 0,* buf.length) would.** @param buf The buffer to fill with data.* @return The number of bytes read.* @throws IOException On error or timeout.*/public int blockingRead(byte[] buf) throws IOException {return blockingRead(buf, 0, buf.length, defaultTimeout);}/*** The same contract as {@link #blockingRead(byte[])} except overrides this* stream's default timeout with the given one.** @param buf The buffer to fill.* @param timeout The timeout in milliseconds.* @return The number of bytes read.* @throws IOException On error or timeout.*/public int blockingRead(byte[] buf, int timeout) throws IOException {return blockingRead(buf, 0, buf.length, timeout);}/*** Blocks until length bytes are read, an error occurs, or the default* timeout is hit (if specified). Saves the data into the given buffer at* the specified offset. If the stream's timeout is not set, behaves as* {@link #read(byte[], int, int)} would.** @param buf The buffer to fill.* @param offset The offset in buffer to save the data.* @param length The number of bytes to read.* @return the number of bytes read.* @throws IOException on error or timeout.*/public int blockingRead(byte[] buf, int offset, int length) throws IOException {return blockingRead(buf, offset, length, defaultTimeout);}/*** The same contract as {@link #blockingRead(byte[], int, int)} except* overrides this stream's default timeout with the given one.** @param buf The buffer to fill.* @param offset Offset in the buffer to start saving data.* @param length The number of bytes to read.* @param timeout The timeout in milliseconds.* @return The number of bytes read.* @throws IOException On error or timeout.*/public int blockingRead(byte[] buf, int offset, int length, int timeout) throws IOException {if (buf.length < offset + length) {throw new IOException("Not enough buffer space for serial data");}if (timeout < 1) {return read(buf, offset, length);}try {byte[] readBuf = serialPort.readBytes(length, timeout);System.arraycopy(readBuf, 0, buf, offset, length);return readBuf.length;} catch (Exception e) {throw new IOException(e);}}@Overridepublic int available() throws IOException {int ret;try {ret = serialPort.getInputBufferBytesCount();if (ret >= 0) {return ret;}throw new IOException("Error checking available bytes from the serial port.");} catch (Exception e) {throw new IOException("Error checking available bytes from the serial port.");}}}

java实现modbus rtu协议与 modscan等工具(2)相关推荐

  1. 安卓开发板之串口通信,通过modbus Rtu协议控制下位机

    安卓开发板之串口通信,通过modbus Rtu协议控制下位机 1.环境准备 2.编写串口操作核心类 3.编写测试类 前言:因为公司最近有个人脸识别门禁的项目,这个项目主要业务是实现远程人脸注册,管理员 ...

  2. modbus RTU协议设备使用无线代替有线注意事项

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

  3. 基于Modbus RTU协议的开关量控制采集简介

    一.什么是开关量控制采集 所谓的开关量控制采集就是通过458/232接口发送控制命令,实现读取开关量输入或者控制开关量输出的通断. 二.开关量输入采集和开关量输出控制 1.  开关量输入采集就是将一个 ...

  4. 8数据提供什么掩膜产品_工业轨式1-8路RS485数据(MODBUS RTU协议)厂家产品说明...

    产品描述 工业级数点对点光猫提供1-8路RS485(MODBUS RTU协议): 在光纤中传输,该产品突破了传统串行接口通讯距离与通讯速率的矛盾,同时,也解决了电磁干扰.地环干扰和雷电破坏的难题,大大 ...

  5. AIRIOT物联网低代码平台如何配置Modbus RTU协议?

    MBRTU即MODBUS RTU的简称,MODBUS是OSI模型第7层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信.平台的MBRTU协议是建立在TCP协议之上的 ...

  6. FDX-B标签RFID读写器CK-LR12-AB之Modbus Rtu协议运用规则

    1.1 Modbus Rtu 协议 1.1.1 寄存器定义表 寄存器地址 定义内容 寄存器地址 定义内容 0 从站地址 1 485速率 2 通信校验 3 读卡模式 4 系统状态 5 RSSI 6 Re ...

  7. RS232(Modbus RTU)+RS485(Modbus RTU)协议RFID识别磁导航AGV小车传感器|定位仪CK-GL16-AB的安装与磁处理方法

    RS232(Modbus RTU)+RS485(Modbus RTU)协议RFID识别磁导航AGV小车传感器|定位仪CK-GL16-AB是一款面向AGV行业新推出的一款"跨界"传感 ...

  8. ubuntu16.04下使用Modbus RTU协议控制Robotiq

    ubuntu16.04下使用Modbus RTU协议控制Robotiq 一.设备配置 二.创建工作空间 三.安装驱动 四.配置串口 五. ROS节点控制夹爪 六.RVIZ显示模型 一.设备配置 操作系 ...

  9. 树莓派4B、Python与三相四线多功能电力仪表通过RS485(modbus RTU协议)收发数据

    树莓派4B+Python与三相四线多功能电力仪表通过RS485(modbus RTU协议)接口发送和接收数据 请耐心把下面的警告⚠️看完 开始之前需要注意以下点:一.那就是安全,生命为本,安全第一.因 ...

  10. 三菱FX3U与台达变频器通讯 采用485方式,modbus RTU协议,对台达变频器频率设定

    三菱FX3U与台达变频器通讯器件:三菱FX3U PLC+FX3U 485BD板,台达VFD变频器,昆仑通态触摸屏 功能:采用485方式,modbus RTU协议,对台达变频器频率设定,正反转,点动控制 ...

最新文章

  1. ACM寒假训练第一周总结
  2. 【小项目关键技术二】UGV电机编码测速
  3. 数据结构与算法 / 总章
  4. 课程设计---停车场管理系统
  5. 计算机有哪两种绘图,能被计算机接受的数字图像有哪两种?它们分别由什么构成?...
  6. 2009年9月等考试题及答案51CTO站第一时间发布
  7. php向bat中传递参数,php-将参数传递给PHPUnit
  8. 6759: 异或序列
  9. iOS代码质量要求_Unity移动端代码热更新技术学习总结
  10. 高中数学程序图转化为c语言,程序转化成逻辑图
  11. GameMap其他初始化
  12. w3school和w3cschool两个网站有什么关系和区别?
  13. Web安全工具大汇聚
  14. 苹果开发者账号--关于邓白氏编码的申请
  15. Jvm与DVM与ART
  16. Strurts(四)——从Struts原型模拟看大道至简(含实例下载)
  17. Hdu 4090 GemAnd Prince (搜索_2010年北京区域赛)
  18. 什么是Pythonic?
  19. 内部收益率 IRR XIRR
  20. python自动化word操作

热门文章

  1. 网络安全:漏洞测试主要平台 BackTrack4+Metasploit+ruby
  2. 备考计算机三级数据库——SQL 案例
  3. DLL注入之修改PE静态注入
  4. IDEA查看Java源码技巧
  5. 小米多主题思路分析-重定向资源篇
  6. loadrunner11 下载安装说明
  7. boblog任意变量覆盖漏洞(二)
  8. java.lang.IllegalStateException崩溃处理——4种情形
  9. php中文分词nlp,几种常见的PHP中文分词系统
  10. 什么是远程桌面?花生壳+Windows远程桌面控制教程