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

(七) YModbus寄存器类型转换:int、float、double和字节序

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

保持寄存器读出来是ushort[]

这很符合 Modbus 协议,但不太符合人看数据的习惯。

现场你想看的通常不是16856这种原始寄存器值,而是温度23.5、压力1.25、计数器123456。这些值在设备内部可能是整数缩放,也可能是float,还可能是 32 位或 64 位整数。

所以读寄存器只是第一步。第二步是把寄存器解释成人能看懂的值。

先确认它到底是什么类型

一个 Modbus 寄存器是 16 位,也就是 2 个字节。

类型常见占用
short/ushort1 个寄存器
int/uint2 个寄存器
float/Single2 个寄存器
long/ulong4 个寄存器
double4 个寄存器

如果手册写温度是float32,一般就要读两个寄存器。

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

如果手册写温度是UINT16,倍率 0.1,那就只读一个寄存器,然后自己除以 10。

这两种处理方式完全不同。

比例系数不是字节序

这个坑很常见。

设备显示23.5,寄存器读出来是235,这时候不要急着按float解析。

它很可能只是整数缩放:

ushortraw=(awaitclient.ReadHoldingRegistersAsync(100,1))[0];decimaltemperature=raw/10m;

字节序解决的是“几个字节怎么拼成一个类型”。

比例系数解决的是“原始数值怎么换算成工程量”。

这两个问题不要混在一起。混在一起以后,现场就会开始盲试:一会儿换字节序,一会儿换地址,一会儿换功能码,最后哪个改动生效都说不清。

再看字序和字节序

如果设备确实存的是floatint32,那就要看顺序。

一个float占 4 个字节,比如:

41 BC 00 00

放进两个寄存器时,可能是:

寄存器 0: 41 BC 寄存器 1: 00 00

也可能是:

寄存器 0: 00 00 寄存器 1: 41 BC

YModbus 把它拆成两个参数:

参数说明
ModbusWordOrder多个 16 位寄存器之间,哪个字在前
ModbusByteOrder一个寄存器内部,高字节还是低字节在前

常见组合是HighWordFirst+BigEndian,但不能假定所有设备都这样。

直接读成 typed 值

如果你只想读一个 typed 值,可以用扩展方法。

float

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

int32

intcounter=awaitclient.ReadHoldingRegisterInt32Async(startAddress:120,wordOrder:ModbusWordOrder.LowWordFirst,byteOrder:ModbusByteOrder.BigEndian);

输入寄存器也有对应方法:

floatpressure=awaitclient.ReadInputRegisterSingleAsync(startAddress:0,wordOrder:ModbusWordOrder.HighWordFirst,byteOrder:ModbusByteOrder.BigEndian);

区别只是功能码不同。保持寄存器走03,输入寄存器走04

批量读完再转换

实际项目里,我更常用另一种方式:先读一段寄存器,再按地址表解析。

例如你一次读 100 个保持寄存器,里面有温度、压力、状态字、计数器。每个字段单独发请求,效率低,也不方便保持同一时刻的数据。

这时候用RegisterConverter

usingYModbus.Protocol;ushort[]registers=awaitclient.ReadHoldingRegistersAsync(100,20);floattemperature=RegisterConverter.ToSingle(registers.AsSpan(0,2).ToArray(),ModbusWordOrder.HighWordFirst,ModbusByteOrder.BigEndian);intcounter=RegisterConverter.ToInt32(registers.AsSpan(2,2).ToArray(),ModbusWordOrder.LowWordFirst,ModbusByteOrder.BigEndian);

写入时也可以反过来转:

ushort[]values=RegisterConverter.FromSingle(23.5F,ModbusWordOrder.HighWordFirst,ModbusByteOrder.BigEndian);awaitclient.WriteMultipleRegistersAsync(100,values);

怎么判断顺序对不对

最稳的办法是找一个已知值。

比如设备屏幕显示温度23.5,你读出来两个寄存器。然后用不同组合解析,看哪个结果接近23.5

可以临时这样试:

foreach(ModbusWordOrderwordOrderinEnum.GetValues<ModbusWordOrder>()){foreach(ModbusByteOrderbyteOrderinEnum.GetValues<ModbusByteOrder>()){floatvalue=RegisterConverter.ToSingle(registers,wordOrder,byteOrder);Console.WriteLine($"{wordOrder},{byteOrder}:{value}");}}

如果某个组合解析出来是4.17E-41这种离谱值,基本就不是它。

但这个办法只是为了确认设备格式。确认以后,最好把格式写进地址表,不要每次靠试。

地址表里要记录格式

一个可维护的地址表,至少应该记录这些东西:

字段示例
地址100
功能码03
数据类型Float32
字序HighWordFirst
字节序BigEndian
比例系数1.0
单位
名称当前温度

只记录“地址”和“名称”是不够的。等项目过几个月再维护,谁也不记得当时这个值为什么要低字在前,为什么要除以 10。

写入 typed 值要更谨慎

读错,通常只是显示不对。

写错,可能会改设备参数。

YModbus 有 typed write helper:

awaitclient.WriteHoldingRegisterSingleAsync(startAddress:100,value:23.5F,wordOrder:ModbusWordOrder.HighWordFirst,byteOrder:ModbusByteOrder.BigEndian);

int32

awaitclient.WriteHoldingRegisterInt32Async(startAddress:120,value:123456,wordOrder:ModbusWordOrder.LowWordFirst,byteOrder:ModbusByteOrder.BigEndian);

真正对设备写之前,先确认地址可写、数值范围安全、字序字节序和手册一致。最好写完以后再读回一次,确认设备里实际变成了什么。

到这里

寄存器转换不是 YModbus 特有的问题,是 Modbus 本身就这样。

YModbus 能帮你做两件事:

  • 直接用 typed helper 读写intfloatdouble
  • RegisterConverter在批量读出的寄存器上做转换

但设备到底是整数缩放、还是 IEEE754 浮点数,字序怎么排,比例系数是多少,还是要回到设备手册和现场验证。

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

相关文章:

  • PP-OCRv6_medium_det_onnx完全指南:从1.5M到34.5M参数的革命性文本检测模型
  • 3步搭建专业级本地语音合成系统:tts-vue完全指南
  • 计算机视觉cv2入门之实时手势检测
  • 别再只玩游戏了!用LabVIEW解析X-Plane的UDP数据流,解锁飞行数据的二次开发
  • 影刀RPA实操指南_自动发送邮件从SMTP配置到带附件定时报告
  • 掌控AMD Ryzen性能的钥匙:SMUDebugTool全面解析与实战指南
  • Lucky服务网关架构深度解析与高级配置实战指南
  • 2026温州龙港二手家电回收排行榜,推荐电话超实用(28字) - 资讯速览
  • 参考创建生产版本,从 SAP S/4HANA 物料主数据复制到主数据治理的那一步
  • 以自己为本:你生来拥有身体、时间、意志的全部主权。 别轻易把它,交出去。
  • 2026常德市权威认证贵金属回收 TOP5+黄金回收白银回收铂金回收门店地址电话推荐
  • 通过QKeyMapper解决Windows平台输入设备统一管理问题
  • 2026广州幕墙清洗服务商权威测评:资质合规与项目实力综合排名 - 互联网科技品牌测评
  • 2026年高端手工蛋卷实力品牌推荐排行榜:JAOLIS角力士凭匠心与品质稳居榜首 - 变量人生001
  • 2026年专业AI标书检测工具实测与选型指南:哪家比较靠谱? - 资讯速览
  • DRG Save Editor终极指南:3分钟学会深岩银河存档修改
  • Blender MMD Tools完整教程:5分钟学会导入MMD模型与动画
  • 如何在5分钟内实现智能图像分层?Layerdivider终极指南
  • 东莞快递袋工厂推荐:这3家实力厂家性价比拉满! - 资讯速览
  • Android Studio中文界面汉化终极教程:3步打造母语开发环境
  • 跨平台音乐格式壁垒的技术突破:ncmdump实现NCM加密文件无缝转换方案
  • BLIP-image-captioning-large在NPU上的极致优化:性能提升300%的秘密
  • Java计算机毕设之基于 SpringBoot 的闲置物品交易与订单管理系统 绿色低碳视角下闲置物品交易平台设计(完整前后端代码+说明文档+LW,调试定制等)
  • 厦门瓷砖空鼓翘边拱起怎么解决?2026专业修复方法攻略 - 苏易修缮
  • 嵌入式系统运行时完整性检查:RTIC硬件配置与安全实践
  • Display Driver Uninstaller:专业显卡驱动彻底清理终极指南
  • 如何彻底改变你的OBS录制工作流?源独立录制插件终极指南
  • 2026年全国旅游旺季到来,在烟台选择旅游包车需要注意什么? - 资讯速览
  • 三步搞定Windows电脑安装安卓应用:APK安装器终极指南
  • 2026广州工程保洁服务商权威测评:合规资质与服务能力深度对比 - 互联网科技品牌测评