首页 > 极客资料 博客日记
C#轻松实现Modbus通信
2024-10-13 00:00:07极客资料围观18次
文章C#轻松实现Modbus通信分享给大家,欢迎收藏极客之家,专注分享技术知识
1、前言
大家好!我是付工。前面给大家介绍了一系列关于RS485与Modbus的知识。
终于有人把RS485说清楚了
终于有人把Modbus说明白了
通透!终于把ModbusRTU弄明白了
这样看来,ModbusTCP协议太简单了
今天跟大家聊聊关于C#如何实现Modbus通信。
2、开源通信库
通信库是对通信协议的封装,一般是以dll动态链接库的形式存在,对于编程者来说,只需要调用库的各种方法即可实现数据读写。
通信库有两种,一种是开源的,即使开源,也要注意看下开源许可证,开源并不一定免费,另外一种就是自己开发封装的,这个需要具备一定的开发能力。
Modbus通信有很多开源通信库,这其中使用较为广泛的是NModbus4,NModbus4是一个开源且免费的Modbus通信库,它的开源许可证是MIT,是一个相对宽松的软件授权条款,可以商用。
3、ModbusRTU通信
1、在项目解决方案资源管理器中,选择【引用】右击,在弹出的界面中,点击【管理NuGet程序包】选项,如下图所示:
2、在打开的选项卡中,选择【浏览】,然后输入NModbus4进行搜索,搜索到之后,选择最新稳定版2.1.0,点击【安装】即可:
3、在NModbus4基础上封装一个打开串口和关闭串口的方法:
private SerialPort serialPort; private ModbusSerialMaster master; public void Open(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) { if (this.serialPort != null && this.serialPort.IsOpen) { this.serialPort.Close(); } this.serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits); this.serialPort.Open(); this.master = ModbusSerialMaster.CreateRtu(this.serialPort); this.master.Transport.WriteTimeout = 2000; this.master.Transport.ReadTimeout = 2000; this.master.Transport.WaitToRetryMilliseconds = 500; this.master.Transport.Retries = 3; } public void Close() { if (this.serialPort != null && this.serialPort.IsOpen) { this.serialPort.Close(); } this.master = null; }
4、在NModbus4基础上封装各种读写的方法,这里以读取保持型寄存器为例,其他方法都是类似的:
public byte[] ReadHoldingRegisters(byte slaveId, ushort start, ushort length) { try { ushort[] data = this.master.ReadHoldingRegisters(slaveId, start, length); List<byte> result = new List<byte>(); foreach (var item in data) { result.AddRange(BitConverter.GetBytes(item).Reverse()); } return result.ToArray(); } catch (Exception ex) { throw new Exception("【读取保持寄存器】失败:" + ex.Message); } }
基于NModbus4实现ModbusRTU通信,不需要关注协议及报文,只需要对NModbus4库二次封装即可。
4、ModbusTCP通信
NModbus4不仅支持ModbusRTU通信,也同样支持ModbusTCP通信,ModbusTCP与ModbusRTU的封装过程非常类似,主要是存在以下两个不同点:
-
ModbusRTU是基于串口通信,因此主要使用的是SerialPort类,而ModbusTCP是基于以太网通信,主要使用的是TcpClient类。
-
ModbusRTU的读取和写入方法中都必须包含从站地址,而ModbusTCP可以把SlaveAddress作为一个可选项。
private TcpClient tcpClient; private ModbusIpMaster master public void Connect(string ip, int port) { tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Parse(ip), port); this.master = ModbusIpMaster.CreateIp(this.tcpClient); this.master.Transport.WriteTimeout = 2000; this.master.Transport.ReadTimeout = 2000; this.master.Transport.WaitToRetryMilliseconds = 500; this.master.Transport.Retries = 3; } public void DisConnect() { if (this.tcpClient != null && this.tcpClient.Connected) { this.tcpClient.Close(); } this.master = null; }
public bool[] ReadOutputCoils(ushort start, ushort length, byte slaveAddress = 1) { try { return this.master.ReadCoils(slaveAddress, start, length); } catch (Exception ex) { throw new Exception("【读取输出线圈】失败:" + ex.Message); } }
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
相关文章
最新发布
- Nuxt.js 应用中的 prerender:routes 事件钩子详解
- 【问题解决】Tomcat由低于8版本升级到高版本使用Tomcat自带连接池报错无法找到表空间的问题
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit
- 六、Spring Boot集成Spring Security之前后分离认证流程最佳方案
- 《JVM第7课》堆区
- .NET 8 高性能跨平台图像处理库 ImageSharp
- 还在为慢速数据传输苦恼?Linux 零拷贝技术来帮你!
- 刚毕业,去做边缘业务,还有救吗?
- 如何避免 HttpClient 丢失请求头:通过 HttpRequestMessage 解决并优化
- 让性能提升56%的Vue3.5响应式重构之“版本计数”