C#实现Modbus通信功能的示例详解

 更新时间:2024年11月29日 10:31:22   作者:小码编匠  
Modbus作为一种开放且广泛采用的通信协议,在实现设备间数据交换方面发挥着至关重要的作用,它不仅支持多种物理层接口(如RS-232, RS-485, 以及以太网),还因其简单易用的特点而被大家所青睐,本文通过实际示例介绍如何在C#项目中轻松实现Modbus通信功能

1、前言

Modbus作为一种开放且广泛采用的通信协议,在实现设备间数据交换方面发挥着至关重要的作用。它不仅支持多种物理层接口(如RS-232, RS-485, 以及以太网),还因其简单易用的特点而被大家所青睐。

本文通过实际示例介绍如何在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作为一个可选项。

ModbusTCP通信库封装过程如下:

1、在NModbus4基础上封装一个TCP连接和断开的方法:

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;
}

2、封装一个读取输出线圈的方法,其他读写方法都是类似的:

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);
     }
}

总结

通过对本篇文章的学习,我们探索了如何使用C#来实现Modbus协议下的数据通信。

最后

到此这篇关于C#实现Modbus通信功能的示例详解的文章就介绍到这了,更多相关C#实现Modbus通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C# dynamic类型使用详解

    C# dynamic类型使用详解

    C#中的dynamic类型允许在运行时确定对象的类型和成员,跳过编译时类型检查,适用于处理未知类型的对象或与动态语言互操作,dynamic支持动态成员解析、添加和删除动态成员,但性能开销较大,类型安全性和调试困难
    2024-12-12
  • Unity实现俄罗斯方块(二)

    Unity实现俄罗斯方块(二)

    这篇文章主要为大家详细介绍了Unity实现俄罗斯方块的第一部分代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • WCF如何使用动态代理精简代码架构

    WCF如何使用动态代理精简代码架构

    这篇文章主要介绍了WCF如何使用动态代理精简代码架构,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • 浅析C#中静态方法和非静态方法的区别

    浅析C#中静态方法和非静态方法的区别

    C#静态方法与非静态方法的区别不仅仅是概念上的,那么他们有什么具体的区别呢?让我们通过本文向大家介绍下C#中静态方法和非静态方法的区别,一起看看吧
    2017-09-09
  • C#使用委托的形式调用线程代码实例

    C#使用委托的形式调用线程代码实例

    今天小编就为大家分享一篇关于C#使用委托的形式调用线程代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • c#版json数据解析示例分享

    c#版json数据解析示例分享

    JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。 JSON采用完全独立于语言的文本格式,可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单,易于人阅读和编写,同时也易于机器解析和生成
    2014-03-03
  • 浅析C# AsyncLocal如何实现Thread间传值

    浅析C# AsyncLocal如何实现Thread间传值

    这篇文章主要是来和大家一起讨论一下C# AsyncLocal如何实现Thread间传值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C#9.0主要特性的一些想法

    C#9.0主要特性的一些想法

    这篇文章主要给大家介绍了关于C#9.0主要特性的一些想法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Unity Shader实现动态过场切换图片效果

    Unity Shader实现动态过场切换图片效果

    这篇文章主要为大家详细介绍了Unity Shader实现动态过场切换图片效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C#中SQL参数传入空值报错解决方案

    C#中SQL参数传入空值报错解决方案

    这篇文章主要介绍了C#中SQL参数传入空值报错解决方案,需要的朋友可以参考下
    2017-06-06

最新评论