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

(十)多UnitId模拟:一个网关下面挂多个从站怎么测

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

单个从站模拟能解决很多问题,但还不够。

现场经常遇到这种结构:一台 TCP 网关下面挂多台 RTU 仪表,或者一条 RS485 总线上挂了多个从站。主站连的 IP、端口或串口都一样,变化的是 UnitId / SlaveId。

这时候要测试主站轮询逻辑,就需要多站号模拟。

YModbus 里对应的是:

  • ModbusTcpSlaveNetwork
  • ModbusRtuSlaveNetwork
  • ModbusAsciiSlaveNetwork

UnitId和SlaveId先别混

TCP 里常叫 Unit ID。

RTU / ASCII 里常叫 Slave ID。

名字不同,本质都是目标站号。

TCP 网关场景下,host + port只是连接到网关,UnitId 才是网关后面的设备。

RTU 总线场景下,串口参数只是打开总线,SlaveId 才是总线上的目标设备。

这个概念没分清,多站号调试一定会乱。

TCP多UnitId示例

下面这个例子在本机127.0.0.1:1502上模拟两个 UnitId。

usingSystem.Net;usingYModbus.Slave;ModbusSlaveDataStoreunit1Store=new(pointCount:100);unit1Store.SetHoldingRegister(0,1234);unit1Store.SetHoldingRegister(1,5678);ModbusSlaveDataStoreunit2Store=new(pointCount:100);unit2Store.SetHoldingRegister(0,2222);unit2Store.SetHoldingRegister(1,3333);awaitusingModbusTcpSlaveNetworknetwork=new(newModbusTcpSlaveNetworkOptions{ListenAddress=IPAddress.Loopback,Port=1502});network.AddSlave(newModbusSlaveDefinition{UnitId=1,PointCount=100},unit1Store);network.AddSlave(newModbusSlaveDefinition{UnitId=2,PointCount=100},unit2Store);awaitnetwork.StartAsync();Console.WriteLine("TCP slave network is running on 127.0.0.1:1502.");Console.ReadLine();awaitnetwork.StopAsync();

主站读 1 号站,返回12345678

主站读 2 号站,返回22223333

同一个端口,不同 UnitId,数据区不同。这就是 TCP 网关测试的核心。

主站侧用MultiUnitClient更顺

这种场景主站侧建议用ModbusMultiUnitClient

usingYModbus.Clients;awaitusingModbusMultiUnitClientclient=awaitModbusClientFactory.CreateTcpMultiUnitAsync(host:"127.0.0.1",port:1502);ushort[]unit1=awaitclient.ReadHoldingRegistersAsync(1,0,2);ushort[]unit2=awaitclient.ReadHoldingRegistersAsync(2,0,2);

第一个参数就是 UnitId。

这样代码和现场结构能对上:同一个网关,多个站号。

运行中修改某个站号的数据

测试主站轮询时,经常要模拟某个设备数据变化。

可以通过TryGetDataStore拿到对应站号的数据区:

if(network.TryGetDataStore(1,outIModbusSlaveDataStore?store)&&storeisnotnull){store.SetHoldingRegister(0,9999);}

主站下一轮读 UnitId 1,就会读到新值。

这可以模拟温度变化、报警置位、计数器增加。比拿真实设备反复造条件方便很多。

RTU多SlaveId

RTU 多站号网络使用同一个串口通道。

usingSystem.IO.Ports;usingYModbus.Serial;usingYModbus.Slave;usingSerialPortport=new("COM3",9600,Parity.None,8,StopBits.One);port.Open();awaitusingModbusRtuSlaveNetworknetwork=new(newSerialPortChannel(port,leaveOpen:true));network.AddSlave(newModbusSlaveDefinition{SlaveId=1,PointCount=100});network.AddSlave(newModbusSlaveDefinition{SlaveId=2,PointCount=100});awaitnetwork.StartAsync();Console.ReadLine();awaitnetwork.StopAsync();

RTU 请求的第一个字节就是 SlaveId。网络会按这个字节把请求路由到不同数据区。

ASCII 多站号写法类似,只是换成ModbusAsciiSlaveNetwork

awaitusingModbusAsciiSlaveNetworknetwork=new(newSerialPortChannel(port,leaveOpen:true));network.AddSlave(newModbusSlaveDefinition{SlaveId=1,PointCount=100});network.AddSlave(newModbusSlaveDefinition{SlaveId=2,PointCount=100});awaitnetwork.StartAsync();

多站号最该看报文

多站号出错时,最先看的不是寄存器值,而是请求里的站号。

TCP 请求里,UnitId 会出现在 MBAP 后面。RTU 请求里,第一个字节就是 SlaveId。

如果你以为主站在读 2 号站,但从站报文里看到的是 1 号站,那问题就很明确。

可以给 network 挂 Traffic 事件:

network.Traffic+=(_,traffic)=>{Console.WriteLine($"{traffic.Direction}{traffic.Message}{Convert.ToHexString(traffic.Frame)}");};

主站和从站两边都看报文,能少很多猜测。

适合做自动化回归

多 UnitId 模拟还有一个很实用的用途:给主站程序做回归测试。

你可以固定一套模拟环境:

UnitId 1: 温度设备 UnitId 2: 压力设备 UnitId 3: IO 模块

每个设备放一组固定数据。主站跑一轮轮询,检查解析结果。

以后改主站代码,再跑同一套模拟环境,就能知道有没有把多站号逻辑改坏。

到这里

单个从站解决“模拟一个设备”。

多 UnitId / 多 SlaveId 网络解决“模拟一组设备”。

如果你的项目里有 TCP 网关、RS485 多仪表轮询、多设备采集,建议尽早用这套方式把测试环境搭起来。

http://www.zskr.cn/news/1519619.html

相关文章:

  • MC56F825x/824x DSC双12位ADC配置与电机控制实战解析
  • 基于设备标识重置技术的Cursor Pro功能绕过实现深度解析
  • 数据分析工具选型指南:选对工具,效率直接翻倍! - 品牌测评鉴赏家
  • 会议视频快速转文字、提取音频!2026实测5款靠谱工具 - 品牌测评鉴赏家
  • AI视频工具实测:Seedance/可灵/HappyHorse谁最能打?
  • 《我劝你先别创业,除非你先测过这个》
  • 【会议征稿通知 | 深圳大学主办 | AP出版 | EI 、Scopus稳定检索】第四届管理创新与经济发展国际学术会议(MIED 2026)
  • [企业AI落地] Windows 11 下快速搭建 Ollama + Hermes + Codex + Open WebUI 本地 Agent 体系
  • CANN数学算子库ops-math底层优化原理深度剖析:昇腾NPU上GELU激活函数三种实现方式的性能与精度权衡工程实践
  • 用户交互体验优化:缩放、拖拽、日志、错误提示
  • 用C语言循环搞定PTA编程题:统计Tom、Jerry和Spike的选票(附完整代码和测试用例)
  • 终极免费视频下载神器:yt-dlp-gui Windows图形界面完整指南
  • 告别无效加班!职场日常办公工具测评,选对效率翻倍 - 品牌测评鉴赏家
  • 免费文件分类整理储存工具合集!学生家长老师自用,零套路超好用 - 品牌测评鉴赏家
  • HCS08寻址模式与指令集实战:从原理到嵌入式代码优化
  • 不靠设备堆产能!集萃智造全流程焊接工艺方案,适配各类工厂工况
  • NXP LS1046A PKHA硬件加速ECC点运算:R2预计算与实战优化
  • 2026年6月长春小班型美术画室排行 - 奔跑123
  • 文件堆积成灾?3分钟搞定高效分类整理,2026最优工具推荐! - 品牌测评鉴赏家
  • MC68040芯片热设计实战:从热阻原理到散热方案选型
  • 、广告配音用什么在线工具效果好?2026通通无印免费AI广告配音教程 - 科技大爆炸
  • 深入解析NXP Kinetis KE1xZ低功耗模式:从电源域到WFI指令实战
  • 简单三步:免费下载Book118文档并生成无水印PDF的完整指南
  • Zenith.NET 开发札记:把 .NET 图形 API 推向现代 RHI
  • 网课视频存在哪里不占手机内存?多种实用存储方式汇总 - 品牌测评鉴赏家
  • MC92604接收器配置与冗余链路设计实战解析
  • 如何实现本地化的实时唇语识别?5个步骤打造隐私保护的口型转文字方案
  • 2026年6月杭州奢侈品回收市场深度调查:多维度数据分析与诚信商家实测 - 资讯速览
  • 从LTE到5G NR:手把手对比分析控制信道设计演进与CORESET的灵活性优势
  • i.MX23 BCH硬件ECC加速器:原理、编程与NAND闪存纠错实战