C# Modbus寄存器类

发布时间 2023-08-16 14:55:55作者: Mr_Xul

注意:字节数据转换的时候用到了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