C# 实现Modbus通信,一篇就够了!

2,673 阅读4分钟

前言

Modbus作为一种工业通讯协议,广泛应用于各种自动化场景中。无论是设备状态的读取,还是参数调节,只要用C#,结合功能强大的NModbus4开源库,就可以事半功倍。

接下来,我们从两个方面详细讲解:基础实现Modbus RTU和TCP,逐步带你走出Modbus通信的“雾区”。

正文

Modbus通信利器:NModbus4

NModbus4是一个非常流行的开源C#库,支持Modbus RTU和TCP协议,开源协议为MIT。它直接包装了Modbus协议的底层处理,方便开发者免去复杂的报文操作。只需要简单调用方法,就能轻松实现数据读写。可以说,只要搞懂了它的使用,Modbus通信就是小菜一碟。

安装方式也超简单,直接通过NuGet搜索NModbus4,选择最新版(如2.1.0),一键安装即可完成集成,更加降低了上手门槛。

实现Modbus RTU通信

Modbus RTU是在串口上的一种数据帧协议,主要依赖SerialPort类进行串口的通信配置。按照以下步骤操作,我们可以轻松拿下RTU的实现。

1、封装串口操作

首先,我们需要为串口的打开、关闭操作封装一套公共方法,使代码更简洁灵活。下面提供了一个示例代码:

private SerialPort serialPort;  
private ModbusSerialMaster master;  

publicvoidOpen(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)  
{  
if (serialPort != null && serialPort.IsOpen) serialPort.Close();  

    serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);  
    serialPort.Open();  
    master = ModbusSerialMaster.CreateRtu(serialPort);  
    master.Transport.WriteTimeout = 2000;  
    master.Transport.ReadTimeout = 2000;  
}  
publicvoidClose()  
{  
if (serialPort != null && serialPort.IsOpen) serialPort.Close();  
    master = null;  
}  

以上代码实现了打开和关闭串口的功能,并设置了常见的超时时间和重试次数。之后,只需要调用Open方法填写参数即可安全地初始化串口连接。

2、读取保持寄存器

读写数据是Modbus RTU的核心任务,以读取保持寄存器(Holding Registers)为例:

publicbyte[] ReadHoldingRegisters(byte slaveId, ushort start, ushort length)  
{  
try  
    {  
ushort[] data = master.ReadHoldingRegisters(slaveId, start, length);  
return data.SelectMany(d => BitConverter.GetBytes(d).Reverse()).ToArray();  
    }  
catch (Exception ex)  
    {  
thrownew Exception("读取保持寄存器失败:" + ex.Message);  
    }  
}  

这样,你只需要提供从站地址、寄存器起始位置和长度,就能轻松获取所需数据。

二、实现Modbus TCP通信

Modbus TCP相较于RTU通信,主要基于TcpClient类与设备通信。整体结构和操作类似,但不再需要手动操作串口参数,而是通过IP和端口实现通信。

1. 封装TCP连接

首先封装TCP连接与断开的方法:

private TcpClient tcpClient;  
private ModbusIpMaster master;  

publicvoidConnect(string ip, int port)  
{  
    tcpClient = new TcpClient();  
    tcpClient.Connect(IPAddress.Parse(ip), port);  
    master = ModbusIpMaster.CreateIp(tcpClient);  
    master.Transport.WriteTimeout = 2000;  
    master.Transport.ReadTimeout = 2000;  
}  
publicvoidDisConnect()  
{  
if (tcpClient != null && tcpClient.Connected)  
    {  
        tcpClient.Close();  
        tcpClient = null;  
    }  
    master = null;  
}  

和串口操作相比,这里的设置更加简洁,只需输入设备的IP地址和端口号即可完成。

2、读取输出线圈

以下是读取输出线圈的一个示例:

publicbool[] ReadOutputCoils(ushort start, ushort length, byte slaveAddress = 1)  
{  
try  
    {  
return master.ReadCoils(slaveAddress, start, length);  
    }  
catch (Exception ex)  
    {  
thrownew Exception("读取输出线圈失败:" + ex.Message);  
    }  
}  

通过上述的封装和实现,我们成功运用NModbus4实现了Modbus RTU和Modbus TCP的通信解决方案。从数据读取到设备控制,仅需要简单调用库中提供的方法接口,就能实现复杂功能,同时大幅降低开发难度。下面是本文的几点总结:

NModbus4是开发利器,支持RTU和TCP协议,使用非常简单。

对串口操作和TCP连接进行了必要的封装,提升了代码复用性。

Modbus的核心在于熟悉寄存器读写,掌握这些方法后,可以灵活操作设备。

如果你正在开发工业通信相关系统,不妨尝试NModbus4,将数据读写的复杂性抛在脑后!

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:工业可视化

出处:mp.weixin.qq.com/s/6UinYOmhNq08L5LFMsAqYg

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!