文章目录

  • 前言
  • 一、Modbus概念
  • 二、使用步骤
    • 1.使用Modbus准备
    • 2.使用步骤
  • 三、Modbus RTU 与 Modbus ASCII对比


前言

Modbus通信协议!


一、Modbus概念

从站设备编码(从站地址、单元ID),一主多从。
存储区:0-线圈状态、1-输入线圈(只读)、3-输入寄存器(只读)、4-保持型寄存器
协议公开的,设备可以支持 1-65535
功能码:
线圈状态(01-读取,05-单写,15-多写)
输入线圈(02-读取)
输入寄存器(04-读取)
保持型寄存器(03-读取,06-单写,16-多写)
协议分类:ModbusRTU、ModbusASCII、ModbusTCP

二、使用步骤

1.使用Modbus准备

1、下载ModbusSalve和ModbusPoll软件
ModbusPoll是主站
在这里插入图片描述
ModbusSalve是从站
在这里插入图片描述
Modbus是一主多从的形式,所以ModbusPoll只能开一个,ModbusSalve可以开多个。
2、安装Modbus4库

2.使用步骤

ModbusRTU和ModbusAscii是基于串口进行通信的所以在使用这两个协议时需要先创建串口。
ModbusRTU

SerialPort port = new SerialPort("COM3",9600,Parity.None,8,StopBits.One);
port.Open();
// 创建ModbusRTU通信协议对象
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);
master.Transport.ReadTimeout = 2000;// 设置超时时间
master.Transport.Retries = 3;// 设置重试次数
// 读取从站地址1的保存型寄存器0~9
ushort[] registers = master.ReadHoldingRegisters(slaveAddress: 1,// 从站地址(1-247)startAddress: 0,// 起始寄存器地址numberOfPoints: 10// 读取寄存器数量);
// 异步读取从站地址1的保存型寄存器0~9
//Task<ushort[]> taskRegisters = master.ReadHoldingRegistersAsync(1, 0, 10);
// 第一种处理异步方法的返回值,所在方法不需要变更异步方法
//ushort[] registersAsync = taskRegisters.GetAwaiter().GetResult();
// 第二种处理异步方法的返回值,所在方法需要变更为异步方法
//ushort[] registersAsync = await master.ReadHoldingRegistersAsync(1, 0, 10);
Debug.WriteLine($"保持寄存器值:{string.Join(",", registers)}");
// 读取从站地址1的输入型寄存器0~9
ushort[] inputRegisters = master.ReadInputRegisters(slaveAddress: 1,startAddress: 0,numberOfPoints: 6);
// 异步读取从站地址1的输入型寄存器0~9
//ushort[] inputRegistersAsync = await master.ReadInputRegistersAsync(1, 0, 6);
Debug.WriteLine($"输入寄存器值:{string.Join(",", inputRegisters)}");
// 读取从站地址1的线圈状态0~7
bool[] coils = master.ReadCoils(slaveAddress: 1,startAddress: 0,numberOfPoints: 8);
// 异步读取从站地址1的线圈状态0~7
//bool[] coilsAsync = await master.ReadCoilsAsync(1, 0, 8);
Debug.WriteLine($"读取线圈状态:{string.Join(",", coils.Select(c=>c.ToString()))}");
// 读取从站地址1的输入线圈0~7
bool[] inputCoils = master.ReadInputs(slaveAddress: 1,startAddress: 0,numberOfPoints: 8);
// 异步读取从站地址1的输入线圈0~7
//bool[] inputCoilsAsycn = await master.ReadInputsAsync(1, 0, 8);
Debug.WriteLine($"读取输入线圈:{string.Join(",", inputCoils.Select(c => c.ToString()))}");
// 写入单个寄存器,向从站1的寄存器6号地址写入数据
//master.WriteSingleRegister(1,6,11111);
ushort[] writeValue = { 1, 2, 3 };
// 写入多个寄存器,向从站1的寄存器0号地址、1号地址、2号地址中依次写入三个数据写入数据
//master.WriteMultipleRegisters(1, 0, writeValue);// 大小端字节序问题
//例如 300的16进制为12C,可以使用两个字节来表示 0x01 0x2C
// 大端字节序:高位在前低位在后
// 0x01 0x2C 存储在字节数组中 datas[0] = 0x01 datas[1] = 0x2C
//小端字节序:低位在前高位在后
// 0x2C 0x01 存储在字节数组中 datas[0] = 0x2C datas[1] = 0x01
// 一个寄存器地址存储2个byte字节
float v7 = 4.5f; // 浮点型数据占4个字节,但是Modbus协议只能传输2个字节的ushort数据
// 首先将浮点数据转换成字节数组,连续两次发送数据
// 获取浮点数据对应的字节信息,C#中的字节转换后的字节数据为小端字节序,然而Modbus协议要求的是大端字节序,所以后面还需处.单最终还得以设备方要求为准.
byte[] v7_bytes = BitConverter.GetBytes(v7);
// 将上面大端数据转换成小端顺序,也就是反转一下数组
Array.Reverse( v7_bytes );// 转换成大端顺序
// 将处理好的浮点型的字节数组转换成ushort数据类型
// 在转换后有4个字节两两一组,一组字节中前面那个字节为高位字节,后面的字节为低位字节,如果需要将字节转换成ushort类型
// ushort类型为16为其中前8位为高位,后8位为低位,如果需要将两个字节转换成16位,则高位字节需要左移8为也就是乘以256,将左移后的
// 数据与低位相加也就得到一个转换后的ushort数据.
ushort s1 = (ushort)(v7_bytes[0] * 256 + v7_bytes[1]);
// 使用C#自带的BitConverter来将字节数据转换成ushort类型
s1 = BitConverter.ToUInt16(new Byte[] { v7_bytes[1], v7_bytes[0] });// 注意:C#自带的BitConverter方法转换是按小端字节序,所以传入的字节数组得是小端字节序否则数据转换错误
//将浮点型的后两位转换成ushort类型
ushort s2 = (ushort)(v7_bytes[2] *256+v7_bytes[3]);
s2 = BitConverter.ToUInt16(new Byte[] { v7_bytes[3], v7_bytes[2] });
ushort[] floatToUshort = new ushort[2]; 
floatToUshort[0] = s1;
floatToUshort[1] = s2;
master.WriteMultipleRegisters(1,8,floatToUshort);// 读取从站地址为1的保持型寄存器8~9(读取浮点型数据)
ushort[] fs = master.ReadHoldingRegisters(1, 8, 2);
// 将读取到的ushort类型的数据转换成byte类型
byte[] us_byte_1 = BitConverter.GetBytes(fs[0]);// BitConverter方法得到的是小端字序
byte[] us_byte_2 = BitConverter.GetBytes(fs[1]);
// 得把小端字序改成大端字序
byte[] f_bytes = new byte[4]
{us_byte_1[1],us_byte_1[0],us_byte_2[1],us_byte_2[0]
};
Array.Reverse(f_bytes);
float f2 = BitConverter.ToSingle(f_bytes, 0);// BitConverter需要小端所以需要使用Array.Reverse将大端转换成小端// 向从站1的0号线圈写入True状态
master.WriteSingleCoil(1, 0, true);
// 向从站1的5号线圈连续写入5个状态
master.WriteMultipleCoils(1, 5, new bool[] { true, true, true, true, true });//异步执行写入操作
//master.WriteSingleCoilAsync(1, 0, true);//master.WriteMultipleCoilsAsync(1, 5, new bool[] { true, true, true, true, true });//master.WriteSingleRegisterAsync(1, 6, 11111);//master.WriteMultipleRegistersAsync(1, 0, writeValue);

ModbusASCII
修改上面代码

将 IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);中的CreateRtu替换成CreateAscii

三、Modbus RTU 与 Modbus ASCII对比

特性Modbus RTUModbus ASCII
数据表示方式二进制格式,每个字节包含 8 位数据ASCII 码格式,每个字节用两个 ASCII 字符表示
传输效率高效,数据紧凑,适合大量数据传输较低,数据量是 RTU 模式的两倍左右
校验方式CRC(循环冗余校验),检测能力强LRC(纵向冗余校验),检测能力相对较弱
通信线路要求要求较高,对数据准确性敏感要求相对较低,对噪声和干扰有一定容忍度
适用场景工业自动化设备间的高速可靠通信与旧设备集成、调试阶段或通信速率要求不高的系统
抗干扰能力较弱,需采取抗干扰措施较强,有一定容错能力
实现复杂度较复杂,需处理二进制编码和 CRC 校验较简单,易于实现

工业场景一般使用ModbusRTU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87784.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87784.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/87784.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前后端分离架构下的跨域问题与解决方案

在现代Web开发中&#xff0c;特别是随着前后端分离架构的普及&#xff0c;跨域问题成为了开发者必须面对的一个重要议题。本文将详细介绍什么是跨域问题、其产生的原因以及如何从前端和后端两个角度来解决这个问题&#xff0c;并提供一些实用的代码示例。一、跨域问题概述1. 定…

搜索数据建设系列之数据架构重构

导读 主要概述百度搜索业务数据建设的创新实践&#xff0c;重点围绕宽表模型设计、计算引擎优化和新一代业务服务交付模式&#xff08;图灵3.0开发模式&#xff09;三大方向&#xff0c;解决了传统数仓在搜索场景下面临的诸多挑战&#xff0c;实现了搜索数据建设的高效、稳定、…

2025年渗透测试面试题总结-2025年HW(护网面试) 29(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。、 目录 2025年HW(护网面试) 29 1. 样本分析思路 2. Linux GDB分析样本示例 3. 应急案例&#xff1a;WebShell后…

动态编程入门第二节:委托与事件 - Unity 开发者的高级回调与通信艺术

动态编程入门第一节&#xff1a;C# 反射 - Unity 开发者的超级工具箱 动态编程入门第二节&#xff1a;委托与事件 - Unity 开发者的高级回调与通信艺术 上次我们聊了 C# 反射&#xff0c;它让程序拥有了在运行时“看清自己”的能力。但光能看清还不够&#xff0c;我们还需要让…

降低网络安全中的人为风险:以人为本的路径

有效降低网络安全中的人为风险&#xff0c;关键在于采取以人为本的方法。这种方法的核心在于通过高效的培训和实践&#xff0c;使员工掌握安全知识、践行安全行为&#xff0c;并最终培育出安全且相互支持的文化氛围。 诚然&#xff0c;技术和政策必须为良好的安全行为提供支持、…

opencv裁剪和编译

opencv裁剪和编译 0. 准备工作 0.1 下载和安装Eigen 地址 https://eigen.tuxfamily.org/index.php?titleMain_Page对于opencv编译&#xff0c;需要增加EIGEN_INCLUDE_PATH和开启WITH_EIGEN -DWITH_EIGENON -DEIGEN_INCLUDE_PATH./3rd/eigen-3.4.01. 实际脚本 编译脚本如下: ch…

小白成长之路-mysql数据基础(三)

文章目录一、主从复制二、案例总结一、主从复制 1、master开启二进制日志记录2、slave开启IO进程&#xff0c;从master中读取二进制日志并写入slave的中继日志3、slave开启SQL进程&#xff0c;从中继日志中读取二进制日志并进行重放4、最终&#xff0c;达到slave与master中数据…

通过 Windows 共享文件夹 + 手机访问(SMB协议)如何实现

通过 Windows 共享文件夹 手机访问&#xff08;SMB协议&#xff09; 实现 PC 和安卓手机局域网文件共享&#xff0c;具体步骤如下&#xff1a; &#x1f4cc; 前置条件 电脑和手机连接同一局域网&#xff08;同一个Wi-Fi或路由器&#xff09;。关闭防火墙或放行SMB端口&#…

【Python3教程】Python3高级篇之正则表达式

博主介绍:✌全网粉丝23W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

Redis--黑马点评--达人探店功能实现详解

达人探店发布探店笔记探店笔记类似于点评网站的评价&#xff0c;往往是图文结合&#xff0c;对应的表有两个&#xff1a;tb_blog&#xff1a;探店笔记表&#xff0c;包含笔记中的标题、文字、图片等tb_blog_comments&#xff1a;其他用户对探店笔记的评价tb_blog表结构如下&…

一探 3D 互动展厅的神奇构造​

3D 互动展厅的神奇之处&#xff0c;离不开一系列先进技术的强力支撑 。其中&#xff0c;VR(虚拟现实)技术无疑是核心亮点之一。通过佩戴 VR 设备&#xff0c;观众仿佛被瞬间 “传送” 到一个全新的世界&#xff0c;能够全身心地沉浸其中&#xff0c;360 度无死角地观察周围的一…

C++ 网络编程(15) 利用asio协程搭建异步服务器

&#x1f680; [协程与异步服务器实战]&#xff1a;[C20协程原理与Boost.Asio异步服务器开发] &#x1f4c5; 更新时间&#xff1a;2025年07月05日 &#x1f3f7;️ 标签&#xff1a;C20 | 协程 | Boost.Asio | 异步编程 | 网络服务器 文章目录前言一、什么是协程&#xff1f;二…

【Java21】在spring boot中使用虚拟线程

文章目录 0.环境说明1.原理解析2.spring boot的方案3.注意事项&#xff08;施工中&#xff0c;欢迎补充&#xff09; 前置知识 虚拟线程VT&#xff08;Virtual Thread&#xff09; 0.环境说明 用于验证的版本&#xff1a; spring boot: 3.3.3jdk: OpenJDK 21.0.5 spring boot…

利器:NPM和YARN及其他

文章目录**1. 安装 Yarn&#xff08;推荐方法&#xff09;****2. 验证安装****3. 常见问题及解决方法****① 权限不足&#xff08;Error: EPERM&#xff09;****② 网络问题&#xff08;连接超时或下载失败&#xff09;****③ 环境变量未正确配置****4. 替代安装方法&#xff0…

跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能

众所周知&#xff0c;直播平台与短视频平台的贴纸功能不仅是用户表达个性的方式&#xff0c;更是平台提高用户粘性和互动转化的法宝。 可问题来了&#xff1a;如何让一个贴纸功能&#xff0c;在Android和iOS两大平台上表现一致、运行流畅、加载稳定&#xff1f;这背后&#xff…

JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)

前言 本片文章是学习B站黑马程序员苍穹外卖的学习笔记。因为最近期末周&#xff0c;一直在应付考试所以就学的很少&#xff0c;恰好视频中在讲Nginx反向代理和负载均衡&#xff08;写着对前端的内容做一个复习&#xff09; 概述&#xff1a; 1.web前端主要由三部分组成&…

智能学号抽取系统 V5.4.3.2 —— Vue.js 实现的多功能课堂随机抽签工具

智能学号抽取系统 V5.4.3.2 —— Vue.js 实现的多功能课堂随机抽签工具 在教学或会议场景中&#xff0c;我们经常需要随机抽取一个或多个学号/编号来决定发言者、答题者或者参与者。为了提高效率和公平性&#xff0c;我们可以使用一些智能化的小工具来实现这一过程。 今天介绍…

从0开始学习R语言--Day39--Spearman 秩相关

在非参数统计中&#xff0c;不看数据的实际数值&#xff0c;单纯比较两组变量的值的排名是通用的基本方法&#xff0c;但在客观数据中&#xff0c;很多变量的关系都是非线性的&#xff0c;其他的方法不是对样本数据的大小和线性有要求&#xff0c;就是只能对比数据的差异性&…

WSL - Linux 安装 Anaconda3-2025.06-0 详细教程 [WSL 分发版均适用]

一、检查系统状态 安装前先确认 WSL - Linxu 已正常启动&#xff08;比如 Ubuntu&#xff09;&#xff0c;网络连接稳定&#xff0c;并且系统磁盘有足够空间&#xff0c;一般建议预留至少 5GB 以上的可用空间&#xff0c;避免因空间不足导致安装失败。 二、下载安装包 Anacond…

热血三国建筑攻略表格

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>热血三国建筑攻略表格</title><style>…