diff --git a/HybirdFrameworkCore/Utils/BitUtls.cs b/HybirdFrameworkCore/Utils/BitUtls.cs index 86ecac7..075bb4c 100644 --- a/HybirdFrameworkCore/Utils/BitUtls.cs +++ b/HybirdFrameworkCore/Utils/BitUtls.cs @@ -15,10 +15,11 @@ public static class BitUtls /// 精度 /// 保留几位小数 /// 位偏移 + /// 对float和double 默认无符号 /// /// public static object Bytes2Value(byte[] bytes, Type propertyType, int start, int length, - double scale, int round, double offset) + double scale, int round, double offset, bool unSign = true) { if (propertyType == BOOLEAN) return Convert.ChangeType(Byte2Bit(bytes, start, length) == 1, propertyType); @@ -44,17 +45,16 @@ public static class BitUtls if (propertyType == FLOAT) return - Convert.ChangeType(Math.Round(Byte2Float(bytes, start, length, scale) - offset, round), propertyType); + Convert.ChangeType(Math.Round(Byte2Float(bytes, start, length, scale, unSign) - offset, round), propertyType); if (propertyType == DOUBLE) return - Convert.ChangeType(Math.Round(Byte2Double(bytes, start, length, scale) - offset, round), + Convert.ChangeType(Math.Round(Byte2Double(bytes, start, length, scale, unSign) - offset, round), propertyType); if (propertyType == STRING) { - - return Convert.ChangeType(Encoding.ASCII.GetString(bytes, start, length), propertyType); + return Convert.ChangeType(Encoding.ASCII.GetString(bytes, start, length/8), propertyType); } if (propertyType == BYTEARRAY) @@ -221,23 +221,23 @@ public static class BitUtls return list.ToArray(); } - public static float Byte2Float(byte[] bytes, int startBit, int length, double factor) + public static float Byte2Float(byte[] bytes, int startBit, int length, double factor, bool unSign) { if (length < 17) { - int d = Byte2Int16(bytes, startBit, length); + int d =unSign ? Byte2UInt16(bytes, startBit, length) : Byte2Int16(bytes, startBit, length); return (float)(d * factor); } else { - var d = Byte2Int32(bytes, startBit, length); + Int64 d = unSign ? Byte2UInt32(bytes, startBit, length) : Byte2Int32(bytes, startBit, length) ; return (float)(d * factor); } } - public static double Byte2Double(byte[] bytes, int startBit, int length, double factor) + public static double Byte2Double(byte[] bytes, int startBit, int length, double factor, bool unSign) { - var d = Byte2UInt32(bytes, startBit, length); + Int64 d = unSign ? Byte2UInt32(bytes, startBit, length) : Byte2Int32(bytes, startBit, length); return (float)(d * factor); } diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs index fee6009..08521d0 100644 --- a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs +++ b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs @@ -91,7 +91,7 @@ public static class ModbusDecoder } case ModbusProperty floatProperty: { - SetPropertyValue(startRegisterNo, floatProperty, decodeUseBytes); + SetPropertyValue(startRegisterNo, floatProperty, decodeUseBytes, true); // SetPropertyValue(floatProperty.RegisterNo, floatProperty, decodeUseBytes); break; } @@ -112,7 +112,7 @@ public static class ModbusDecoder return t; } - private static void SetPropertyValue(int startRegisterNo, ModbusProperty field, byte[] bytes) + private static void SetPropertyValue(int startRegisterNo, ModbusProperty field, byte[] bytes, bool unSign = true) { var registerNo = field.RegisterNo; var start = field.Start; @@ -134,7 +134,7 @@ public static class ModbusDecoder _ => length }; - var value = BitUtls.Bytes2Value(bytes, valueType, start, length, scale, round, offset); + var value = BitUtls.Bytes2Value(bytes, valueType, start, length, scale, round, offset, unSign); field.Value = (T)value; } } \ No newline at end of file diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs index e4ad4aa..2787bca 100644 --- a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs +++ b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs @@ -12,7 +12,7 @@ public class ModbusTcpMaster private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusTcpMaster)); - private ModbusTcpNet ModbusTcpNet; + private ModbusTcpNet? ModbusTcpNet; public string Ip { get; set; } = "127.0.0.1"; @@ -23,6 +23,11 @@ public class ModbusTcpMaster public int Duration { get; set; } = 1000; public bool Connected { get; set; } + /// + /// 自动重连开关 + /// + public bool AutoReConnect { get; set; } + public string connectId { get; set; } public MyReadAction? ReadAction { get; set; } @@ -36,8 +41,8 @@ public class ModbusTcpMaster public bool Connect() { + Thread.Sleep(Duration); GetLog().Info($"begin to connect {Ip}:{Port}"); - try { if (ModbusTcpNet == null) @@ -55,12 +60,20 @@ public class ModbusTcpMaster else { GetLog().Info($"connect {Ip}:{Port} failed {result.Message}"); + if (AutoReConnect) + { + return Connect(); + } } } } catch (Exception e) { GetLog().Error($"connect {Ip}:{Port} exception {e.Message}"); + if (AutoReConnect) + { + return Connect(); + } } return Connected; @@ -112,7 +125,7 @@ public class ModbusTcpMaster return null; } - public byte[]? BatchRead(int registerNo, int length) + public byte[]? BatchReadHolderRegister(int registerNo, int length) { OperateResult result = ModbusTcpNet.Read("x=3;" + registerNo, (ushort)length); if (result.IsSuccess) return result.Content; @@ -120,6 +133,58 @@ public class ModbusTcpMaster return null; } + public byte[]? BatchReadInputRegister(int registerNo, int length) + { + OperateResult result = ModbusTcpNet.Read("x=4;" + registerNo, (ushort)length); + if (result.IsSuccess) return result.Content; + + return null; + } + + /// + /// 读取线圈,需要指定起始地址,如果富文本地址不指定,默认使用的功能码是 0x01
+ /// To read the coil, you need to specify the start address. If the rich text address is not specified, the default function code is 0x01. + ///
+ /// 起始地址,格式为"1234" + /// 带有成功标志的bool对象 + public OperateResult ReadCoil(string address) => ModbusTcpNet.ReadBool(address); + + /// + /// 批量的读取线圈,需要指定起始地址,读取长度,如果富文本地址不指定,默认使用的功能码是 0x01
+ /// For batch reading coils, you need to specify the start address and read length. If the rich text address is not specified, the default function code is 0x01. + ///
+ /// 起始地址,格式为"1234" + /// 读取长度 + /// 带有成功标志的bool数组对象 + public OperateResult ReadCoil(string address, ushort length) + { + return ModbusTcpNet.ReadBool(address, length); + } + + /// + /// 读取输入线圈,需要指定起始地址,如果富文本地址不指定,默认使用的功能码是 0x02
+ /// To read the input coil, you need to specify the start address. If the rich text address is not specified, the default function code is 0x02. + ///
+ /// 起始地址,格式为"1234" + /// 带有成功标志的bool对象 + public OperateResult ReadDiscrete(string address) + { + return ModbusTcpNet.ReadDiscrete(address); + } + + /// + /// 批量的读取输入点,需要指定起始地址,读取长度,如果富文本地址不指定,默认使用的功能码是 0x02
+ /// To read input points in batches, you need to specify the start address and read length. If the rich text address is not specified, the default function code is 0x02 + ///
+ /// 起始地址,格式为"1234" + /// 读取长度 + /// 带有成功标志的bool数组对象 + public OperateResult ReadDiscrete(string address, ushort length) + { + return ModbusTcpNet.ReadDiscrete(address, length); + } + + public bool WriteValue(ModbusProperty property) { var value = property.Value; diff --git a/HybirdFrameworkDriver/Session/ModbusSession.cs b/HybirdFrameworkDriver/Session/ModbusSession.cs index 627c1b1..da750de 100644 --- a/HybirdFrameworkDriver/Session/ModbusSession.cs +++ b/HybirdFrameworkDriver/Session/ModbusSession.cs @@ -30,6 +30,6 @@ public class ModbusSession public byte[]? Read(int registerNo, int length) { - return ModbusTcpMaster.BatchRead(registerNo, length); + return ModbusTcpMaster.BatchReadHolderRegister(registerNo, length); } } \ No newline at end of file diff --git a/HybirdFrameworkDriver/Session/SessionMgr.cs b/HybirdFrameworkDriver/Session/SessionMgr.cs index 48bded0..431901e 100644 --- a/HybirdFrameworkDriver/Session/SessionMgr.cs +++ b/HybirdFrameworkDriver/Session/SessionMgr.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using DotNetty.Buffers; using DotNetty.Transport.Channels; using log4net; @@ -16,10 +17,17 @@ public class SessionMgr public static IoSession? GetSession(string key) { - Dictionary.TryGetValue(key, out IoSession? value); + if (Dictionary.ContainsKey(key)) + { + IoSession? value; + Dictionary.TryGetValue(key, out value); + return value; } + return null; + } + public static List GetSessionList() { return Dictionary.Values.ToList(); diff --git a/HybirdFrameworkDriver/TcpClient/TcpClient.cs b/HybirdFrameworkDriver/TcpClient/TcpClient.cs index ae3bc11..199889c 100644 --- a/HybirdFrameworkDriver/TcpClient/TcpClient.cs +++ b/HybirdFrameworkDriver/TcpClient/TcpClient.cs @@ -1,3 +1,4 @@ +using System.Net; using System.Reflection; using Autofac; using Autofac.Core; @@ -138,7 +139,7 @@ public class TcpClient : IDisposable where TH : IChannelHandler { try { - Task task = _bootstrap!.ConnectAsync(Host, Port); + Task task = _bootstrap!.ConnectAsync(new IPEndPoint(IPAddress.Parse(Host), Port)); Channel = task.Result; Connected = Channel.Open; }