GitHub 项目地址:https://github.com/lidecong133/YModbus
做工业上位机、设备调试、数据采集这些东西,绕不开一个协议:Modbus。
不管是 PLC、仪表、传感器、变频器,还是 RS485 模块、串口服务器、Modbus 网关,很多设备最后都会丢给你一句话:
支持 Modbus RTU / Modbus TCP。
听起来挺简单,对吧?
但真正做项目的时候,就会发现事情没那么轻松。
有的设备地址从0开始,有的手册写40001;
有的浮点数是高字在前,有的是低字在前;
有的设备响应慢,需要重试;
有的网关下面挂了多个从站,要区分slaveID;
有时候你还得自己模拟一个从站,测试主站程序到底有没有问题。
这些东西单独看都不难,但凑到一个真实项目里,就很容易变成一堆细碎的问题。
工控调试人员最头疼的地方
做工控调试的人,最怕的其实不是“协议本身有多难”。
真正麻烦的是:现场信息经常是不完整的。
设备手册可能只有几页,写着“支持 Modbus RTU”,然后给你一张寄存器表。
但是它不一定告诉你地址到底是从0开始,还是从1开始。
不一定告诉你浮点数是高字在前,还是低字在前。
也不一定告诉你这个功能码到底支不支持,异常码返回以后应该怎么判断。
还有更常见的情况:
- 串口参数不确定,波特率、校验位、停止位要一个个试
- RS485 的 A/B 线接反了,软件看起来就像设备没响应
- 网关下面挂了多个从站,但是
slaveID对不上 - TCP 能连上,但是读寄存器一直超时
- 手册写的是
40001,程序里到底填0还是1,现场容易吵起来 - 读出来的数据是
16856,但你明明想要的是温度23.5 - 厂家说设备没问题,软件说报文没问题,最后谁都得看原始报文
调试的时候,客户站在旁边等结果,设备厂家电话里也说不清楚,这种压力大家都懂。
所以这个系列不会只讲“YModbus 这个库怎么用”。
我会把 Modbus 协议相关的核心内容也放进来,尽量用现场调试能听懂的方式讲清楚:
- Modbus TCP、RTU、ASCII 到底有什么区别
slaveID/UnitId是什么- 线圈、离散输入、保持寄存器、输入寄存器怎么区分
- 功能码
01、02、03、04、05、06、15、16分别干什么 - 为什么地址经常差 1
- RTU 报文里的 CRC 怎么看
- TCP 报文里的 MBAP 头是什么
- 异常码返回以后怎么判断问题
int、float、double为什么要关心字节序和字序
我的目标很简单:
哪怕你以前只是会用调试软件点几下,跟着这个系列看下来,也能慢慢明白 Modbus 的核心逻辑。
以后再遇到设备不通、数据不对、地址不明白、浮点数解析错误这些问题,至少能知道从哪里下手,而不是只能盲试。
所以我准备做一个自己的 Modbus 通讯库,名字叫:
YModbus
这个系列文章,会先从 Modbus 协议讲起,然后介绍 YModbus 通讯库,最后再介绍主站和从站调试工具的使用。
为什么要自己做一个库?
其实 .NET 里面已经有一些 Modbus 库可以用。
如果只是简单读几个寄存器,很多库都能完成任务。
那为什么还要自己做?
原因很简单:我想要一个自己完全可控的工业通讯基础库。
工业软件和普通业务软件不太一样。
普通软件出问题,大不了刷新一下页面。
工业现场通讯出问题,可能就是设备不响应、数据采不上来、客户现场调不通。
所以通讯库对我来说,不能只是“能用”就行,还要做到几件事:
- 代码结构清楚,后面好维护
- TCP、RTU、ASCII 都能覆盖
- 主站、从站都要有
- 报文收发过程能看得见
- 异常、超时、重试要能控制
- 后面能服务自己的主站/从站调试工具
这也是 YModbus 的定位。
它不是只做一个 NuGet 包,而是希望把协议学习、通讯库和调试工具慢慢串起来。
YModbus 准备解决什么问题?
我给 YModbus 定了几个比较实际的目标。
第一个是做一个干净的 Modbus 核心库。
包括:
- Modbus TCP
- Modbus RTU
- Modbus ASCII
- 常用功能码
- CRC / LRC 校验
- 寄存器读写
- 异常响应处理
- 寄存器类型转换
比如最常见的读取保持寄存器:
ushort[]registers=awaitclient.ReadHoldingRegistersAsync(0,4);这类代码要尽量简单。
你只关心从哪个地址读、读几个,底层报文怎么拼、CRC 怎么算、TCP 帧怎么处理,都交给库去做。
第二个目标,是做好从站模拟。
很多时候我们开发主站程序,手里不一定有真实设备。
或者设备在客户现场,不可能一直连着调试。
这时候一个好用的从站模拟器就很重要。
YModbus 里面会有从站数据区,比如:
- Coils
- Discrete Inputs
- Holding Registers
- Input Registers
也可以做 TCP 从站、RTU 从站、ASCII 从站。
后面调试软件里面,也会直接把这些数据区用表格显示出来,方便手动改数据、看报文。
第三个目标,是做调试软件。
库只是给开发者用的。
但很多时候,现场工程师更需要一个工具。
所以我会同时做:
- YModbus 主站调试软件
- YModbus 从站模拟软件
主站工具用来连接设备、读取寄存器、写线圈、写寄存器、看通讯报文。
从站工具用来模拟设备,测试主站程序。
这两个调试工具会完全免费使用。
不搞激活码,不搞功能锁,也不靠收费解锁功能。工具本身先让大家能用起来。
YModbus 现在是什么状态?
YModbus 现在已经放到了 GitHub 上。
我把它放出来,不是想简单丢一个压缩包,而是希望大家能看到这个库是怎么一步步做起来的。
对工业通讯库来说,透明度还是挺重要的。
你能看到代码怎么组织,功能码怎么处理,TCP、RTU、ASCII 的报文怎么收发,异常和重试是怎么设计的。这样以后真要用到项目里,心里会更有底。
当然,现在它还不是一个“什么都完美”的成熟库。
我更愿意把它看成一个正在持续完善的工程:
- 核心通讯库会继续补功能
- 示例代码会尽量写得更清楚
- 文档会慢慢补完整
- 主站和从站调试工具会保持免费
- 遇到现场调试中常见的问题,也会逐步整理到文档里
如果你只是想学习 Modbus,可以从文章和 samples 开始看。
如果你是做上位机、PLC 通讯、仪表采集或者网关调试,也可以直接把项目拉下来跑一跑,看一下它的 API 和调试工具是不是顺手。
我希望这个项目不是只放在那里给人“看一眼”,而是真的能慢慢变成一个对工控调试有帮助的工具包。
这个系列准备写什么?
这个专栏不会一上来就贴一堆源码。
我想按调试人员真正上手的顺序来写。
第一部分,先讲Modbus 协议。
这一部分会把基础概念讲清楚,比如:
- Modbus 协议到底是什么
- TCP、RTU、ASCII 有什么区别
- 主站、从站、
slaveID怎么理解 - 线圈、离散输入、保持寄存器、输入寄存器有什么区别
- 功能码和寄存器怎么对应
- 为什么地址经常差 1
- RTU 报文、TCP 报文、ASCII 报文怎么看
- CRC、LRC、异常码这些东西到底有什么用
- 浮点数、整数、字节序、字序怎么处理
第二部分,再讲YModbus 通讯库。
也就是怎么用代码去做这些事情:
- 怎么创建 TCP、RTU、ASCII 主站客户端
- 怎么读取线圈和寄存器
- 怎么写线圈、写保持寄存器
- 怎么处理异常、超时和重试
- 怎么做寄存器类型转换
- 怎么搭建一个 Modbus TCP 从站
- 怎么模拟多个
slaveID
第三部分,讲YModbus 主站和从站调试工具。
这两个工具会完全免费。
主站工具用来连接真实设备、读写数据、查看报文;从站工具用来模拟设备、测试主站程序、排查通讯问题。
我希望这个系列不只是“库的使用说明”,而是真的能让调试人员把 Modbus 通讯这件事理解清楚,然后能快速上手。
写在最后
做 YModbus 这个项目,本质上是想把工业通讯里那些零散的东西收拢起来。
协议是一部分。
代码库是一部分。
调试工具是一部分。
如果这三块能慢慢串起来,学习 Modbus、写通讯程序、现场调试设备就会顺很多。
这也是我做 YModbus 的真正原因。
只有先搞明白功能码、寄存器、地址、报文格式,后面看 YModbus 的代码和使用调试工具时,才不会觉得突兀。