基于C#和NModbus4庫實現的Modbus RTU串口通信

基于C#和NModbus4庫實現的Modbus RTU串口通信,包含完整的界面設計和功能實現:


一、項目依賴配置

  1. NuGet包安裝

    Install-Package NModbus4
    Install-Package System.IO.Ports
    
  2. 窗體控件布局

    <!-- 基礎控件配置 -->
    <ComboBox x:Name="cmbPort" Margin="5" Width="120"/>
    <Button x:Name="btnConnect" Content="連接" Margin="5"/>
    <Button x:Name="btnRead" Content="讀取寄存器" Margin="5"/>
    <TextBox x:Name="txtLog" Height="200" Margin="5" TextWrapping="Wrap"/>
    <DataGrid x:Name="dgData" AutoGenerateColumns="False" Margin="5"><DataGrid.Columns><DataGridTextColumn Header="地址" Binding="{Binding Address}"/><DataGridTextColumn Header="" Binding="{Binding Value}"/></DataGrid.Columns>
    </DataGrid>
    

二、核心代碼實現

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Windows;
using Modbus.Device;namespace ModbusRTUDemo
{public partial class MainWindow : Window{#region 成員變量private IModbusSerialMaster _master;private SerialPort _serialPort;private const ushort START_ADDR = 40001; // 起始寄存器地址private const ushort READ_COUNT = 10;    // 讀取數量#endregionpublic MainWindow(){InitializeComponent();InitializeSerialPorts();btnConnect.Click += BtnConnect_Click;btnRead.Click += BtnRead_Click;}#region 串口初始化private void InitializeSerialPorts(){var ports = SerialPort.GetPortNames();cmbPort.ItemsSource = ports;cmbPort.SelectedIndex = 0;}#endregion#region 連接控制private void BtnConnect_Click(object sender, RoutedEventArgs e){try{if (_master != null && _master.IsOpen){Disconnect();btnConnect.Content = "連接";txtLog.AppendText("已斷開連接\n");return;}_serialPort = new SerialPort(cmbPort.Text, 9600, Parity.None, 8, StopBits.One){ReadTimeout = 3000,WriteTimeout = 3000};_master = ModbusSerialMaster.CreateRtu(_serialPort);_master.Transport.Retries = 3; // 重試次數_master.Transport.WriteTimeout = 2000;_master.Transport.ReadTimeout = 2000;_master.Open();btnConnect.Content = "斷開";txtLog.AppendText($"已連接到 {_serialPort.PortName}\n");}catch (Exception ex){txtLog.AppendText($"連接失敗: {ex.Message}\n");}}#endregion#region 數據讀取private async void BtnRead_Click(object sender, RoutedEventArgs e){try{var result = await Task.Run(() => _master.ReadHoldingRegisters(1, START_ADDR, READ_COUNT));dgData.ItemsSource = result.Select((value, index) => new {Address = START_ADDR + index,Value = value.ToString("0.00")}).ToList();txtLog.AppendText($"讀取成功: {result.Length} 個寄存器\n");}catch (Exception ex){txtLog.AppendText($"讀取失敗: {ex.Message}\n");}}#endregion#region 連接管理private void Disconnect(){_master?.Close();_master = null;_serialPort?.Close();}protected override void OnClosed(EventArgs e){base.OnClosed(e);Disconnect();}#endregion}
}

參考代碼 C# 寫的串口通信程序源碼 youwenfan.com/contentcsb/111840.html

三、關鍵功能說明

  1. 串口配置
    • 支持自動檢測可用串口(通過SerialPort.GetPortNames()
    • 默認參數:9600波特率、無校驗、8數據位、1停止位
  2. Modbus操作
    • 讀取保持寄存器ReadHoldingRegisters方法實現
    • 寫單個寄存器:擴展方法WriteSingleRegister
    • 批量寫線圈WriteMultipleCoils方法
  3. 異常處理
    • 自動重試機制(默認3次重試)
    • 超時設置(讀寫各2秒)

四、擴展功能實現

  1. 定時數據采集

    private System.Timers.Timer _pollTimer = new System.Timers.Timer(5000);private void StartPolling()
    {_pollTimer.Elapsed += (s,e) => {var data = _master.ReadHoldingRegisters(1, START_ADDR, READ_COUNT);Dispatcher.Invoke(() => UpdateDataGrid(data));};_pollTimer.Start();
    }
    
  2. CRC校驗實現

    private byte[] CalculateCRC(byte[] data)
    {ushort crc = 0xFFFF;for (int i = 0; i < data.Length; i++){crc ^= (ushort)data[i];for (int j = 0; j < 8; j++){if ((crc & 0x0001) != 0){crc >>= 1;crc ^= 0xA001;}else{crc >>= 1;}}}return new byte[] { (byte)crc, (byte)(crc >> 8) };
    }
    

五、調試技巧

  1. 串口監控
    使用虛擬串口工具(如VSPD)進行通信調試

  2. 數據驗證

    // 校驗從站響應
    if (response.SlaveId != slaveId) throw new InvalidDataException("從站ID不匹配");
    
  3. 協議分析
    通過Wireshark抓包分析Modbus RTU幀結構


完整項目源碼可通過NuGet部署NModbus4庫后導入Visual Studio運行。實際應用中需根據設備手冊調整功能碼和寄存器地址。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93913.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93913.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93913.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

想要批量提取視頻背景音樂?FFmpeg 和轉換器都安排上

你是否遇到過這樣的情況&#xff1f;看到一個超贊的短視頻&#xff0c;里面的背景音樂特別好聽&#xff0c;想單獨保存下來當手機鈴聲或收藏&#xff0c;卻不知道怎么把音樂從視頻里“摳”出來&#xff1f;別擔心&#xff01;今天就為大家分享兩種簡單易行的方法&#xff0c;無…

為什么MCP協議是AI集成的未來API

一、企業AI應用的核心挑戰與架構演進 當前企業AI落地面臨三大核心痛點&#xff1a; ??系統集成困境??&#xff1a;需對接企業內部業務系統&#xff08;CRM/ERP等&#xff09;??異構環境兼容??&#xff1a;需整合第三方AI服務與傳統API??數據孤島突破??&#xff1…

Apache Tomcat樣例目錄session操縱漏洞解讀

【漏洞名稱】&#xff1a;Apache Tomcat樣例目錄session操縱漏洞 &#xff08;Apache Tomcat示例目錄漏洞&#xff09;【漏洞等級】&#xff1a;中危&#xff0c;5.9分。【漏洞描述】Apache Tomcat默認安裝頁面中存在examples樣例目錄&#xff0c;里面存放著Servlets、JSP、Web…

Go語言實戰案例:實現HTTP客戶端請求并解析響應

本文是 Go 網絡與并發實戰系列的第2篇&#xff0c;聚焦于如何使用 Go 實現一個 HTTP 客戶端&#xff0c;完成請求發送、響應解析、錯誤處理、Header與Body提取等完整流程。一、前言&#xff1a;為什么學習HTTP客戶端&#xff1f;在日常開發中&#xff0c;無論是調用 RESTful AP…

java的冒泡排序算法

冒泡排序是一種簡單的排序算法&#xff0c;通過重復遍歷待排序序列&#xff0c;比較相鄰元素并在必要時交換位置&#xff0c;最終實現排序。以下是Java實現的詳細說明&#xff1a;核心原理?比較相鄰元素?&#xff1a;從序列第一個元素開始&#xff0c;逐對比較相鄰元素的大小…

玻爾茲曼分布與玻爾茲曼探索

目錄 玻爾茲曼分布定義 玻爾茲曼探索&#xff1a; 1. 玻爾茲曼分布公式 2. 溫度 T 如何影響采樣結果&#xff1f; (1) 高溫 (T→∞)&#xff1a; (2) 低溫 (T→0)&#xff1a; (3) 中等溫度 (T∈(0,∞))&#xff1a; 3. 直觀示例 4. 實際應用中的意義 5.核心誤區澄清…

【工具】jsDelivr CDN完全指南:免費高速的開源項目CDN服務

前言 在現代Web開發中&#xff0c;內容分發網絡&#xff08;CDN&#xff09;已經成為提升網站性能的重要工具。jsDelivr作為一個免費、快速、可靠的開源CDN服務&#xff0c;為全球開發者提供了優質的靜態資源分發服務。無論是加速GitHub倉庫訪問、分發npm包&#xff0c;還是為…

OSPF筆記整理

一、OSPF 基礎特性1. 技術背景&#xff08;對比 RIP&#xff09;RIP 的缺陷&#xff1a;最大跳數 15 限制、周期性發送全路由表&#xff08;占用帶寬&#xff09;、收斂慢、以跳數為度量值、易產生環路、30 秒更新間隔。OSPF 的改進&#xff1a;無跳數限制&#xff08;支持大規…

sqLite 數據庫 (3):以編程方式使用 sqLite,4 個函數,以及 sqLite 移植,合并編譯

&#xff08;22&#xff09; 只有四個函數 &#xff1a;以及 &#xff1a;&#xff08;23&#xff09;以及 &#xff1a;&#xff08;24&#xff09;&#xff08;25&#xff09; sqLite 的源代碼很少 &#xff1a;&#xff08;26&#xff09;&#xff08;27&#xff09;&#x…

Nginx跨域問題與 MIME 類型錯誤深度排錯指南:解決 MIME type of “application/octet-stream“ 報錯

前言&#xff1a;在 Web 開發中&#xff0c;跨域請求和資源加載錯誤是前端工程師和運維人員經常遇到的棘手問題。本文將詳細解析 Nginx 環境下跨域配置的多種方案、gzip 類型參數的優化要點&#xff0c;以及.mjs 文件 MIME 類型錯誤的解決方法&#xff0c;并結合排錯思路和原理…

什么是大端?什么是小端?如何驗證?

什么是大端&#xff1f;什么是小端&#xff1f;如何驗證&#xff1f; 在計算機系統中&#xff0c;大端&#xff08;Big-Endian&#xff09; 和小端&#xff08;Little-Endian&#xff09; 是兩種不同的字節序&#xff08;Byte Order&#xff09;&#xff0c;用于描述多字節數據…

JavaScript 語句和函數

1. JavaScript 語句 1&#xff09;if語句 if (condition) statement1 else statement2這里的條件&#xff08;condition&#xff09;可以是任何表達式&#xff0c;并且求值結果不一定是布爾值。 ECMAScript會自動調用Boolean()函數將這個表達式的值轉換為布爾值。 如果條件…

代碼隨想錄刷題Day22

替換數字 這道題比較簡單&#xff0c;遇到字母就copy到新的字符數組&#xff0c;如果是遇到數字&#xff0c;就在新字符數組中加入number的字符串。代碼如下&#xff1a; #include<stdio.h> #include<ctype.h> #include<string.h> #define Max 1000000 int…

邏輯回歸參數調優實戰指南

邏輯回歸的參數調節參數展示 LogisticRegression(penaltyl2,dualFalse,tol1e4,C1.0,fit_interceptTrue,intercept_scaling1,class_weightNone,random_stateNone,solverliblinear,max_iter100,multi_classovr,verbose0,warm_startFalse, n_jobs1)在前面的學習中&#xff0c;我們…

cocosCreator2.4 googlePlay登錄升級、API 35、16KB內存頁面的支持

環境&#xff1a;我這里是cocosCreator 2.4.12 導出的android 工程 登錄升級 后臺收到的google 的提醒&#xff1a; 之前是通過implementation com.google.android.gms:play-services-auth:20.0.0 來獲取玩家 uid 和 郵箱&#xff0c;然后發送到我們的服務器獲取賬號。 升級…

unity avpro實現互動影游關鍵問題

創建視頻播放器?在Hierarchy面板中右鍵創建&#xff1a;Video > AVPro Video - MediaPlayer創建后會生成一個MediaPlayer對象&#xff0c;用于控制視頻播放添加視頻資源將視頻文件放入項目的StreamingAssets文件夾下在MediaPlayer組件的設置中選擇要播放的視頻文件在UI上顯…

【C找第一個只出現一次的字符】2022-8-18

緣由樣例通過&#xff0c;請問為什么錯了呢&#xff1f;(語言-c語言)-編程語言-CSDN問答 char str[100000];fgets(str, 100000, stdin);int a[26]{}, i, count 0;int len strlen(str);for (i 0; i<len; i) a[str[i] - a];for (i 0; i<len; i){if (a[str[i] - a] 1){…

MCP AI應用通信的底層機制

技術小館專注AI與Java領域的前沿技術知識庫 技術小館官網 在AI應用快速發展的今天&#xff0c;不同AI系統之間的高效通信成為技術架構的關鍵挑戰。MCP&#xff08;Model Context Protocol&#xff09;作為新一代AI應用通信協議&#xff0c;正在重新定義AI工具生態的構建方式。…

UI測試平臺TestComplete如何實現從Git到Jenkins的持續測試

還在為手動做UI測試又慢又累發愁&#xff1f;更頭痛的是&#xff0c;代碼改完還得等半天才能測&#xff0c;測完了結果又散得到處都是&#xff0c;根本看不清質量全貌?TestComplete幫你搞定&#xff1a;直接連上你的Git倉庫&#xff0c;代碼一有動靜就能感知。接著&#xff0c…

【Debian】4-?2 Gitea搭建

【Debian】4-?2 Gitea搭建一、準備工作二、創建 Gitea 用戶&#xff08;推薦&#xff09;三、下載并安裝 Gitea四、配置Gitea4-1 創建目錄結構4-2 創建配置目錄五、配置 Systemd 服務六、訪問 Gitea Web 界面七、小插曲一、準備工作 更新系統軟件為最新 sudo apt update &am…