如何用C#基于Modbus从COM口读取寄存器并转换为电压等值
C# + EasyModbus 实现Modbus RTU设备连接与寄存器读取教程
一、准备工作
- 确认USB转RS485的COM口编号:打开电脑「设备管理器」→「端口(COM和LPT)」,找到对应的串口(比如
COM3) - 核对分析仪的Modbus参数:波特率、数据位、停止位、奇偶校验(必须和设备手册一致,常见配置是9600、8、1、无校验)
- 提前查好设备手册里的寄存器信息:要读的寄存器地址(注意地址的计数方式)、寄存器类型(保持/输入寄存器),以及对应的物理量转换规则
二、项目搭建与库安装
- 打开Visual Studio,创建控制台应用(.NET Framework或.NET Core都可以,这里以.NET Framework为例)
- 安装EasyModbus库:
- 右键项目 → 「管理NuGet程序包」
- 在「浏览」里搜
EasyModbus,安装最新稳定版即可
三、完整示例源码
using EasyModbus; using System; namespace ModbusRtuReader { class Program { static void Main(string[] args) { // 初始化Modbus客户端 ModbusClient modbusClient = new ModbusClient(); // 配置串口参数(必须和设备完全匹配) modbusClient.SerialPort = "COM3"; // 替换成你的实际COM口 modbusClient.Baudrate = 9600; modbusClient.Parity = System.IO.Ports.Parity.None; modbusClient.StopBits = System.IO.Ports.StopBits.One; modbusClient.DataBits = 8; modbusClient.UnitIdentifier = 1; // 设备地址,默认是1,改了的话要同步 try { // 连接设备 modbusClient.Connect(); Console.WriteLine("设备连接成功!"); // 读取寄存器:以保持寄存器为例,起始地址0(注意手册如果是1-based,比如40001要转成0),读2个寄存器 int[] rawValues = modbusClient.ReadHoldingRegisters(0, 2); // 输出原始寄存器值 Console.WriteLine("\n读取到的原始寄存器值:"); for (int i = 0; i < rawValues.Length; i++) { Console.WriteLine($"寄存器[{i}]:{rawValues[i]}"); } // 转换为实际物理量(示例规则,必须以设备手册为准) // 假设手册说明:电压=寄存器值×0.01V,电流=寄存器值×0.001A float voltage = rawValues[0] * 0.01f; float current = rawValues[1] * 0.001f; Console.WriteLine("\n转换后物理量:"); Console.WriteLine($"电压:{voltage:F2} V"); Console.WriteLine($"电流:{current:F3} A"); } catch (Exception ex) { Console.WriteLine($"操作失败:{ex.Message}"); } finally { // 无论成功失败,最后都要断开连接 if (modbusClient.Connected) { modbusClient.Disconnect(); Console.WriteLine("\n已断开设备连接"); } } Console.ReadLine(); } } }
四、关键细节说明
1. 寄存器地址的坑
Modbus协议本身用0-based地址,但很多设备手册会标注1-based地址(比如保持寄存器40001对应协议里的地址0),一定要对照手册转换,读错地址会返回异常。
如果要读输入寄存器,把ReadHoldingRegisters换成ReadInputRegisters即可。
2. 物理量转换的常见方式
所有转换规则必须以设备手册为准,常见的几种情况:
- 线性转换:
物理量 = 寄存器值 × 系数 + 偏移量,比如温度=寄存器值×0.1-20 - 双寄存器转浮点数:有些设备用两个连续寄存器存IEEE754浮点数,示例代码:
// 假设寄存器0和1存一个浮点数 byte[] byteBuffer = new byte[4]; byteBuffer[0] = (byte)(rawValues[0] >> 8); // 取高字节 byteBuffer[1] = (byte)rawValues[0]; // 取低字节 byteBuffer[2] = (byte)(rawValues[1] >> 8); byteBuffer[3] = (byte)rawValues[1]; float floatValue = BitConverter.ToSingle(byteBuffer, 0); - 比例转换:比如寄存器值范围0-4095对应0-10V,公式:
电压 = (rawValue / 4095f) * 10
3. 常见问题排查
- 连接失败:检查COM口是否被占用、串口参数是否和设备一致、RS485接线是否正确(A接A,B接B)
- 读取异常:检查设备地址是否正确、寄存器地址/类型是否匹配、设备是否处于正常工作状态
内容的提问来源于stack exchange,提问作者BKC
相关产品推荐
相关产品推荐

