C#中使用NModbus4

以下是关于在C#中使用NModbus4库进行Modbus通信的完整技术指南,包含代码示例和工程实践:
一、开发环境搭建

  1. 安装NModbus4库
  2. 通过NuGet安装

Install-Package NModbus4
  1. 基础UI布局设计
<Form>
    <ComboBox Name="cmbPort" Items="COM1,COM2,COM3"/>
    <Button Name="btnConnect" Text="连接"/>
    <Button Name="btnRead" Text="读取寄存器"/>
    <TextBox Name="txtLog" Multiline="true" ScrollBars="Vertical"/>
</Form>

二、Modbus RTU主站实现

  1. 串口初始化与连接
private SerialPort _serialPort;
private IModbusSerialMaster _master;

private void ConnectRTU()
{
    _serialPort = new SerialPort(cmbPort.Text, 9600, Parity.None, 8, StopBits.One)
    {
        ReadTimeout = 1000,
        WriteTimeout = 1000
    };
  
    _serialPort.Open();
    _master = ModbusSerialMaster.CreateRtu(_serialPort);
    _master.Transport.Retries = 3; // 设置重试次数
}
  1. 功能码实现
    03功能码(读保持寄存器)
public ushort[] ReadHoldingRegisters(byte slaveId, ushort startAddr, ushort count)
{
    try
    {
        return _master.ReadHoldingRegisters(slaveId, startAddr, count);
    }
    catch (Exception ex)
    {
        Log($"读取失败: {ex.Message}");
        return null;
    }
}

06功能码(写单个寄存器)

public void WriteSingleRegister(byte slaveId, ushort address, ushort value)
{
    _master.WriteSingleRegister(slaveId, address, value);
}

三、Modbus TCP主站实现

  1. TCP连接管理
private TcpClient _tcpClient;
private IModbusMaster _tcpMaster;

private void ConnectTCP()
{
    _tcpClient = new TcpClient("192.168.1.100", 502);
    _tcpMaster = ModbusIpMaster.CreateIp(_tcpClient);
}
  1. 数据读写操作
// 读取输入寄存器(04功能码)
ushort[] inputs = _tcpMaster.ReadInputRegisters(1, 0, 10);

// 批量写线圈(15功能码)
bool[] coils = { true, false, true };
_tcpMaster.WriteMultipleCoils(1, 0, coils);

四、高级功能实现

  1. 定时数据采集
private System.Timers.Timer _pollTimer;

void StartPolling()
{
    _pollTimer = new System.Timers.Timer(1000);
    _pollTimer.Elapsed += (s,e) => 
    {
        var data = ReadHoldingRegisters(1, 0, 10);
        UpdateUI(data);
    };
    _pollTimer.Start();
}
  1. 多线程处理
Task.Run(() =>
{
    using (var master = ModbusSerialMaster.CreateRtu(_serialPort))
    {
        while (true)
        {
            // 异步读取操作
            var values = master.ReadHoldingRegisters(1, 0, 10);
            ProcessData(values);
        }
    }
});

五、从站实现方案

  1. RTU从站配置
private ModbusSlave _slave;

void StartRtuSlave()
{
    _serialPort = new SerialPort("COM2", 9600);
    var factory = new ModbusFactory();
    _slave = factory.CreateRtuSlave(1, new DataStore());
    _slave.Listen(_serialPort.BaseStream);
}
  1. 数据存储与同步
public class DataStore : IModbusDataStore
{
    private readonly Dictionary<ushort, ushort> _registers = new();

    public ushort[] ReadRegisters(ushort start, ushort count)
    {
        return Enumerable.Range(start, count)
               .Select(addr => _registers.GetValueOrDefault(addr))
               .ToArray();
    }
}

六、调试与测试

  1. 虚拟串口工具
    // 使用Virtual Serial Port Driver创建COM3<->COM4端口对
    // 主站使用COM3,从站使用COM4
  2. 报文分析
// 启用调试日志
_master.Transport.LoggingEnabled = true;
_master.Transport.Log += (s,e) => 
    Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] {e.Message}");

七、最佳实践
参数配置建议
波特率:9600/19200/115200
超时时间:读1000ms,写500ms
重试次数:3次
错误处理机制

try
{
    // 业务代码
}
catch (ModbusException ex)
{
    Log($"Modbus错误: {ex.ErrorCode}");
}
catch (IOException ex)
{
    Log($"IO异常: {ex.Message}");
    Reconnect();
}

你可能感兴趣的:(上位机,c#,开发语言)