java modbus协议
概念
Modbus是一种串行通信协议,Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。
大多数Modbus设备通信通过串口EIA-485物理层进行。
通讯格式
地址域 | 功能码 | 数据 | CRC校验(低字节在前) |
---|---|---|---|
1字节 | 1字节 | N字节 | 2字节 |
在单片机硬件通讯串口行业,很多厂家都把485串口参数设置为:
波特率9600,无奇偶校验,1停止位
功能码说明
实际用途中常用的功能码有:
- 0x03用来读取单片机寄存器的数据
- 0x06用来给单片机写入数据
功能码0x03:读单个或多个保持寄存器
设备地址(1字节) | 功能码(1字节) | 寄存器起始地址(2字节) | 寄存器数量(2字节) | CRC校验(2字节) |
---|---|---|---|---|
XX | 03 | XX XX | XX XX | XX XX |
响应:
设备地址(1字节) | 功能码(1字节) | 数据长度(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
XX | 03 | XX XX | N字节 | XX XX |
示例
查询设备类型
设备地址(1字节) | 功能码(1字节) | 数据长度(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
01 | 03 | 00 01 | 00 01 | D5 CA |
查询设备类型响应
设备地址(1字节) | 功能码(1字节) | 数据长度(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
01 | 03 | 02 | 00 21 | 78 5C |
功能码0x06:写单个寄存器
设备地址(1字节) | 功能码(1字节) | 寄存器地址(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
XX | 06 | XX XX | N字节 | XX XX |
响应:
设备地址(1字节) | 功能码(1字节) | 寄存器地址(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
XX | 06 | XX XX | N字节 | XX XX |
示例
写数据
设备地址(1字节) | 功能码(1字节) | 寄存器地址(2字节) | 数据(N字节) | CRC校验(2字节) |
---|---|---|---|---|
01 | 06 | 00 14 | 00 00 | C9 CE |
Java版modbus协议代码:
package com.wrs.project.modbus;import java.util.ArrayList;
import java.util.List;public class ModbusUtils {/*** 读指令* @param deviceAddress 设备地址* @param registerAddress 寄存器起始地址* @param registerCount 寄存器个数* @return*/public static byte[] getReadModbus(int deviceAddress, int registerAddress, int registerCount) {int registerLow = registerAddress & 0xFF;int registerHigh = registerAddress >>> 8;int countLow = registerCount & 0xFF;int countHigh = registerCount >>> 8;int[] data = new int[]{registerHigh, registerLow, countHigh, countLow};byte[] sendData = getModbusData(deviceAddress, 0x03, data);return sendData;}/*** 写指令* @param deviceAddress 设备地址* @param registerAddress 寄存器起始地址* @param writeData 寄存器个数* @return*/public static byte[] getWriteModbus(int deviceAddress, int registerAddress, int[] writeData) {int registerLow = registerAddress & 0xFF;int registerHigh = registerAddress >>> 8;int[] data = new int[writeData.length + 2];data[0] = registerHigh;data[1] = registerLow;for (int i = 0; i < writeData.length; i ++) {data[i + 2] = writeData[i];}byte[] sendData = getModbusData(deviceAddress, 0x06, data);return sendData;}public static List<Byte> isValidModbusResponseData(List<Byte> list) {if (null != list && list.size() >= 4) {int size = list.size();int leng = ByteUtils.byteToInt(list.get(2));int totalSize = leng + 5;if (size < totalSize) {return null;}List tempList = list.subList(0, totalSize - 2);byte[] tempData = ArrayUtils.listTobyte(tempList);int crc = CRCUtils.getCRC(tempData);int low = crc & 0xFF;int high = crc >>> 8;byte lowData = list.get(totalSize - 2);byte hightData = list.get(totalSize - 1);if (low == ByteUtils.byteToInt(lowData) && high == ByteUtils.byteToInt(hightData)) {return list.subList(0, totalSize);} else {return null;}} else {return null;}}public static byte[] getModbusData(int address, int function, int[] data) {int leng = 2;if (null != data) {leng += data.length;}byte[] tempData = new byte[leng];tempData[0] = ByteUtils.intToByte(address);tempData[1] = ByteUtils.intToByte(function);if (null != data) {for (int i = 0; i < data.length; i++) {tempData[i + 2] = ByteUtils.intToByte(data[i]);}}int crc = CRCUtils.getCRC(tempData);int low = crc & 0xFF;int high = crc >>> 8;List list = new ArrayList();list.addAll(ArrayUtils.byteToList(tempData));list.add(ByteUtils.intToByte(low));list.add(ByteUtils.intToByte(high));return ArrayUtils.listTobyte(list);}
}
项目源码:https://codechina.csdn.net/it1/modbusproject
如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!
读者有什么想看的相关技术篇章,欢迎评论留言!
QQ交流群:908058499
相关文章:

layui栅格布局问题
在使用layer.open弹出到窗口中,使用布局一直不起作用。 开始到写法如下, 目的是一行分成左右两块,比例为8:4等分。 <div class"layui-fluid"><div class"layui-row layui-col-space10"><div class"layui-col-md…

Unity3d载入外部图片文件
unity里的图片在生成时会压缩成资源文件,有时客户想自己放一些图片用unity显示,就必须载入外部图片。 大体思路:用Application.streamingAssetsPath或Application.dataPath来指定存放图片的相对路径。用DirectoryInfo获得目录。遍历后FileInf…

Linux06-服务、守护进程和systemd
目录 一、简介systemd 二、使用systemd 2.1、systemctl命令与systemd单元 2.2、控制系统服务 一、简介systemd RHEL6及以前,系统启动和服务器进程是由第一个进程 init 管理,init按顺序启动、启动慢。 RHEL7以后系统启动和服务器进程由 systemd系统和…

ORB_SLAM2回环检测
词典是特征点的描述子的集合,属于同一类特征的特征点的描述子组成单词。 在局部建图线程中,处理完一个关键帧后,会将其放入回环检测线程 在使用关键帧数据库搜索候选关键帧组(DetectLoopCandidates)的时候&…

nginx 启动 + uwsgi + django
https://www.cnblogs.com/chenice/p/6921727.html https://blog.csdn.net/Aaroun/article/details/78218131转载于:https://www.cnblogs.com/pythonClub/p/9746866.html

poj1741(树的点分治)
题目连接:POJ - 1741 看了好长时间才明白了点...... 网上讲解很多但感觉都不够详细。。。大概是太弱了吧-_-|| 学通了再回来写详解。。。 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 #include<algorithm>5 #define LL lo…

Android 串口通讯
概念 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一…

Linux07-OpenSSH
目录 一、使用SSH访问远程主机 1.1、什么是OpenSSH Secure Shell(SSH) 1.2、SSH主机密钥 二、配置基于SSH密钥的身份验证 2.1、基于SSH密钥的身份验证 2.2、自定义SSH服务配置 2.3、sftp传输文件 一、使用SSH访问远程主机 1.1、什么是OpenSSH Se…

ORB_SLAM2中的Sim3变换
对于双目、RGB-D相机,可获得深度,因此不存在尺度问题,因此Sim3中的尺度s1。 (1)通过词袋加速算法实现当前帧、闭环帧的特征点的匹配,建立闭环帧的路标点和当前帧的特征点间的联系。 (2ÿ…

Ubuntu16.04 下的网易云出现网络异常、无法播放,界面无响应问题的统一解决
能够在Linux系统下体验到原生界面的网易云音乐是件不错的事情,但是它总是经常性的出现网络异常,界面无响应的问题 为了听歌的体验,进行深入探究: 首先通过终端启用网易云音乐:sudo netease-cloud-music 会得到网易云音…

SpringBoot 概念和起步
一、概念和由来 1、什么是 Spring Boot Spring Boot 的设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用特定方式来进行配置,从而使开发人员不再需要定义样板化的配置。 Spring Boot 其实不是什么新的框架,它默认配置了很多框架的使用…

WKWebView Safari调试、JS互调、加载进度条、JS中alert、confirm、prompt
主要内容 Safari调试swift/OC与JS互调增加加载进度条支持JS中alert、confirm、prompt Safari调试 设置 —> safari --> 高级,开启JavaScript、网页检查器 打开Safari浏览器,选择调试的网页,同样在js里面可以断点调试: swift/OC与JS互调 这里…

CentOS7 打包RPM 升级OpenSSH8.3
目录 一、源码包 二、打包RPM 2.1、准备阶段 2.2、打包排错阶段 三、升级 漏扫设备发现OpenSSH有漏洞,需要升级到OpenSSH 8.1及以上版本,那么干脆就直接升级到发文时最新的版本,OpenSSH 8.3。做法是找到OpenSSH 8.3的源码包,…

步步为营-44-窗体之间传值--观察者模式
说明 :观察者模式又叫发布-订阅模式,其中又涉及到中介者模式 1 结构 2 创建Main窗体(中介者),ChildForm1(发布者),ChildForm2(订阅者),ChildForm3(订阅者), 2.1 ChildForm1中添加按钮,当按钮被点击是ChildForm2(订阅者),ChildForm3(订阅者),的文本框汇中获取信息 2.2 定义接口 …

java指令详解
Java是通过java虚拟机来装载和执行编译文件(class文件)的,java虚拟机通过命令java option 来启动,-option为虚拟机参数,通过这些参数可对虚拟机的运行状态进行调整. 一、如何查看参数列表: 虚拟机参数分为基本和扩展两…

wrs-arcface虹软人脸识别
前言 虹软人脸识别组件,支持活体识别、离线识别、图片人脸特征识别、图片是否同一人对比、相机人脸识别或对比,虹软免费版请使https://ext.dcloud.net.cn/plugin?id6084 功能 支持活体识别、离线识别图片人脸特征识别(年龄、性别、3DAngle)两张图片是否是同一人…

C++指针与引用的区别
(1)指针是一个变量,本身占有内存,内存中存储的是所指向对象的地址。引用是内存的别名。 (2)指针可以通过解引用的方式,取出所指向内存中的值。引用没有解引用。 (3)指针可…

Linux08-日志
目录 一、systemd的日志 1.1、sytemd-journald与systemd日志 1.2、systemd日志的持久化 二、系统常规日志 2.1、系统日志概述 2.2、查看系统日志文件 2.3、日志的轮转 2.4、分析系统日志 2.5、使用logger发送消息到日志 RHEL7的日志由2个服务负责记录,分别…

Java的小实验——各种测试以及说明
日期:2018.10.07 星期五 博客期:014 一、Java中的位运算 代码如下: 1 package Morts107;2 3 public class Test107 {4 public static void main(String[] args) {5 int z;6 z 13>>1;//00001101(13)---------------…

C++内存的分区
C内存分为四个区: (1)代码区:存放代码转译成的二进制代码。 (2)全局区:存放全局变量、静态变量(static)、常量(如字符串常量)。 全局区中还包含一…

SpringCloud的服务网关zuul
演示如何使用api网关屏蔽各服务来源 一、概念和定义 1、zuul最终还是使用Ribbon的,顺便测试一下Hystrix断路保护2、zuul也是一个EurekaClient,访问服务注册中心,获取元数据,使用本地的Ribbon负载均衡,Hystrix断路保护&…

wrs-tuya-cloud
前言 wrs-tuya-cloud是涂鸦官网针对云开发的插件,包含垂直品类硬件API(万能红外开放能力、设备连接服务、设备OTA固件升级、实时音视频、睡眠带开放能力、体脂秤开放能力、智能门锁开放能力、视频云存储 、邮件服务 、 语音消息服务、消息推送服务、短信服务 、内测…

Windows Server 2016 笔记
从业界普遍实践结果来看,Windows Server在服务器领域真是不太好用。但是,有些时候由于种种原因不得不用,所以还是有必要了解一下的。今天参加了一个Windows Server的培训,主要面对Windows Server 2016,写下这篇博客备忘…

(办公)网页发送到桌面快捷方式怎么做
转载自百度:https://jingyan.baidu.com/article/f79b7cb303d50a9145023e6e.html 有时候一个网页我们需要经常用到,每次找那个需要的网页很耗时间,那么我们怎么把我们需要的网页发送到桌面快捷方式呢? 这样下次我们直接点击桌面上的快捷方式就…

C++程序编译过程
程序编译的过程,是将源代码转换为计算机可执行的机械语言的过程。分为预处理、编译、汇编、链接四步。 (1)预处理:对程序进行预处理,比如将头文件的代码直接赋值到当前代码中等等. (2)编译&am…

Java的注释(详细版)
注释是对代码进行必要的说明,以便于后期的修改、维护和升级。Java的注释分为三种:第一种是**单行注释**:用双斜杠“//”来进行实例://单行注释第二种是**文档注释**:用斜杠“/”和星号“*”来进行实例:/***…

Hadoop的存储架构介绍
http://lxw1234.com/archives/2016/04/638.htm 该文章介绍了Hadoop的架构原理,简单易懂。 目前公司提供Hadoop的运算集群BMR,可以直接申请集群资源。转载于:https://www.cnblogs.com/blog-of-Fourier/p/6809811.html

编译OpenSSH8.4的RPM包及升级
目录 一、安装相关依赖包 二、创建rpmbuild目录并下载源码 三、打包及排错 四、升级到OpenSSH 8.4p1 以下是打包好的OpenSSH 8.4p1,包括7个rpm包,欢迎下载使用。 OpenSSH-8.4p1-Bundle 一、安装相关依赖包 根据以往经验,需要安装wget、…

centos 系统使用verdaccio搭建npm私库
.安装nodejs yum install -y nodejs 2.安装verdaccio npm install -g verdaccio --unsafe-perm 3.配置 a.修改配置文件 config.yaml,在其最后添加监听端口(使其可在外网访问) listen: 0.0.0.0:4873 b.对外开放4873端口 firewall-cmd --state …

视觉SLAM中PNP求解
PNP(Perspective-n-points)是SLAM中估计位姿的重要方法。已知条件为路标点在相机1中的相机坐标以及投影到相机2中的像素坐标,据此去估计相机1、相机2间的位姿。主要解法包括DLT、P3P、EPNP P3P 已知A、B、C在相机1坐标系下的坐标࿰…