当前位置: 首页 > news >正文

(三)YModbus上手:先把寄存器读出来

GitHub 项目地址:https://github.com/lidecong133/YModbus

前面两篇先把为什么做 YModbus、Modbus 协议的基本概念讲了一遍。

这一篇开始写代码。

不用一上来就想着把所有功能码都用一遍,也不用急着研究各种高级封装。

工控调试里,第一步通常很简单:

我能不能连上设备,并且读到一组正确的寄存器?

只要这一步通了,后面写参数、读 float、批量轮询、多设备采集,都是在这个基础上往上加。

先记住几个参数

用 YModbus 读设备之前,先把下面几个东西搞清楚:

参数RTU 场景TCP 场景
连接方式串口,比如COM3IP 和端口,比如192.168.1.10:502
设备编号slaveIDunitId
功能码比如03读保持寄存器一样
起始地址协议地址,通常从0开始一样
数量要读几个线圈或寄存器一样

这里特别注意地址。

如果设备手册写的是40001,很多时候代码里要填的是0,不是40001

因为40001通常表示“保持寄存器区第 1 个点”,而不是报文里真的发送地址40001

从 RTU 开始

现场最常见的还是 Modbus RTU。

比如电脑通过 USB 转 RS485 接一个仪表,仪表站号是1,波特率9600,我们想读保持寄存器地址0开始的 4 个寄存器。

用 YModbus 大概就是这样:

usingSystem.IO.Ports;usingYModbus.Clients;usingYModbus.Serial;usingSerialPortport=new("COM3"){BaudRate=9600,DataBits=8,Parity=Parity.None,StopBits=StopBits.One,ReadTimeout=2000,WriteTimeout=2000};port.Open();byteslaveID=1;ushortstartAddress=0;ushortquantity=4;awaitusingModbusClientclient=ModbusSerialClientFactory.CreateRtu(slaveID,port,leaveOpen:true);ushort[]registers=awaitclient.ReadHoldingRegistersAsync(startAddress,quantity);foreach(ushortvalueinregisters){Console.WriteLine(value);}

这段代码做的事情其实很直白:

  1. 打开串口
  2. 创建 RTU client
  3. 用功能码03读取保持寄存器
  4. 拿到ushort[]结果

YModbus 里ReadHoldingRegistersAsync对应的就是功能码03

如果现场读不到,先不要急着改代码,先查这几件事:

  • 串口号是不是对的
  • 波特率是不是对的
  • 校验位是不是对的
  • slaveID是不是对的
  • 地址是不是应该从0开始
  • 设备是不是支持功能码03

很多现场问题,最后都是这些参数里有一个没对上。

写保持寄存器

读通以后,再考虑写。

比如从地址100开始写 3 个保持寄存器:

ushortstartAddress=100;ushort[]values=newushort[]{1,2,3};awaitclient.WriteMultipleRegistersAsync(startAddress,values);

这个方法对应功能码16,也就是0x10

如果只写一个寄存器,可以用:

awaitclient.WriteSingleRegisterAsync(100,123);

这个对应功能码06

写操作要比读操作谨慎。

读错了,大多数时候只是读不到或者数据不对。写错了,可能会把设备参数改掉,甚至影响现场动作。

所以刚开始调试时,我一般建议:

  • 先读
  • 再写不影响设备运行的测试地址
  • 确认设备手册里的写入范围
  • 确认写入值有没有单位和倍率

比如手册写“温度设定值,单位 0.1 ℃”,那你想写25.0 ℃,可能实际要写250

TCP 怎么写

Modbus TCP 的代码更短一些,因为不用自己配置串口参数。

比如连接127.0.0.1:1502,UnitId 是1

usingYModbus.Clients;awaitusingModbusClientclient=awaitModbusClientFactory.CreateTcpAsync(host:"127.0.0.1",port:1502,unitId:1);ushort[]registers=awaitclient.ReadHoldingRegistersAsync(0,4);foreach(ushortvalueinregisters){Console.WriteLine(value);}

这里再强调一下:

CreateTcpAsync创建的是 Modbus TCP client,它会主动连接对方的 TCP server。

这个 client/server 是 TCP 通讯关系,不要简单理解成主站/从站。

你在代码里填的unitId,更多是 Modbus 报文里的 Unit Identifier。直连普通 TCP 设备时,很多设备填1就可以;如果是 TCP 转 RTU 网关,它后面可能挂了多个 RTU 设备,这时unitId往往就对应后面的 RTU 站号。

一个 client 固定一个 UnitId

上面的ModbusClient有一个特点:创建时就指定了slaveIDunitId

也就是说,它适合这种场景:

我现在主要跟一个设备通讯。

比如:

awaitusingModbusClientclient=awaitModbusClientFactory.CreateTcpAsync("192.168.1.10",502,unitId:1);

后面这个client发出去的请求,默认都发给unitId = 1

如果你要在同一条连接里轮询多个 UnitId,可以用ModbusMasterClient

awaitusingModbusMasterClientmaster=awaitModbusClientFactory.CreateTcpMasterAsync("192.168.1.10",502);ushort[]unit1=awaitmaster.ReadHoldingRegistersAsync(1,0,10);ushort[]unit2=awaitmaster.ReadHoldingRegistersAsync(2,0,10);

这样每次调用时都可以传不同的 UnitId。

这在网关场景很有用。

读 float 和 int32

Modbus 寄存器本身是 16 位的。

但现场很多数据不是 16 位,比如:

  • int32
  • uint32
  • float
  • double

这种数据一般会占多个寄存器。

YModbus 里可以先读原始寄存器:

ushort[]registers=awaitclient.ReadHoldingRegistersAsync(0,2);

也可以用 typed helper 直接转成 .NET 类型:

usingYModbus.Clients;usingYModbus.Protocol;floattemperature=awaitclient.ReadHoldingRegisterSingleAsync(startAddress:0,wordOrder:ModbusWordOrder.HighWordFirst,byteOrder:ModbusByteOrder.BigEndian);

这里最容易出问题的是字节序和字顺序。

如果读出来的 float 特别离谱,比如一个温度读成了一个很大的数,先别怀疑设备坏了,优先查:

  • 高字在前还是低字在前
  • 每个寄存器内部是不是大端
  • 手册里有没有写 ABCD、CDAB、BADC、DCBA 这种顺序

YModbus 里用ModbusWordOrderModbusByteOrder来控制这件事。

RetryOptions 什么时候用

工业现场通讯不一定每次都很稳。

偶尔一次超时、设备忙、网关后面的设备没响应,都可能遇到。

YModbus 里可以在创建 client 时传ModbusRetryOptions

usingYModbus.Transports;ModbusRetryOptionsretryOptions=new(){RetryCount=2,RetryDelayMilliseconds=100};awaitusingModbusClientclient=awaitModbusClientFactory.CreateTcpAsync("192.168.1.10",502,unitId:1,retryOptions:retryOptions);

这里的RetryCount = 2,意思是第一次请求失败后,最多再重试 2 次。

重试不是万能的。

如果地址错了、功能码错了、站号错了,重试多少次都没用。

它更适合处理偶发性的通讯抖动。

先跑 samples

如果你刚拿到项目,不想一上来就写代码,可以先跑 sample。

TCP 可以先启动一个本地从站模拟:

dotnet run--project.\samples\YModbus.Sample.TcpSlave

再开一个终端读它:

dotnet run--project.\samples\YModbus.Sample.TcpClient--127.0.0.1 1502 1 0 4

RTU 需要真实串口设备,比如:

dotnet run--project.\samples\YModbus.Sample.RtuClient--COM3 9600 1 0 4

这几个参数分别是:

参数含义
COM3串口号
9600波特率
1slaveID
0起始地址
4读取数量

先把 sample 跑通,再复制里面的关键代码到自己的项目里,会比一开始就硬写省很多时间。

我建议的调试顺序

用 YModbus 调设备时,我建议按这个顺序来:

  1. 先确认通讯方式:RTU 还是 TCP
  2. RTU 先确认串口参数,TCP 先确认 IP 和端口
  3. 先读保持寄存器,不要一上来就写
  4. 手册写40001时,代码里优先试地址0
  5. 先读ushort[]原始值,再处理floatint32
  6. 原始值对了,再做单位、倍率、字节序转换
  7. 最后再考虑批量轮询、重试、异常处理

这样排查起来会比较稳。

很多时候不是库的问题,也不是设备的问题,而是地址、功能码、站号、字节序这些基础信息没有对齐。

写在最后

YModbus 的目标不是把 Modbus 包装得看不见。

我更希望它做两件事:

  • 常见读写操作写起来简单
  • 真出问题时,还能看得懂底层到底在干什么

所以你会看到它既有ReadHoldingRegistersAsync这种直接可用的方法,也保留了slaveIDunitId、功能码、寄存器地址这些 Modbus 里本来就很重要的概念。

对工控调试来说,这样反而更踏实。

因为现场最怕的不是代码多写几行,而是出了问题以后完全不知道从哪里查。

http://www.jsqmd.com/news/1000692/

相关文章:

  • 2026成都菁英单招集训重磅开启!专属惊喜福利+官方直通联系方式 - 成都单招培训
  • OpenPLC:开源工业控制器的革命性选择
  • 昆明名表回收深度测评(2026)|黄金波动下,劳力士欧米茄变现谁更稳 - 奢侈品回收评测
  • 2026广州发明专利申请机构测评|核心技术/材料配方/软件算法专利精细化撰写、实质审查答辩、高授权率辅导服务商推荐TOP3 - 信息热点
  • 3分钟搞定缠论分析:ChanlunX通达信插件完整指南
  • 2026 无锡顶奢手表江诗丹顿回收,权威鉴定精准估价无套路 - 奢侈品回收评测
  • 江苏低分考生复读优选,南京头部复读学校排名盘点 - 信息热点
  • 别再死记硬背了!用‘矛盾特殊性’搞定你的Spring Boot多环境配置难题
  • 专访|广州企业布局AI流量怎么选靠谱GEO公司?业内专家给出标准答案 - 信息热点
  • OBS多平台直播终极指南:3步实现高效多路推流方案
  • 老宁波人出手闲置钻戒,实体门店称重检测无套路 - 奢侈品交易观察员
  • 实测福州本地手表回收:欧米茄全系列报价,海马超霸星座哪家高? - 奢侈品回收评测
  • 揭秘!贴片式弹簧顶针生产厂家的那些事儿 - 信息热点
  • 关于动态规划【力扣96.不同的二叉搜索树的递推公式怎么理解?】
  • 2026 最新!海南海口注册公司流程 费用,新手零踩坑指南 - 信息热点
  • Python+Django实战|个人家庭记账理财系统:多账户管理、收支分类、日常记账、预算管控、账单检索、数据可视化、报表导出
  • 2026广州各区发明专利布局指南|高含金量专利挖掘、技术交底文件优化、分区差异化布局策略,优质专利代理机构推荐TOP3 - 信息热点
  • 从WMS到WMTS:为什么你的Web地图加载慢?聊聊瓦片金字塔技术的演进与实战
  • 成都庆典策划公司怎么选?开业盛典策划周年庆典剪彩奠基启动揭牌一站搞定 - 信息热点
  • 终极3步方案:无需Steam客户端轻松下载创意工坊模组
  • 成都2026房产社区配套 “重宣传轻落地”,润达丰测如何选择配套完善的宜居社区? - 信息热点
  • 口腔执业医师历年真题资料开箱评测 - 医考机构品牌测评专家
  • 加筋挡土墙施工,土工格栅的铺设规范要求
  • 河北电焊防爆墙厂家实力排行:5家合规企业盘点 - 奔跑123
  • 别再乱选了!南宁 7 家黄金回收实地测评,套路全曝光 - 奢侈品回收评测
  • 网页设计没思路?5 个宝藏网站,让你作图效率翻倍
  • 西安除甲醛公司六大品牌解读:契合关中气候与城市格局的选择参考 - 信息热点
  • 如何快速掌握AI视频修复:终极完整教程
  • 柯桥区原配起诉小三追回财产,律师怎么选?2026年本地实测盘点 - 边虞技术
  • NSK极限重载滚珠丝杠DFD 10010-6详解