C# Modbus寄存器类
注意:字节数据转换的时候用到了BitConverter扩展类,请参考我之前的文章【传送门】
使用的第三方库:NModbus4.NetCore
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; } } } }
调用方式
// Modbus开始监听 ModbusRegister.StartListener(502, 0x01);