C#上位機之Modbus通信協議!

文章目錄

  • 前言
  • 一、Modbus概念
  • 二、使用步驟
    • 1.使用Modbus準備
    • 2.使用步驟
  • 三、Modbus RTU 與 Modbus ASCII對比


前言

Modbus通信協議!


一、Modbus概念

從站設備編碼(從站地址、單元ID),一主多從。
存儲區:0-線圈狀態、1-輸入線圈(只讀)、3-輸入寄存器(只讀)、4-保持型寄存器
協議公開的,設備可以支持 1-65535
功能碼:
線圈狀態(01-讀取,05-單寫,15-多寫)
輸入線圈(02-讀取)
輸入寄存器(04-讀取)
保持型寄存器(03-讀取,06-單寫,16-多寫)
協議分類:ModbusRTU、ModbusASCII、ModbusTCP

二、使用步驟

1.使用Modbus準備

1、下載ModbusSalve和ModbusPoll軟件
ModbusPoll是主站
在這里插入圖片描述
ModbusSalve是從站
在這里插入圖片描述
Modbus是一主多從的形式,所以ModbusPoll只能開一個,ModbusSalve可以開多個。
2、安裝Modbus4庫

2.使用步驟

ModbusRTU和ModbusAscii是基于串口進行通信的所以在使用這兩個協議時需要先創建串口。
ModbusRTU

SerialPort port = new SerialPort("COM3",9600,Parity.None,8,StopBits.One);
port.Open();
// 創建ModbusRTU通信協議對象
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);
master.Transport.ReadTimeout = 2000;// 設置超時時間
master.Transport.Retries = 3;// 設置重試次數
// 讀取從站地址1的保存型寄存器0~9
ushort[] registers = master.ReadHoldingRegisters(slaveAddress: 1,// 從站地址(1-247)startAddress: 0,// 起始寄存器地址numberOfPoints: 10// 讀取寄存器數量);
// 異步讀取從站地址1的保存型寄存器0~9
//Task<ushort[]> taskRegisters = master.ReadHoldingRegistersAsync(1, 0, 10);
// 第一種處理異步方法的返回值,所在方法不需要變更異步方法
//ushort[] registersAsync = taskRegisters.GetAwaiter().GetResult();
// 第二種處理異步方法的返回值,所在方法需要變更為異步方法
//ushort[] registersAsync = await master.ReadHoldingRegistersAsync(1, 0, 10);
Debug.WriteLine($"保持寄存器值:{string.Join(",", registers)}");
// 讀取從站地址1的輸入型寄存器0~9
ushort[] inputRegisters = master.ReadInputRegisters(slaveAddress: 1,startAddress: 0,numberOfPoints: 6);
// 異步讀取從站地址1的輸入型寄存器0~9
//ushort[] inputRegistersAsync = await master.ReadInputRegistersAsync(1, 0, 6);
Debug.WriteLine($"輸入寄存器值:{string.Join(",", inputRegisters)}");
// 讀取從站地址1的線圈狀態0~7
bool[] coils = master.ReadCoils(slaveAddress: 1,startAddress: 0,numberOfPoints: 8);
// 異步讀取從站地址1的線圈狀態0~7
//bool[] coilsAsync = await master.ReadCoilsAsync(1, 0, 8);
Debug.WriteLine($"讀取線圈狀態:{string.Join(",", coils.Select(c=>c.ToString()))}");
// 讀取從站地址1的輸入線圈0~7
bool[] inputCoils = master.ReadInputs(slaveAddress: 1,startAddress: 0,numberOfPoints: 8);
// 異步讀取從站地址1的輸入線圈0~7
//bool[] inputCoilsAsycn = await master.ReadInputsAsync(1, 0, 8);
Debug.WriteLine($"讀取輸入線圈:{string.Join(",", inputCoils.Select(c => c.ToString()))}");
// 寫入單個寄存器,向從站1的寄存器6號地址寫入數據
//master.WriteSingleRegister(1,6,11111);
ushort[] writeValue = { 1, 2, 3 };
// 寫入多個寄存器,向從站1的寄存器0號地址、1號地址、2號地址中依次寫入三個數據寫入數據
//master.WriteMultipleRegisters(1, 0, writeValue);// 大小端字節序問題
//例如 300的16進制為12C,可以使用兩個字節來表示 0x01 0x2C
// 大端字節序:高位在前低位在后
// 0x01 0x2C 存儲在字節數組中 datas[0] = 0x01 datas[1] = 0x2C
//小端字節序:低位在前高位在后
// 0x2C 0x01 存儲在字節數組中 datas[0] = 0x2C datas[1] = 0x01
// 一個寄存器地址存儲2個byte字節
float v7 = 4.5f; // 浮點型數據占4個字節,但是Modbus協議只能傳輸2個字節的ushort數據
// 首先將浮點數據轉換成字節數組,連續兩次發送數據
// 獲取浮點數據對應的字節信息,C#中的字節轉換后的字節數據為小端字節序,然而Modbus協議要求的是大端字節序,所以后面還需處.單最終還得以設備方要求為準.
byte[] v7_bytes = BitConverter.GetBytes(v7);
// 將上面大端數據轉換成小端順序,也就是反轉一下數組
Array.Reverse( v7_bytes );// 轉換成大端順序
// 將處理好的浮點型的字節數組轉換成ushort數據類型
// 在轉換后有4個字節兩兩一組,一組字節中前面那個字節為高位字節,后面的字節為低位字節,如果需要將字節轉換成ushort類型
// ushort類型為16為其中前8位為高位,后8位為低位,如果需要將兩個字節轉換成16位,則高位字節需要左移8為也就是乘以256,將左移后的
// 數據與低位相加也就得到一個轉換后的ushort數據.
ushort s1 = (ushort)(v7_bytes[0] * 256 + v7_bytes[1]);
// 使用C#自帶的BitConverter來將字節數據轉換成ushort類型
s1 = BitConverter.ToUInt16(new Byte[] { v7_bytes[1], v7_bytes[0] });// 注意:C#自帶的BitConverter方法轉換是按小端字節序,所以傳入的字節數組得是小端字節序否則數據轉換錯誤
//將浮點型的后兩位轉換成ushort類型
ushort s2 = (ushort)(v7_bytes[2] *256+v7_bytes[3]);
s2 = BitConverter.ToUInt16(new Byte[] { v7_bytes[3], v7_bytes[2] });
ushort[] floatToUshort = new ushort[2]; 
floatToUshort[0] = s1;
floatToUshort[1] = s2;
master.WriteMultipleRegisters(1,8,floatToUshort);// 讀取從站地址為1的保持型寄存器8~9(讀取浮點型數據)
ushort[] fs = master.ReadHoldingRegisters(1, 8, 2);
// 將讀取到的ushort類型的數據轉換成byte類型
byte[] us_byte_1 = BitConverter.GetBytes(fs[0]);// BitConverter方法得到的是小端字序
byte[] us_byte_2 = BitConverter.GetBytes(fs[1]);
// 得把小端字序改成大端字序
byte[] f_bytes = new byte[4]
{us_byte_1[1],us_byte_1[0],us_byte_2[1],us_byte_2[0]
};
Array.Reverse(f_bytes);
float f2 = BitConverter.ToSingle(f_bytes, 0);// BitConverter需要小端所以需要使用Array.Reverse將大端轉換成小端// 向從站1的0號線圈寫入True狀態
master.WriteSingleCoil(1, 0, true);
// 向從站1的5號線圈連續寫入5個狀態
master.WriteMultipleCoils(1, 5, new bool[] { true, true, true, true, true });//異步執行寫入操作
//master.WriteSingleCoilAsync(1, 0, true);//master.WriteMultipleCoilsAsync(1, 5, new bool[] { true, true, true, true, true });//master.WriteSingleRegisterAsync(1, 6, 11111);//master.WriteMultipleRegistersAsync(1, 0, writeValue);

ModbusASCII
修改上面代碼

將 IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);中的CreateRtu替換成CreateAscii

三、Modbus RTU 與 Modbus ASCII對比

特性Modbus RTUModbus ASCII
數據表示方式二進制格式,每個字節包含 8 位數據ASCII 碼格式,每個字節用兩個 ASCII 字符表示
傳輸效率高效,數據緊湊,適合大量數據傳輸較低,數據量是 RTU 模式的兩倍左右
校驗方式CRC(循環冗余校驗),檢測能力強LRC(縱向冗余校驗),檢測能力相對較弱
通信線路要求要求較高,對數據準確性敏感要求相對較低,對噪聲和干擾有一定容忍度
適用場景工業自動化設備間的高速可靠通信與舊設備集成、調試階段或通信速率要求不高的系統
抗干擾能力較弱,需采取抗干擾措施較強,有一定容錯能力
實現復雜度較復雜,需處理二進制編碼和 CRC 校驗較簡單,易于實現

工業場景一般使用ModbusRTU

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

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

相關文章

前后端分離架構下的跨域問題與解決方案

在現代Web開發中&#xff0c;特別是隨著前后端分離架構的普及&#xff0c;跨域問題成為了開發者必須面對的一個重要議題。本文將詳細介紹什么是跨域問題、其產生的原因以及如何從前端和后端兩個角度來解決這個問題&#xff0c;并提供一些實用的代碼示例。一、跨域問題概述1. 定…

搜索數據建設系列之數據架構重構

導讀 主要概述百度搜索業務數據建設的創新實踐&#xff0c;重點圍繞寬表模型設計、計算引擎優化和新一代業務服務交付模式&#xff08;圖靈3.0開發模式&#xff09;三大方向&#xff0c;解決了傳統數倉在搜索場景下面臨的諸多挑戰&#xff0c;實現了搜索數據建設的高效、穩定、…

2025年滲透測試面試題總結-2025年HW(護網面試) 29(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。、 目錄 2025年HW(護網面試) 29 1. 樣本分析思路 2. Linux GDB分析樣本示例 3. 應急案例&#xff1a;WebShell后…

動態編程入門第二節:委托與事件 - Unity 開發者的高級回調與通信藝術

動態編程入門第一節&#xff1a;C# 反射 - Unity 開發者的超級工具箱 動態編程入門第二節&#xff1a;委托與事件 - Unity 開發者的高級回調與通信藝術 上次我們聊了 C# 反射&#xff0c;它讓程序擁有了在運行時“看清自己”的能力。但光能看清還不夠&#xff0c;我們還需要讓…

降低網絡安全中的人為風險:以人為本的路徑

有效降低網絡安全中的人為風險&#xff0c;關鍵在于采取以人為本的方法。這種方法的核心在于通過高效的培訓和實踐&#xff0c;使員工掌握安全知識、踐行安全行為&#xff0c;并最終培育出安全且相互支持的文化氛圍。 誠然&#xff0c;技術和政策必須為良好的安全行為提供支持、…

opencv裁剪和編譯

opencv裁剪和編譯 0. 準備工作 0.1 下載和安裝Eigen 地址 https://eigen.tuxfamily.org/index.php?titleMain_Page對于opencv編譯&#xff0c;需要增加EIGEN_INCLUDE_PATH和開啟WITH_EIGEN -DWITH_EIGENON -DEIGEN_INCLUDE_PATH./3rd/eigen-3.4.01. 實際腳本 編譯腳本如下: ch…

小白成長之路-mysql數據基礎(三)

文章目錄一、主從復制二、案例總結一、主從復制 1、master開啟二進制日志記錄2、slave開啟IO進程&#xff0c;從master中讀取二進制日志并寫入slave的中繼日志3、slave開啟SQL進程&#xff0c;從中繼日志中讀取二進制日志并進行重放4、最終&#xff0c;達到slave與master中數據…

通過 Windows 共享文件夾 + 手機訪問(SMB協議)如何實現

通過 Windows 共享文件夾 手機訪問&#xff08;SMB協議&#xff09; 實現 PC 和安卓手機局域網文件共享&#xff0c;具體步驟如下&#xff1a; &#x1f4cc; 前置條件 電腦和手機連接同一局域網&#xff08;同一個Wi-Fi或路由器&#xff09;。關閉防火墻或放行SMB端口&#…

【Python3教程】Python3高級篇之正則表達式

博主介紹:?全網粉絲23W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

Redis--黑馬點評--達人探店功能實現詳解

達人探店發布探店筆記探店筆記類似于點評網站的評價&#xff0c;往往是圖文結合&#xff0c;對應的表有兩個&#xff1a;tb_blog&#xff1a;探店筆記表&#xff0c;包含筆記中的標題、文字、圖片等tb_blog_comments&#xff1a;其他用戶對探店筆記的評價tb_blog表結構如下&…

一探 3D 互動展廳的神奇構造?

3D 互動展廳的神奇之處&#xff0c;離不開一系列先進技術的強力支撐 。其中&#xff0c;VR(虛擬現實)技術無疑是核心亮點之一。通過佩戴 VR 設備&#xff0c;觀眾仿佛被瞬間 “傳送” 到一個全新的世界&#xff0c;能夠全身心地沉浸其中&#xff0c;360 度無死角地觀察周圍的一…

C++ 網絡編程(15) 利用asio協程搭建異步服務器

&#x1f680; [協程與異步服務器實戰]&#xff1a;[C20協程原理與Boost.Asio異步服務器開發] &#x1f4c5; 更新時間&#xff1a;2025年07月05日 &#x1f3f7;? 標簽&#xff1a;C20 | 協程 | Boost.Asio | 異步編程 | 網絡服務器 文章目錄前言一、什么是協程&#xff1f;二…

【Java21】在spring boot中使用虛擬線程

文章目錄 0.環境說明1.原理解析2.spring boot的方案3.注意事項&#xff08;施工中&#xff0c;歡迎補充&#xff09; 前置知識 虛擬線程VT&#xff08;Virtual Thread&#xff09; 0.環境說明 用于驗證的版本&#xff1a; spring boot: 3.3.3jdk: OpenJDK 21.0.5 spring boot…

利器:NPM和YARN及其他

文章目錄**1. 安裝 Yarn&#xff08;推薦方法&#xff09;****2. 驗證安裝****3. 常見問題及解決方法****① 權限不足&#xff08;Error: EPERM&#xff09;****② 網絡問題&#xff08;連接超時或下載失敗&#xff09;****③ 環境變量未正確配置****4. 替代安裝方法&#xff0…

跨平臺直播美顏SDK集成實錄:Android/iOS如何適配貼紙功能

眾所周知&#xff0c;直播平臺與短視頻平臺的貼紙功能不僅是用戶表達個性的方式&#xff0c;更是平臺提高用戶粘性和互動轉化的法寶。 可問題來了&#xff1a;如何讓一個貼紙功能&#xff0c;在Android和iOS兩大平臺上表現一致、運行流暢、加載穩定&#xff1f;這背后&#xff…

JavaWeb(蒼穹外賣)--學習筆記04(前端:HTML,CSS,JavaScript)

前言 本片文章是學習B站黑馬程序員蒼穹外賣的學習筆記。因為最近期末周&#xff0c;一直在應付考試所以就學的很少&#xff0c;恰好視頻中在講Nginx反向代理和負載均衡&#xff08;寫著對前端的內容做一個復習&#xff09; 概述&#xff1a; 1.web前端主要由三部分組成&…

智能學號抽取系統 V5.4.3.2 —— Vue.js 實現的多功能課堂隨機抽簽工具

智能學號抽取系統 V5.4.3.2 —— Vue.js 實現的多功能課堂隨機抽簽工具 在教學或會議場景中&#xff0c;我們經常需要隨機抽取一個或多個學號/編號來決定發言者、答題者或者參與者。為了提高效率和公平性&#xff0c;我們可以使用一些智能化的小工具來實現這一過程。 今天介紹…

從0開始學習R語言--Day39--Spearman 秩相關

在非參數統計中&#xff0c;不看數據的實際數值&#xff0c;單純比較兩組變量的值的排名是通用的基本方法&#xff0c;但在客觀數據中&#xff0c;很多變量的關系都是非線性的&#xff0c;其他的方法不是對樣本數據的大小和線性有要求&#xff0c;就是只能對比數據的差異性&…

WSL - Linux 安裝 Anaconda3-2025.06-0 詳細教程 [WSL 分發版均適用]

一、檢查系統狀態 安裝前先確認 WSL - Linxu 已正常啟動&#xff08;比如 Ubuntu&#xff09;&#xff0c;網絡連接穩定&#xff0c;并且系統磁盤有足夠空間&#xff0c;一般建議預留至少 5GB 以上的可用空間&#xff0c;避免因空間不足導致安裝失敗。 二、下載安裝包 Anacond…

熱血三國建筑攻略表格

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>熱血三國建筑攻略表格</title><style>…