C#讀取modbus值,C#讀寫modbus,支持讀寫uint32值,Modbus TCP工具類

C#讀取modbus值,C#讀寫modbus,支持讀寫uint32值;Modbus TCP工具類
需要首先安裝nuget包Modbus

using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Modbus;namespace WindowsServiceMESProcessDispatchOrder
{/// <summary>/// Modbus工具類,提供Modbus TCP通信的基本操作/// </summary>/// <remarks>/// 創建時間:2025-6-25 09:10:34,作者:wanghaoli/// </remarks>public sealed class ModbusTool{/// <summary>///  超時時間,單位為毫秒 /// </summary>const int timeout = 1200;private static readonly object _obj = new object(); /// <summary>/// 下位機ip/// </summary>private static string ip = "192.168.0.50";/// <summary>///  默認端口為502,實際使用時可以根據需要修改/// </summary>private static int port = 502;/// <summary>/// 從站標識,默認為1,實際使用時可以根據需要修改/// </summary>private static byte slaveAddress = 1;/// <summary>/// 默認使用預設配置,此方法不需要調用;/// 當從站ip、端口、從站標識改變時,才需調用此方法設置新地址;/// </summary>/// <param name="_ip">下位機ip</param>/// <param name="_port">下位機端口</param>/// <param name="_slaveAddress">從站標識</param>public static void SetModbusSlaveInfo(string _ip = "192.168.0.50", int _port = 502, byte _slaveAddress = 1){ip = _ip;port = _port;slaveAddress = _slaveAddress;}/// <summary>/// 讀取數據地址/// </summary>private static List<ushort> AddressReadList = new List<ushort>() {1000,1010,1012,1013,1014,1015,1020,1024,1025,1027,1028,1029,1030,1041,};/// <summary>/// 單個位置寫入數據/// </summary>/// <param name="address">要寫的寄存器地址,比如1000</param>/// <param name="value">寫入的值</param>public static void WriteValue(ushort address, ushort value){try{using (TcpClient client = new TcpClient(ip, port)){client.ReceiveTimeout = timeout; // 設置接收超時為1秒client.SendTimeout = timeout; // 設置發送超時為1秒IModbusMaster master = ModbusIpMaster.CreateIp(client);// 寫入 master.WriteSingleRegister(slaveAddress, address, value);LogHelpter.AddLog($"地址{address},寫入值{value},成功");}}catch (Exception ex){LogHelpter.AddLog($"modbus訪問異常:{ex.ToString()}", null, "error_modbus");}}/// <summary>/// 寫入值 uint32;會從startAddress地址開始寫入2個寄存器;/// 比如startAddress傳參1000,則會寫入1000和1001兩個寄存器;  /// </summary>/// <param name="startAddress">開始地址</param>/// <param name="value">寫入值,uint32</param>/// <param name="slaveId">從屬機</param>public static void WriteUInt32(ushort startAddress, uint value, byte slaveId = 1){try{using (TcpClient client = new TcpClient(ip, port)){client.ReceiveTimeout = timeout; // 設置接收超時為1秒client.SendTimeout = timeout; // 設置發送超時為1秒IModbusMaster master = ModbusIpMaster.CreateIp(client);ushort highNum = (ushort)((value >> 16) & 0xFFFF);ushort lowNum = (ushort)(value & 0xFFFF);//Console.WriteLine($"位置={startAddress},uint32寫入,highNum={highNum},lowNum={lowNum}");// 寫入              master.WriteMultipleRegisters(slaveId, startAddress, new ushort[] { highNum, lowNum });LogHelpter.AddLog($"地址{startAddress},寫入值{value},成功");//Console.WriteLine($"uint32寫入成功,寫入值{value}");}}catch (Exception ex){//Console.WriteLine($"WriteUInt32,modbus訪問異常:{ex.ToString()}");LogHelpter.AddLog($"WriteUInt32,異常:{ex.ToString()}", null, "error_modbus");}}/// <summary>/// 讀取uint32值;會從startAddress地址開始讀取2個寄存器的值合并還原為一個uint32值;/// </summary>/// <param name="startAddress">讀取地址</param>/// <param name="slaveId">從屬機</param>/// <returns></returns>public static uint ReadValueUInt32(ushort startAddress, byte slaveId = 1){try{using (TcpClient client = new TcpClient(ip, port)){client.ReceiveTimeout = timeout; // 設置接收超時為1秒client.SendTimeout = timeout; // 設置發送超時為1秒IModbusMaster master = ModbusIpMaster.CreateIp(client);// 讀取ushort[] buffer = master.ReadHoldingRegisters(slaveId, startAddress, 2);//Console.WriteLine($"讀取buffer[0]={buffer[0]},1={buffer[1]}");//合并還原為uint32uint result = ((uint)buffer[0] << 16) | buffer[1];return result;}}catch (Exception ex){//Console.WriteLine($"ReadValueUInt32,modbus訪問異常:{ex.ToString()}");LogHelpter.AddLog($"ReadValueUInt32,modbus訪問異常:{ex.ToString()}",null, "error_modbus");}return 0;}/// <summary>/// 讀取單個位置數據,并返回讀取的值/// </summary>/// <param name="address">要讀取的寄存器位置,比如1000</param>/// <returns></returns>public static ushort ReadValue(ushort address){try{using (TcpClient client = new TcpClient(ip, port)){client.ReceiveTimeout = timeout; // 設置接收超時為1秒client.SendTimeout = timeout; // 設置發送超時為1秒IModbusMaster master = ModbusIpMaster.CreateIp(client);master.Transport.ReadTimeout = timeout; // 設置讀取超時為1秒master.Transport.WriteTimeout = timeout; // 設置寫入超時為1秒//讀取數據ushort[] buffer = master.ReadHoldingRegisters(slaveAddress, address, 1);ushort value = buffer.FirstOrDefault();return value;}}catch (Exception ex){LogHelpter.AddLog($"ReadValue異常:{ex.ToString()}", null, "error_modbus");}return 0;}/// <summary>/// 讀取數據/// </summary>public static void TestRead(){try{using (TcpClient client = new TcpClient(ip, port)){client.ReceiveTimeout = timeout; // 設置接收超時為1秒client.SendTimeout = timeout; // 設置發送超時為1秒IModbusMaster master = ModbusIpMaster.CreateIp(client);master.Transport.ReadTimeout = timeout; // 設置讀取超時為1秒master.Transport.WriteTimeout = timeout; // 設置寫入超時為1秒foreach (var item in AddressReadList){//讀取數據ushort[] buffer = master.ReadHoldingRegisters(slaveAddress, item, 1);ushort value = buffer.FirstOrDefault();Console.WriteLine($"讀取地址{item}的數值={value}");}}}catch (Exception ex){LogHelpter.AddLog($"modbus訪問異常:{ex.ToString()}", null, "error_modbus");}}/// <summary>///讀取值, modbus超時控制,會在規定時間內返回/// </summary>/// <param name="address">modbus讀取地址</param>/// <returns></returns>public static ushort CallReadValue(ushort address){ushort result = 0;var task = Task.Factory.StartNew(_address =>{ushort argsAddress = Convert.ToUInt16(_address);result = ReadValue(argsAddress);return result;}, address);task.Wait(timeout);//  return task.Result;return result;}/// <summary>///讀取值 UInt32類型, modbus超時控制,會在規定時間內返回/// </summary>/// <param name="address">modbus讀取地址</param>/// <returns></returns>public static uint CallReadValueUInt32(ushort address){uint result = 0;var task = Task.Factory.StartNew(_address =>{ushort argsAddress = Convert.ToUInt16(_address);result = ReadValueUInt32(argsAddress, slaveAddress);return result;}, address);task.Wait(timeout);return result;}/// <summary>///  寫入值,modbus超時控制,會在規定時間內返回/// </summary>/// <param name="address">寫入地址</param>/// <param name="value">寫入值</param>public static void CallWriteValue(ushort address, ushort value){Task.Factory.StartNew(() =>{WriteValue(address, value);                  }).Wait(timeout);}}
}

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

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

相關文章

Oracle注釋詳解

在Oracle SQL中&#xff0c;注釋是用于解釋代碼邏輯、提高可讀性的文本&#xff0c;不會被數據庫執行。Oracle支持兩種類型的注釋語法&#xff1a; 1. 單行注釋&#xff08;--&#xff09; 使用雙連字符--在一行中添加注釋&#xff0c;從--開始到行末的所有內容都會被視為注釋。…

關于 scrapy框架 詳解

scrapy 是一個純 Python 編寫的異步爬蟲框架&#xff0c;具備以下特點&#xff1a;優勢說明異步高效基于 Twisted&#xff0c;非阻塞 IO模塊化各部分可靈活配置/替換中間件機制支持代理、UA、cookie 控制等強大的解析內置 XPath、CSS 提取器自動去重Scheduler 內部維護請求 fin…

DHCP中繼實驗及其核心原理

DHCP 中繼&#xff08;DHCP Relay&#xff09;是一種允許跨網段分配 IP 地址的技術&#xff0c;無需在每個子網部署 DHCP 服務器。以下是其原理和配置方法的詳細說明&#xff1a;一、核心原理1. 為什么需要 DHCP 中繼&#xff1f;問題&#xff1a;DHCP 客戶端通過廣播&#xff…

ABP VNext + RediSearch:微服務級全文檢索

ABP VNext RediSearch&#xff1a;微服務級全文檢索 &#x1f680; &#x1f4da; 目錄ABP VNext RediSearch&#xff1a;微服務級全文檢索 &#x1f680;&#x1f4da; 一、背景與動機 &#x1f680;&#x1f6e0;? 二、環境與依賴 &#x1f433;2.1 Docker Compose 啟動 R…

TensorFlow深度學習實戰——基于自編碼器構建句子向量

TensorFlow深度學習實戰——基于自編碼器構建句子向量 0. 前言1. 句子向量2. 基于自編碼器構建句子向量2.1 數據處理2.2 模型構建與訓練 3. 模型測試相關鏈接 0. 前言 在本節中&#xff0c;我們將構建和訓練一個基于長短期記憶 (Long Short Term Memory, LSTM) 的自編碼器&…

C語言使用Protobuf進行網絡通信

筆者前面博文Go語言網絡游戲服務器模塊化編程介紹了Go語言在開發網絡游戲時如何進行模塊化編程&#xff0c;在其中使用了Protobuf進行網絡通信。在Protobuf官方實現中并沒有生成C語言的實現&#xff0c;不過有一個開源的protobuf-c可以使用。 先來看看protobuf-c生成的代碼&am…

vue3 隨手筆記12--組件通信方式9/5--useAttrs

一 什么是useAttrsuseAttrs 是 Vue 3 Composition API 中提供的一個函數&#xff0c;它屬于 Vue 的組合式 API 工具集的一部分。通過 useAttrs&#xff0c;你可以訪問傳遞給組件但未被聲明為 props 的所有屬性。這對于處理非 prop 特性&#xff08;attributes&#xff09;特別有…

HumanRisk-自動化安全意識與合規教育平臺方案

權威數據顯示&#xff0c;74%以上的數據泄露與網絡安全事件歸根結底與人為因素有關&#xff0c;60%以上的網絡安全事件是由內部人員失誤造成的。這一現狀揭示了一個核心命題&#xff1a;網絡安全威脅正從技術漏洞轉向“人為因素風險”。Gartner的調查發現&#xff0c;即便接受了…

2025年食品科學與健康大數據國際會議(SHBD 2025)

2025年食品科學與健康大數據國際會議 2025 International Conference on Food Science and Health Big Data&#xff08;一&#xff09;大會信息 會議簡稱&#xff1a;ICFSHBD 2025 大會地點&#xff1a;中國上…

CompareFace人臉識別算法環境部署

一、docker 安裝 步驟1&#xff1a;啟用系統功能 右鍵開始菜單 → 應用和功能 → 點擊 程序和功能 → 勾選 Hyper-V 和 Windows子系統Linux 步驟2&#xff1a;獲取安裝包 訪問Docker官網安裝包下載頁 &#xff0c;下載「Docker Desktop Installer.rar」壓縮包 步驟3&#…

STM32固件升級設計——內部FLASH模擬U盤升級固件

目錄 一、功能描述 1、BootLoader部分&#xff1a; 2、APP部分&#xff1a; 二、BootLoader程序制作 1、分區定義 2、 主函數 3、配置USB 4、配置fatfs文件系統 5、程序跳轉 三、APP程序制作 四、工程配置&#xff08;默認KEIL5&#xff09; 五、運行測試 結束語…

操作系統引導過程

操作系統引導是指計算機利用 CPU 運行特定程序&#xff0c;通過程序識別硬盤&#xff0c;識別硬盤分區&#xff0c;識別硬盤分區上的操作系統&#xff0c;最后通過程序啟動操作系統。 引導流程&#xff08;8步核心環節&#xff09; 1. 激活CPU 加電后CPU自動讀取 ROM中的Boot…

Safetensors與大模型文件格式全面解析

Safetensors是一種專為存儲大型張量數據設計的文件格式&#xff0c;由Hugging Face團隊開發&#xff0c;旨在提供安全高效的模型參數存儲解決方案。下面將詳細介紹Safetensors格式及其特點&#xff0c;并全面梳理當前主流的大模型文件格式。 一、Safetensors格式詳解 1. 基本概…

分布式理論:CAP、Base理論

目錄 1、CAP理論 1.1、介紹 1.2、CAP的三種選擇 1.3、CAP的注意事項 2、BASE理論 2.1、定義介紹 2.2、最終一致性的介紹 2.3、BASE的實現方式 2.4、與ACID的對比 3、CAP與BASE的聯系 4、如何選擇CAP 前言 在分布式系統中&#xff0c;CAP理論和BASE理論是指導系統設計…

【最新】飛算 JavaAl安裝、注冊,使用全流程,讓ai自己給你寫代碼,解放雙手

目錄 飛算 JavaAl 產品介紹 安裝飛算 JavaAl 第一步&#xff1a;點擊 File->Setting 第二步&#xff1a;點擊 Plugins 第三步&#xff1a;搜索 CalEx-JavaAI 第四步&#xff1a;點擊 Install 進行安裝 第五步&#xff1a;點擊 Install &#xff0c;查看安裝好的飛算…

無人設備遙控器之姿態控制算法篇

無人設備遙控器的姿態控制算法通過傳感器數據融合、控制算法優化和執行機構調節實現動態平衡&#xff0c;核心算法包括PID控制、自適應控制、模型預測控制&#xff08;MPC&#xff09;&#xff0c;以及數據融合中的互補濾波和卡爾曼濾波&#xff0c;同時涉及四元數算法和深度強…

【加解密與C】Base系列(三)Base85

Base85 編碼簡介 Base85&#xff08;也稱為 Ascii85&#xff09;是一種二進制到文本的編碼方案&#xff0c;用于將二進制數據轉換為可打印的ASCII字符。它的效率高于Base64&#xff0c;但生成的字符串可能包含特殊字符&#xff08;如引號或反斜杠&#xff09;&#xff0c;需在…

Docker企業級應用:從入門到生產環境最佳實踐

一、Docker核心概念與架構 1.1 Docker技術棧 #mermaid-svg-CUEiyGo05ZYG524v {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CUEiyGo05ZYG524v .error-icon{fill:#552222;}#mermaid-svg-CUEiyGo05ZYG524v .error-te…

8、保存應用數據

目錄用戶首選項的使用用戶首選項主要API用戶首選項開發流程用戶首選項開發實踐關系型數據庫的使用關系型數據庫工作流程關系型數據庫開發實踐用戶首選項的使用 用戶首選項主要API 用戶首選項開發流程 成功的獲取了一個名為myStore的Preferences實例 保存了一個鍵值對&#x…

(C++)list列表相關基礎用法(C++教程)(STL庫基礎教程)

源代碼&#xff1a;#include <iostream> #include <list>using namespace std;int main(){list<int> numbers{10,20,30};numbers.push_front(5);numbers.push_back(40);auto it numbers.begin();advance(it,2);numbers.insert(it,15);cout<<"該列…