using System.Collections; using HslCommunication; using HslCommunication.Core; using HslCommunication.ModBus; using HybirdFrameworkCore.Utils; using log4net; namespace HybirdFrameworkDriver.ModbusTcpMaster; public class ModbusTcpMaster { private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusTcpMaster)); // public string Ip { get; set; } = "127.0.0.1"; public string Ip { get; set; } = "192.168.1.5"; public int Port { get; set; } = 502; public DataFormat DataFormat { get; set; } = DataFormat.ABCD; public int Duration { get; set; } = 1000; public bool Connected { get; set; } = false; public delegate void MyReadAction(ModbusTcpMaster str); public MyReadAction? ReadAction { get; set; } private bool StopFlag { get; set; } = false; private ModbusTcpNet ModbusTcpNet; ILog GetLog() { return Log; } public bool Connect() { GetLog().Info($"begin to connect {Ip}:{Port}"); try { if (ModbusTcpNet == null) { ModbusTcpNet = new ModbusTcpNet(Ip, Port); ModbusTcpNet.DataFormat = DataFormat; OperateResult result = ModbusTcpNet.ConnectServer(); if (result.IsSuccess) { Connected = true; GetLog().Info($"connect {Ip}:{Port} success"); StartListen(); } else { GetLog().Info($"connect {Ip}:{Port} failed {result.Message}"); } } } catch (Exception e) { GetLog().Error($"connect {Ip}:{Port} exception {e.Message}"); } return Connected; } public void StartListen() { StopListen(); StopFlag = false; Thread readThread = new Thread(ReadFunc) { IsBackground = true, Name = $"{Ip}:{Port}-reader-thread" }; readThread.Start(); } public void StopListen() { StopFlag = true; Thread.Sleep(500); } private void ReadFunc() { if (ReadAction != null) { while (!StopFlag) { try { ReadAction(this); Thread.Sleep(Duration); } catch (Exception e) { Log.Error(e); } } } GetLog().Info("stop listen"); } public byte[]? ReadRegister(int registerNo, int start, int length) { start = start % 16 == 0 ? start / 16 : start / 16 + 1; length = length % 8 == 0 ? length / 8 : length / 8 + 1; OperateResult result = ModbusTcpNet.Read("x=3;" + (registerNo + start), (ushort)length); if (result.IsSuccess) { return result.Content; } return null; } public byte[]? BatchRead(int registerNo, int length) { OperateResult result = ModbusTcpNet.Read("x=3;" + registerNo, (ushort)length); if (result.IsSuccess) { return result.Content; } return null; } public bool WriteValue(ModbusProperty property) { T value = property.Value; if (value == null) { GetLog().Warn($"write property{property.RegisterNo} null value"); return false; } bool result = false; ModbusDataType dataType = property.Type; int start = property.Start; int length = property.Length; int registerNo = property.RegisterNo - 40000; byte[] setValue = BitUtls.Value2Bytes(value, property.Scale, property.Offset); OperateResult operateResult; switch (dataType) { case ModbusDataType.Byte: start = start % 2 == 0 ? start / 2 : start / 2 + 1; operateResult = ModbusTcpNet.Write("x=6;" + (registerNo + start), setValue); result = operateResult.IsSuccess; break; case ModbusDataType.Register: operateResult = ModbusTcpNet.Write("x=16;" + (registerNo + start), setValue); result = operateResult.IsSuccess; break; case ModbusDataType.Bit: start = start % 16 == 0 ? start / 16 : start / 16 + 1; length = length % 8 == 0 ? length / 8 : length / 8 + 1; OperateResult readResult = ModbusTcpNet.Read("x=3;" + (registerNo + start), (ushort)length); if (readResult.IsSuccess) { byte[] bytes = readResult.Content; BitArray bitArray = new BitArray(bytes); int index = 0; for (int i = property.Start % 16; i < property.Length; i++) { bitArray[i] = (setValue[index / 8] & (1 << (index % 8))) > 0; index++; } bitArray.CopyTo(bytes, 0); operateResult = ModbusTcpNet.Write("x=6;" + (registerNo + start), bytes); result = operateResult.IsSuccess; } break; } return result; } }