(一)YModbus开篇:为什么工控调试离不开 Modbus?
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分别干什么为什么地址经常差 1RTU 报文里的 CRC 怎么看TCP 报文里的 MBAP 头是什么异常码返回以后怎么判断问题int、float、double为什么要关心字节序和字序我的目标很简单哪怕你以前只是会用调试软件点几下跟着这个系列看下来也能慢慢明白 Modbus 的核心逻辑。以后再遇到设备不通、数据不对、地址不明白、浮点数解析错误这些问题至少能知道从哪里下手而不是只能盲试。所以我准备做一个自己的 Modbus 通讯库名字叫YModbus这个系列文章会先从 Modbus 协议讲起然后介绍 YModbus 通讯库最后再介绍主站和从站调试工具的使用。为什么要自己做一个库其实 .NET 里面已经有一些 Modbus 库可以用。如果只是简单读几个寄存器很多库都能完成任务。那为什么还要自己做原因很简单我想要一个自己完全可控的工业通讯基础库。工业软件和普通业务软件不太一样。普通软件出问题大不了刷新一下页面。工业现场通讯出问题可能就是设备不响应、数据采不上来、客户现场调不通。所以通讯库对我来说不能只是“能用”就行还要做到几件事代码结构清楚后面好维护TCP、RTU、ASCII 都能覆盖主站、从站都要有报文收发过程能看得见异常、超时、重试要能控制后面能服务自己的主站/从站调试工具这也是 YModbus 的定位。它不是只做一个 NuGet 包而是希望把协议学习、通讯库和调试工具慢慢串起来。YModbus 准备解决什么问题我给 YModbus 定了几个比较实际的目标。第一个是做一个干净的 Modbus 核心库。包括Modbus TCPModbus RTUModbus ASCII常用功能码CRC / LRC 校验寄存器读写异常响应处理寄存器类型转换比如最常见的读取保持寄存器ushort[]registersawaitclient.ReadHoldingRegistersAsync(0,4);这类代码要尽量简单。你只关心从哪个地址读、读几个底层报文怎么拼、CRC 怎么算、TCP 帧怎么处理都交给库去做。第二个目标是做好从站模拟。很多时候我们开发主站程序手里不一定有真实设备。或者设备在客户现场不可能一直连着调试。这时候一个好用的从站模拟器就很重要。YModbus 里面会有从站数据区比如CoilsDiscrete InputsHolding RegistersInput Registers也可以做 TCP 从站、RTU 从站、ASCII 从站。后面调试软件里面也会直接把这些数据区用表格显示出来方便手动改数据、看报文。第三个目标是做调试软件。库只是给开发者用的。但很多时候现场工程师更需要一个工具。所以我会同时做YModbus 主站调试软件YModbus 从站模拟软件主站工具用来连接设备、读取寄存器、写线圈、写寄存器、看通讯报文。从站工具用来模拟设备测试主站程序。这两个调试工具会完全免费使用。不搞激活码不搞功能锁也不靠收费解锁功能。工具本身先让大家能用起来。YModbus 现在是什么状态YModbus 现在已经放到了 GitHub 上。我把它放出来不是想简单丢一个压缩包而是希望大家能看到这个库是怎么一步步做起来的。对工业通讯库来说透明度还是挺重要的。你能看到代码怎么组织功能码怎么处理TCP、RTU、ASCII 的报文怎么收发异常和重试是怎么设计的。这样以后真要用到项目里心里会更有底。当然现在它还不是一个“什么都完美”的成熟库。我更愿意把它看成一个正在持续完善的工程核心通讯库会继续补功能示例代码会尽量写得更清楚文档会慢慢补完整主站和从站调试工具会保持免费遇到现场调试中常见的问题也会逐步整理到文档里如果你只是想学习 Modbus可以从文章和 samples 开始看。如果你是做上位机、PLC 通讯、仪表采集或者网关调试也可以直接把项目拉下来跑一跑看一下它的 API 和调试工具是不是顺手。我希望这个项目不是只放在那里给人“看一眼”而是真的能慢慢变成一个对工控调试有帮助的工具包。这个系列准备写什么这个专栏不会一上来就贴一堆源码。我想按调试人员真正上手的顺序来写。第一部分先讲Modbus 协议。这一部分会把基础概念讲清楚比如Modbus 协议到底是什么TCP、RTU、ASCII 有什么区别主站、从站、slaveID怎么理解线圈、离散输入、保持寄存器、输入寄存器有什么区别功能码和寄存器怎么对应为什么地址经常差 1RTU 报文、TCP 报文、ASCII 报文怎么看CRC、LRC、异常码这些东西到底有什么用浮点数、整数、字节序、字序怎么处理第二部分再讲YModbus 通讯库。也就是怎么用代码去做这些事情怎么创建 TCP、RTU、ASCII 主站客户端怎么读取线圈和寄存器怎么写线圈、写保持寄存器怎么处理异常、超时和重试怎么做寄存器类型转换怎么搭建一个 Modbus TCP 从站怎么模拟多个slaveID第三部分讲YModbus 主站和从站调试工具。这两个工具会完全免费。主站工具用来连接真实设备、读写数据、查看报文从站工具用来模拟设备、测试主站程序、排查通讯问题。我希望这个系列不只是“库的使用说明”而是真的能让调试人员把 Modbus 通讯这件事理解清楚然后能快速上手。写在最后做 YModbus 这个项目本质上是想把工业通讯里那些零散的东西收拢起来。协议是一部分。代码库是一部分。调试工具是一部分。如果这三块能慢慢串起来学习 Modbus、写通讯程序、现场调试设备就会顺很多。这也是我做 YModbus 的真正原因。只有先搞明白功能码、寄存器、地址、报文格式后面看 YModbus 的代码和使用调试工具时才不会觉得突兀。