基于C#实现Modbus RTU通信

简介: 基于C#实现Modbus RTU通信

一、环境配置与依赖安装

# NuGet包安装(支持.NET Framework 4.5+)
Install-Package NModbus4
Install-Package System.IO.Ports

二、核心代码实现

1. 串口初始化与连接

using System.IO.Ports;
using Modbus.Device;

public class ModbusRtuMaster
{
   
    private SerialPort _serialPort;
    private IModbusSerialMaster _master;

    public void Connect(string portName, int baudRate = 9600, Parity parity = Parity.None, 
                       int dataBits = 8, StopBits stopBits = StopBits.One)
    {
   
        try
        {
   
            _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits)
            {
   
                ReadTimeout = 3000,
                WriteTimeout = 3000
            };

            _serialPort.Open();
            _master = ModbusSerialMaster.CreateRtu(_serialPort);
            _master.Transport.Retries = 3; // 设置重试次数
            _master.Transport.WriteTimeout = 2000;
            _master.Transport.ReadTimeout = 2000;
        }
        catch (Exception ex)
        {
   
            Console.WriteLine($"连接失败: {ex.Message}");
            throw;
        }
    }

    public void Disconnect()
    {
   
        _master?.Close();
        _serialPort?.Close();
    }
}

2. 数据读取操作

public ushort[] ReadHoldingRegisters(byte slaveId, ushort startAddr, ushort count)
{
   
    try
    {
   
        return _master.ReadHoldingRegisters(slaveId, startAddr, count);
    }
    catch (ModbusException ex)
    {
   
        Console.WriteLine($"Modbus错误: {ex.ErrorCode}");
        return null;
    }
    catch (IOException ex)
    {
   
        Console.WriteLine($"通信异常: {ex.Message}");
        return null;
    }
}

// 示例调用
var data = master.ReadHoldingRegisters(1, 0, 10); // 从站1读取保持寄存器0-9

3. 数据写入操作

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

public void WriteMultipleCoils(byte slaveId, ushort startAddr, bool[] values)
{
   
    _master.WriteMultipleCoils(slaveId, startAddr, values);
}

三、关键功能实现

1. CRC16校验(Modbus标准)

public static class Crc16
{
   
    public static byte[] Compute(byte[] data)
    {
   
        ushort crc = 0xFFFF;
        foreach (byte b in data)
        {
   
            crc ^= (ushort)b;
            for (int i = 0; i < 8; i++)
            {
   
                if ((crc & 0x0001) != 0)
                {
   
                    crc >>= 1;
                    crc ^= 0xA001;
                }
                else
                {
   
                    crc >>= 1;
                }
            }
        }
        return new[] {
    (byte)crc, (byte)(crc >> 8) };
    }

    public static bool Validate(byte[] dataWithCrc)
    {
   
        if (dataWithCrc.Length < 2) return false;
        byte[] data = dataWithCrc.Take(dataWithCrc.Length - 2).ToArray();
        byte[] crc = Compute(data);
        return crc[0] == dataWithCrc[dataWithCrc.Length - 2] 
            && crc[1] == dataWithCrc[dataWithCrc.Length - 1];
    }
}

2. 帧间延迟计算

private int CalculateInterFrameDelay()
{
   
    int charBits = 1 + _serialPort.DataBits + 
                  (_serialPort.StopBits == StopBits.One ? 1 : 2) + 
                  (_serialPort.Parity == Parity.None ? 0 : 1);
    return (int)(3500.0 * charBits / _serialPort.BaudRate); // 3.5字符时间
}

四、错误处理与调试

1. 异常处理策略

try
{
   
    var data = ReadHoldingRegisters(1, 0, 10);
    if (data == null) throw new InvalidOperationException("读取失败");
}
catch (TimeoutException)
{
   
    Console.WriteLine("通信超时,请检查设备状态");
    Reconnect();
}
catch (InvalidOperationException ex)
{
   
    Console.WriteLine($"操作失败: {ex.Message}");
}

2. 自动重连机制

private void Reconnect()
{
   
    Disconnect();
    Thread.Sleep(1000);
    Connect(_config.PortName, _config.BaudRate);
}

五、性能优化

1批量操作优化

// 批量读取多个寄存器区域
public Dictionary<ushort, ushort[]> BatchRead(
    params (byte SlaveId, ushort StartAddr, ushort Count)[] requests)
{
   
    var results = new Dictionary<ushort, ushort[]>();
    Parallel.ForEach(requests, request => 
    {
   
        var data = ReadHoldingRegisters(request.SlaveId, request.StartAddr, request.Count);
        lock (results) results[request.SlaveId] = data;
    });
    return results;
}

2异步通信实现

public async Task<ushort[]> ReadAsync(byte slaveId, ushort startAddr, ushort count)
{
   
    return await Task.Run(() => ReadHoldingRegisters(slaveId, startAddr, count));
}

参考代码 C#利用modbus rtu模式与下位机通讯 www.youwenfan.com/contentalg/112701.html

六、完整项目结构

ModbusRTUDemo/
├── src/
│   ├── ModbusMaster/          // 主站核心逻辑
│   ├── SerialPortConfig.cs    // 串口配置管理
│   └── ProtocolHandler.cs     // 协议解析器
├── tests/
│   ├── ModbusTests.cs         // 单元测试
│   └── StressTests.cs         // 压力测试
└── docs/
    └── 开发指南.md

七、调试与测试工具

  1. 虚拟串口工具

    使用VSPD创建虚拟串口对(如COM3<->COM4),方便调试

  2. Wireshark抓包分析

    过滤Modbus RTU协议,观察完整的请求/响应帧结构

  3. Modbus从站模拟

    使用Modbus Slave工具创建测试从站设备


八、扩展应用场景

1.多从站管理

public class ModbusNetwork
{
   
    private Dictionary<byte, ModbusRtuMaster> _slaves = new();

    public void AddSlave(byte address, string portName)
    {
   
        var master = new ModbusRtuMaster();
        master.Connect(portName);
        _slaves[address] = master;
    }
}

2.数据缓存机制

public class DataCache
{
   
    private Dictionary<ushort, (DateTime Timestamp, ushort Value)[]> _cache = new();

    public void UpdateCache(ushort[] data, ushort startAddr)
    {
   
        _cache[startAddr] = data.Select((v, i) => 
            (DateTime.Now, v)).ToArray();
    }
}

九、最佳实践建议

  1. 参数配置规范

    • 波特率:9600/19200/115200(根据设备手册选择)

    • 数据格式:8N1(默认配置)

    • 超时时间:读操作1000ms,写操作500ms

  2. 安全防护措施

  • 添加设备认证机制

  • 实现数据加密传输

  • 设置访问权限控制

相关文章
|
18天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
31359 109
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
7天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
4552 2
|
13天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
6536 17
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
12天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
4590 9
|
14天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5542 19
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
14天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
6070 5
|
16天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7695 17
|
10天前
|
人工智能 JavaScript 安全
Claude Code 安装指南
Claude Code 是 Anthropic 推出的本地 AI 编程助手,支持 Mac/Linux/WSL/Windows 多平台一键安装(Shell/PowerShell/Homebrew/NPM),提供 CLI 交互、代码生成、审查、Git 提交等能力,并内置丰富斜杠命令与自动更新机制。
3865 0