当前位置: 首页 > news >正文

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.dtcms.com/a/269611.html

相关文章:

  • HTTPS工作原理
  • java获取文件的消息摘要APP进行文件完整性校验
  • JavaScript基础篇——第二章 类型转换与常见错误解析
  • 二分查找篇——搜索二维矩阵【LeetCode】遍历法
  • qt-C++笔记之setCentralWidget的使用
  • Visual Studio Code 中统一配置文件在团队协作中的应用
  • 论文略读:Prefix-Tuning: Optimizing Continuous Prompts for Generation
  • Git 安装避坑指南:从环境检查到高级配置的全流程解析
  • EXCEL转html,含图片
  • Linux下SPHinXsys源码编译安装及使用
  • Flutter基础(前端教程③-跳转)
  • Wend看源码-RAGFlow(上)
  • nvm npm nrm 使用教程
  • 台式电脑如何连wifi 快速连接方法
  • synchronized 的使用和特性
  • 算法学习笔记:11.冒泡排序——从原理到实战,涵盖 LeetCode 与考研 408 例题
  • VBA经典应用69例应用8:取消预设任务
  • (三)C#使用yolo
  • 在教育领域中,如何通过VRM分片错序对视频进行加密?
  • git学习:首次创建仓库
  • ubuntu 运行脚本打开WIFI adb
  • YOLO在自动驾驶交通标志识别中的应用与优化【附代码】
  • Qt:图片切割
  • 代码详细注释:演示如何使用dup()系统调用复制文件描述符
  • Linux操作系统:再谈虚拟地址空间
  • const char* 、char*和char[]的区别
  • MySQL数据库访问(C/C++)
  • 恒创科技:香港站群服务器做seo站群优化效果如何
  • 2025年数据挖掘与计算机科学国际会议 (DMCS 2025)
  • 基于Docker Compose部署Traccar容器与主机MySQL的完整指南