首页 > 编程语言 >C# Modbus寄存器类

C# Modbus寄存器类

时间:2023-08-16 14:56:29浏览次数:46  
标签:index slave C# ushort value Modbus static 寄存器 public

注意:字节数据转换的时候用到了BitConverter扩展类,请参考我之前的文章 

链接:https://www.cnblogs.com/smartnn/p/17633877.html

using Modbus.Data;
using Modbus.Device;
using Modbus.Message;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Demo
{
    /// <summary>
    /// Modbus寄存器
    /// </summary>
    public class ModbusRegister
    {
        /// <summary>
        /// Modbus写入事件
        /// </summary>
        public static event EventHandler<ModbusSlaveRequestEventArgs> ModbusWriteEvent;
        /// <summary>
        /// ModbusSlave
        /// </summary>
        private static ModbusSlave _slave;
        /// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="port"></param>
        /// <param name="localAddress"></param>
        public static void StartListener(int port, byte localAddress)
        {
            // 创建TCP监听
            TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
            // 实例化ModbusSlave
            _slave = ModbusTcpSlave.CreateTcp(localAddress, tcpListener);
            // 数据存储
            _slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
            // Modbus请求事件
            _slave.ModbusSlaveRequestReceived += ModbusSlave_ModbusSlaveRequestReceived;
            // Modbus写入事件
            _slave.WriteComplete += ModbusSlave_WriteComplete;
            // 开始监听
            _slave.ListenAsync();
        }
        /// <summary>
        /// Modbus请求接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void ModbusSlave_ModbusSlaveRequestReceived(object sender, ModbusSlaveRequestEventArgs e)
        {
            // 输出信息
            Console.WriteLine("Modbus:{0}", e.Message.ToString());
        }
        /// <summary>
        /// Modbus写入完成事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void ModbusSlave_WriteComplete(object sender, ModbusSlaveRequestEventArgs e)
        {
            try
            {
                // 输出信息
                Console.WriteLine("Modbus:{0}", e.Message.ToString());
                // 写单个保持寄存器
                if (e.Message is WriteSingleRegisterRequestResponse message)
                {
                    // Modbus地址
                    ushort addr = Convert.ToUInt16("4" + (message.StartAddress + 1).ToString("D4"));
                    // 处理数据
                    ModbusReceiverHandler.Receive(addr, message.Data.ToArray());
                }
                // Modbus写入事件
                ModbusWriteEvent?.Invoke(_slave, e);
            }
            catch (Exception ex)
            {
                Logger.Error("Modbus write event", ex);
            }
        }

        /// <summary>
        /// 设置数据(CoilDiscretes)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_CoilDiscretes(ushort index, bool value)
        {
            lock (_slave)
            {
                _slave.DataStore.CoilDiscretes[index] = value;
            }
        }
        /// <summary>
        /// 设置数据(InputDiscretes)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_InputDiscretes(ushort index, bool value)
        {
            lock (_slave)
            {
                _slave.DataStore.InputDiscretes[index] = value;
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_InputRegisters(ushort index, ushort value)
        {
            lock (_slave)
            {
                _slave.DataStore.InputRegisters[index] = value;
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_InputRegisters(ushort index, int value)
        {
            lock (_slave)
            {
                // int转ushort数组
                ushort[] values = value.GetBytes_Network().BytesToUshorts();
                // 数据保存
                for (int i = 0; i < values.Length; i++)
                {
                    _slave.DataStore.HoldingRegisters[index + i] = values[i];
                }
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_InputRegisters(ushort index, float value)
        {
            lock (_slave)
            {
                // float转ushort数组
                ushort[] values = value.GetBytes_Network().BytesToUshorts();
                // 数据保存
                for (int i = 0; i < values.Length; i++)
                {
                    _slave.DataStore.HoldingRegisters[index + i] = values[i];
                }
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_InputRegisters(ushort index, double value)
        {
            lock (_slave)
            {
                // double转ushort数组
                ushort[] values = value.GetBytes_Network().BytesToUshorts();
                // 数据保存
                for (int i = 0; i < values.Length; i++)
                {
                    _slave.DataStore.HoldingRegisters[index + i] = values[i];
                }
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <param name="values"></param>
        public static void SetData_InputRegisters(ushort index, ushort length, ushort[] values)
        {
            lock (_slave)
            {
                // 数据保存
                for (int i = 0; i < length; i++)
                {
                    _slave.DataStore.InputRegisters[index + i] = values.Length > i ? values[i] : (ushort)0;
                }
            }
        }
        /// <summary>
        /// 设置数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <param name="message"></param>
        public static void SetData_InputRegisters(ushort index, ushort length, string message)
        {
            lock (_slave)
            {
                // 字符串转ushort数组
                ushort[] values = Encoding.ASCII.GetBytes(message).BytesToUshorts();
                // 数据保存
                for (int i = 0; i < length; i++)
                {
                    _slave.DataStore.InputRegisters[index + i] = values.Length > i ? values[i] : (ushort)0;
                }
            }
        }
        /// <summary>
        /// 设置数据(HoldingRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetData_HoldingRegisters(ushort index, ushort value)
        {
            lock (_slave)
            {
                // 数据保存
                _slave.DataStore.HoldingRegisters[index] = value;
            }
        }
        /// <summary>
        /// 设置数据(HoldingRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <param name="values"></param>
        public static void SetData_HoldingRegisters(ushort index, ushort[] values)
        {
            lock (_slave)
            {
                // 数据保存
                for (int i = 0; i < values.Length; i++)
                {
                    _slave.DataStore.HoldingRegisters[index + i] = values[i];
                }
            }
        }

        /// <summary>
        /// 获取数据(CoilDiscretes)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool GetData_CoilDiscretes(ushort index)
        {
            lock (_slave)
            {
                return _slave.DataStore.CoilDiscretes[index];
            }
        }
        /// <summary>
        /// 获取数据(InputDiscretes)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool GetData_InputDiscretes(ushort index)
        {
            lock (_slave)
            {
                return _slave.DataStore.InputDiscretes[index];
            }
        }
        /// <summary>
        /// 获取数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static ushort GetData_InputRegisters(ushort index)
        {
            lock (_slave)
            {
                return _slave.DataStore.InputRegisters[index];
            }
        }
        /// <summary>
        /// 获取数据(InputRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static string GetData_InputRegisters(ushort index, ushort length)
        {
            lock (_slave)
            {
                List<ushort> list = new List<ushort>();
                for (int i = 0; i < length; i++)
                {
                    list.Add(_slave.DataStore.InputRegisters[index + i]);
                }
                ushort[] ushorts = list.ToArray();
                byte[] bytes = ushorts.UshortsToBytes();
                string message = bytes.GetString_UTF8(0, bytes.Length);
                return message;
            }
        }
        /// <summary>
        /// 获取数据(HoldingRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static ushort GetData_HoldingRegisters(ushort index)
        {
            lock (_slave)
            {
                return _slave.DataStore.HoldingRegisters[index];
            }
        }
        /// <summary>
        /// 获取数据(HoldingRegisters)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static string GetData_HoldingRegisters(ushort index, ushort length)
        {
            lock (_slave)
            {
                List<ushort> list = new List<ushort>();
                for (int i = 0; i < length; i++)
                {
                    list.Add(_slave.DataStore.HoldingRegisters[index + i]);
                }
                ushort[] ushorts = list.ToArray();
                byte[] bytes = ushorts.UshortsToBytes();
                string message = bytes.GetString_UTF8(0, bytes.Length);
                return message;
            }
        }

        /// <summary>
        /// 设置数据(Boolean)
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        public static void SetData_Boolean(ushort address, bool value)
        {
            ushort type = (ushort)(address / 10000);
            ushort index = (ushort)(address % 10000);
            if (type == 0)
            {
                SetData_CoilDiscretes(index, value);
            }
            else if (type == 1)
            {
                SetData_InputDiscretes(index, value);
            }
        }
        /// <summary>
        /// 设置数据(UInt16)
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        public static void SetData_UInt16(ushort address, ushort value)
        {
            ushort type = (ushort)(address / 10000);
            ushort index = (ushort)(address % 10000);
            if (type == 3)
            {
                SetData_InputRegisters(index, value);
            }
            else if (type == 4)
            {
                SetData_HoldingRegisters(index, value);
            }
        }

        /// <summary>
        /// 获取数据(Boolean)
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static bool GetData_Boolean(ushort address)
        {
            lock (_slave)
            {
                ushort type = (ushort)(address / 10000);
                ushort index = (ushort)(address % 10000);
                bool value = false;
                if (type == 0)
                {
                    value = GetData_CoilDiscretes(index);
                }
                else if (type == 1)
                {
                    value = GetData_InputDiscretes(index);
                }
                return value;
            }
        }
        /// <summary>
        /// 获取数据(UInt16)
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static ushort GetData_UInt16(ushort address)
        {
            lock (_slave)
            {
                ushort type = (ushort)(address / 10000);
                ushort index = (ushort)(address % 10000);
                ushort value = 0;
                if (type == 3)
                {
                    value = GetData_InputRegisters(index);
                }
                else if (type == 4)
                {
                    value = GetData_HoldingRegisters(index);
                }
                return value;
            }
        }
        /// <summary>
        /// 获取数据(String)
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string GetData_String(ushort address, ushort length)
        {
            lock (_slave)
            {
                ushort type = (ushort)(address / 10000);
                ushort index = (ushort)(address % 10000);
                string message = string.Empty;
                if (type == 3)
                {
                    message = GetData_InputRegisters(index, length);
                }
                else if (type == 4)
                {
                    message = GetData_HoldingRegisters(index, length);
                }
                return message;
            }
        }

        /// <summary>
        /// 获取全部数据(HoldingRegisters)
        /// </summary>
        /// <returns></returns>
        public static ModbusDataCollection<ushort> GetHoldingRegisters()
        {
            lock (_slave)
            {
                 return _slave.DataStore.HoldingRegisters;
            }
        }
    }
}
View Code

 调用方式

// Modbus开始监听
ModbusRegister.StartListener(502, 0x01);
View Code

 

翻译

搜索

复制

标签:index,slave,C#,ushort,value,Modbus,static,寄存器,public
From: https://www.cnblogs.com/smartnn/p/17634906.html

相关文章

  • ZS Shuffles Cards 题解
    ZSShufflesCards题解我们把每一次抽一些数字牌再抽到joker视作一局游戏。每局期望轮数首先考虑\(f_i\)表示每一局游戏抽出\(i\)张牌的概率。那么就是先抽出\(i-1\)张数字牌,再抽出一张joker。概率就是:\[f_i=\fracm{n+m-i+1}\prod_{k=0}^{i-2}......
  • TZC-400学习
    ARM®CoreLink™TZC-400TrustZone®AddressSpaceController该篇文档的翻译及一些总结说明:https://www.cnblogs.com/lvzh/p/16582717.htmlTZC400学习总结这是个大佬的总结:https://blog.csdn.net/weixin_42135087/article/details/107161137TZC400总结之于SOC安全域https......
  • 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - CQL
    删除数据库中以往的图MATCH(n)DETACHDELETEn创建节点CREATE命令语法Neo4jCQL“CREATE”命令用于创建没有属性的节点。它只是创建一个没有任何数据的节点。CREATE(<node-name>:<label-name>{<Property1-name>:<Property1-Value>..............
  • teamcenter awc 这两个柱状图数据比例差别太大,导致进行中的13条数据显示不出来,点击事
    原因: 解决方法:修改参数: ......
  • .NET Core6.0配置JWT
    环境 ASP.NETCoreWebAPIJWT的一些讲解和与Session的区别俺就不多说了可以去官方文档了解一下直接上代码简单粗暴(以下操作都是在ASP.NETCoreWebAPI进行操作)第一步:引入一个NuGet包  根据自己.NET版本选择对应的版本号 第二步:在appsettings.json配置一些信息"A......
  • 笔记整理--C语言--很酷的C语言技巧 - 博客 - 伯乐在线——转载
    C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常有用的语法技巧和功能,只是没有多少人知道罢了。指定的初始化很多人都知道像这样来静态地初始化数组:intfibs[]={1,1,2,3,5};C99标准实际......
  • 关于条件变量(C语言)
    由于条件变量必须和互斥锁协同使用,所以在介绍条件前会先介绍一下互斥锁(本文目前只介绍C语言,C++的条件变量可能后期会介绍)1、互斥锁从本质上来说,互斥锁是一把锁,保护共享资源免受并发影响的问题,同一时间只能有一个线程可以访问被保护的资源,从而防止竞态而产生不好的结果......
  • 2023-08-16 flutter之执行命令【flutter doctor】报错:Android sdkmanager tool not fo
    步骤如下: 注:请确保你有足够的空间安装并运行as工具。 ......
  • c/c++参数入栈顺序和参数计算顺序
    如果大家细心的话应该知道c/c++语言函数参数入栈顺序为从右至左,那么为什么这样呢?来看看两个知识点:参数的计算顺序与压栈顺序。参数入栈顺序c/c++中规定了函数参数的压栈顺序是从右至左,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。参......
  • LeetCode 714.买卖股票的最佳时机含手续费
    1.题目:给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格;整数 fee 代表了交易股票的手续费用。你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。注意:这里的一笔交易......