C# Modbus协议通讯,NModbus轻松实现

这里讲解modbusRTU和modbusTCP。
先安装NModbus库,在nuget中搜索:
在这里插入图片描述

直接上代码!!!

 public abstract class BaseModbus
 {
     /// <summary>
     /// 关闭
     /// </summary>
     public abstract void Close();
 }
public enum FunctionCode
{
    /// <summary>
    /// 01读取单个线圈
    /// </summary>
    ReadCoils,
    /// <summary>
    /// 02读取输入线圈/离散量线圈
    /// </summary>
    ReadInputs,
    /// <summary>
    /// 03读取保持寄存器
    /// </summary>
    ReadHoldingRegisters,
    /// <summary>
    /// 04读取输入寄存器
    /// </summary>
    ReadInputRegisters,
    /// <summary>
    /// 05写单个线圈
    /// </summary>
    WriteSingleCoilAsync,
    /// <summary>
    /// 06写单个输入线圈/离散量线圈/单个寄存器
    /// </summary>
    WriteSingleRegisterAsync,
    /// <summary> 
    /// 0x0F写多个线圈   0x0F=15
    /// </summary>
    WriteMultipleCoilsAsync,
    /// <summary>
    /// 0x10写多个保持寄存器  0x10=16
    /// </summary>
    WriteMultipleRegistersAsync
}

RTU

 public class ModbusRTU : BaseModbus
 {
     public bool IsConnection = false;
     /// <summary>
     /// 串口操作对象
     /// </summary>
     public SerialPort? SPort;
     public IModbusSerialMaster? rtuMaster;
     /// <summary>
     ///  RTU连接
     /// </summary>
     /// <param name="PortName"></param>
     /// <param name="BaudRate">波特率</param>
     /// <param name="DataBits">数据位</param>
     /// <param name="StopBits">停止位</param>
     /// <param name="Parity">校验位</param>
     /// <param name="WriteTimeout"></param>
     /// <param name="ReadTimeout"></param>
     /// <returns></returns>
     public virtual bool Connection(string PortName, int BaudRate, int DataBits,
       System.IO.Ports.StopBits StopBits, System.IO.Ports.Parity Parity, int WriteTimeout = 200, int ReadTimeout = 200)
     {
         try
         {
             SPort = new SerialPort();
             SPort.PortName = PortName;
             SPort.BaudRate = BaudRate;
             SPort.DataBits = DataBits;
             SPort.Parity = Parity;
             SPort.StopBits = StopBits;
             SPort.WriteTimeout = WriteTimeout;
             SPort.ReadTimeout = ReadTimeout;
             SPort.Open();
             //SPort.DataReceived += SPort_DataReceived;
             var factory = new ModbusFactory();
             rtuMaster = factory.CreateRtuMaster(SPort);
             IsConnection = true;
             return true;
         }
         catch (Exception)
         {
             IsConnection = false;
             return false;
         }
     }
     /// <summary>
     /// 关闭
     /// </summary>
     public override void Close()
     {
         if (SPort == null)
             return;
         SPort.Close();
         IsConnection = false;
     }
     /// <summary>
     /// 写入
     /// </summary>
     /// <param name="functionCode">功能码类型</param>
     /// <param name="slaveAddress">站地址</param>
     /// <param name="startAddress">位置,从0开始</param>
     /// <param name="coilsBuffer">线圈数据</param>
     /// <param name="registerBuffer">寄存器数据</param>
     public virtual async void WriteData(FunctionCode functionCode, byte slaveAddress, ushort startAddress, bool[]? coilsBuffer = null, ushort[]? registerBuffer = null)
     {
         try
         {
             if (SPort == null)
                 return;
             if (SPort.IsOpen == false)
             {
                 SPort.Open();
             }
             switch (functionCode)
             {
                 case FunctionCode.WriteSingleCoilAsync:
                     if (coilsBuffer == null)
                         return;
                     await rtuMaster.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);
                     break;
                 case FunctionCode.WriteSingleRegisterAsync:
                     if (registerBuffer == null)
                         return;
                     await rtuMaster.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
                     break;
                 case FunctionCode.WriteMultipleCoilsAsync:
                     if (coilsBuffer == null)
                         return;
                     await rtuMaster.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);
                     break;
                 case FunctionCode.WriteMultipleRegistersAsync:
                     if (registerBuffer == null)
                         return;
                     await rtuMaster.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);
                     break;
                 default:
                     break;
             }
         }
         catch (Exception)
         {
         }
     }
     /// <summary>
     /// 读取
     /// </summary>
     /// <param name="functionCode">功能码类型</param>
     /// <param name="slaveAddress">站地址</param>
     /// <param name="startAddress">位置,从0开始</param>
     /// <param name="numberOfPoints">长度</param>
     public virtual (bool[]?, ushort[]?) ReadData(FunctionCode functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints)
     {
         bool[]? coilsBuffer = null;//线圈数据
         ushort[]? registerBuffer = null;//寄存器数据
         try
         {
             if (rtuMaster == null)
                 return (coilsBuffer, registerBuffer);
             if (SPort == null)
                 return (coilsBuffer, registerBuffer);
             if (SPort.IsOpen == false)
             {
                 SPort.Open();
             }
             switch (functionCode)
             {
                 case FunctionCode.ReadCoils:
                     coilsBuffer = rtuMaster.ReadCoils(slaveAddress, startAddress, numberOfPoints);
                     break;
                 case FunctionCode.ReadHoldingRegisters:
                     registerBuffer = rtuMaster.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
                     break;
                 case FunctionCode.ReadInputs:
                     coilsBuffer = rtuMaster.ReadInputs(slaveAddress, startAddress, numberOfPoints);
                     break;
                 case FunctionCode.ReadInputRegisters:
                     registerBuffer = rtuMaster.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
                     break;
                 default:
                     break;
             }
             return (coilsBuffer, registerBuffer);
         }
         catch (Exception)
         {
         }
         return (coilsBuffer, registerBuffer);
     }

 }

TCP

public class ModbusTCP : BaseModbus
{
    /// <summary>
    /// 网口操作对象
    /// </summary>
    public TcpClient? tcpClient;
    public IModbusMaster? tcpMaster;
    public bool IsConnection;
    /// <summary>
    /// TCP连接
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="point"></param>
    /// <returns></returns>
    public virtual bool Connection(string ip, int port=-1)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(ip) || port<0)
                return false;
            tcpClient = new TcpClient();
            tcpClient.Connect(IPAddress.Parse(ip), port);
            var factory = new ModbusFactory();
            tcpMaster = factory.CreateMaster(tcpClient);
            IsConnection = true;
            return true;
        }
        catch (Exception)
        {
            IsConnection = false;
            return false;
        }
    }
    /// <summary>
    /// 关闭
    /// </summary>
    public override void Close()
    {
        if (tcpClient == null)
            return;
        tcpClient.Close();
        IsConnection = false;
    }

    /// <summary>
    /// 写入
    /// </summary>
    /// <param name="functionCode">功能码类型</param>
    /// <param name="slaveAddress">站地址</param>
    /// <param name="startAddress">位置,从0开始</param>
    /// <param name="coilsBuffer">线圈数据</param>
    /// <param name="registerBuffer">寄存器数据</param>
    public virtual async void WriteData(FunctionCode functionCode, byte slaveAddress, ushort startAddress, bool[]? coilsBuffer = null, ushort[]? registerBuffer = null)
    {
        try
        {
            if (tcpClient == null)
                return;
            if (tcpMaster == null)
                return;
            switch (functionCode)
            {
                case FunctionCode.WriteSingleCoilAsync:
                    if (coilsBuffer == null)
                        return;
                    await tcpMaster.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);
                    break;
                case FunctionCode.WriteSingleRegisterAsync:
                    if (registerBuffer == null)
                        return;
                    await tcpMaster.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
                    break;
                case FunctionCode.WriteMultipleCoilsAsync:
                    if (coilsBuffer == null)
                        return;
                    await tcpMaster.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);
                    break;
                case FunctionCode.WriteMultipleRegistersAsync:
                    if (registerBuffer == null)
                        return;
                    await tcpMaster.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);
                    break;
                default:
                    break;
            }
        }
        catch (Exception)
        {
        }
    }
    /// <summary>
    /// 读取
    /// </summary>
    /// <param name="functionCode">功能码类型</param>
    /// <param name="slaveAddress">站地址</param>
    /// <param name="startAddress">位置,从0开始</param>
    /// <param name="numberOfPoints">长度</param>
    public virtual (bool[]?, ushort[]?) ReadData(FunctionCode functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints)
    {
        bool[]? coilsBuffer = null;//线圈数据
        ushort[]? registerBuffer = null;//寄存器数据
        try
        {
            if (tcpMaster == null)
                return (coilsBuffer, registerBuffer);
            switch (functionCode)
            {
                case FunctionCode.ReadCoils:
                    coilsBuffer = tcpMaster.ReadCoils(slaveAddress, startAddress, numberOfPoints);
                    break;
                case FunctionCode.ReadHoldingRegisters:
                    registerBuffer = tcpMaster.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
                    break;
                case FunctionCode.ReadInputs:
                    coilsBuffer = coilsBuffer = tcpMaster.ReadInputs(slaveAddress, startAddress, numberOfPoints);
                    break;
                case FunctionCode.ReadInputRegisters:
                    registerBuffer = tcpMaster.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
                    break;
                default:
                    break;
            }
            return (coilsBuffer, registerBuffer);
        }
        catch (Exception)
        {
        }
        return (coilsBuffer, registerBuffer);
    }
}

C#技术交流QQ群:371769310

  • 15
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值