From b5e3afe40dad7ad944f2a38eadea1f2ccfa66af3 Mon Sep 17 00:00:00 2001 From: MysticBoy Date: Tue, 6 Dec 2022 16:01:32 +0800 Subject: [PATCH] =?UTF-8?q?ModBus=20=E4=BC=98=E5=8C=96=E5=92=8C=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E7=AB=AF=20(#35)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1. 使用枚举直接对比性能更好。 2. 初步加入大小端转换 * 忽略本地sqlite文件等。 * 修改大小端 --- .gitignore | 4 +- IoTGateway/IoTGateway.csproj | 5 + .../DriverModbusMaster/ModbusMaster.cs | 216 ++++++++++++------ Plugins/PluginInterface/DataTypeEnum.cs | 3 +- .../DriverAddressIoArgModel.cs | 4 +- Plugins/PluginInterface/EndianEnum.cs | 19 ++ 6 files changed, 180 insertions(+), 71 deletions(-) create mode 100644 Plugins/PluginInterface/EndianEnum.cs diff --git a/.gitignore b/.gitignore index 9119290..f1c0e31 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,6 @@ bin-release/ # should NOT be excluded as they contain compiler settings and other important # information for Eclipse / Flash Builder. /.vs -/IoTGateway/wwwroot/3d \ No newline at end of file +/IoTGateway/wwwroot/3d +/IoTGateway/iotgateway.db-wal +/IoTGateway/iotgateway.db-shm diff --git a/IoTGateway/IoTGateway.csproj b/IoTGateway/IoTGateway.csproj index 08114db..d9091a4 100644 --- a/IoTGateway/IoTGateway.csproj +++ b/IoTGateway/IoTGateway.csproj @@ -17,6 +17,11 @@ + + + + + diff --git a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs index 30213b4..f2e3a99 100644 --- a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs +++ b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs @@ -348,19 +348,19 @@ namespace DriverModbusMaster else if (funCode == 4) rawBuffers = _master.ReadInputRegisters(SlaveAddress, startAddress, count); - var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType); + var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.Endian); if (ioarg.ValueType == DataTypeEnum.AsciiString) retBuffers = rawBuffers; - if (ioarg.ValueType.ToString().Contains("Uint16")) + if (ioarg.ValueType== DataTypeEnum.Uint16) ret.Value = retBuffers[0]; - else if (ioarg.ValueType.ToString().Contains("Int16")) + else if (ioarg.ValueType== DataTypeEnum.Int16) ret.Value = (short)retBuffers[0]; - else if (ioarg.ValueType.ToString().Contains("Uint32")) + else if (ioarg.ValueType== DataTypeEnum.Uint32) ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1]; - else if (ioarg.ValueType.ToString().Contains("Int32")) + else if (ioarg.ValueType== DataTypeEnum.Int32) ret.Value = (retBuffers[0] << 16) + retBuffers[1]; - else if (ioarg.ValueType.ToString().Contains("Float")) + else if (ioarg.ValueType== DataTypeEnum.Float) { var bytes = new[] { @@ -369,7 +369,7 @@ namespace DriverModbusMaster }; ret.Value = BitConverter.ToSingle(bytes, 0); } - else if (ioarg.ValueType.ToString().Contains("AsciiString")) + else if (ioarg.ValueType== DataTypeEnum.AsciiString) { var str = Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray()); if (str.Contains('\0')) @@ -390,69 +390,151 @@ namespace DriverModbusMaster private ushort GetModbusReadCount(uint functionCode, DataTypeEnum dataType) { - if (dataType.ToString().Contains("32") || dataType.ToString().Contains("Float")) + if (Is32Bit(dataType)) return 2; - if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double")) + if (Is64Bit(dataType)) return 4; return 1; - } - - //预留了大小端转换的 - private ushort[] ChangeBuffersOrder(ushort[] buffers, DataTypeEnum dataType) - { - var newBuffers = new ushort[buffers.Length]; - if (dataType.ToString().Contains("32") || dataType.ToString().Contains("Float")) - { - var a = buffers[0] & 0xff00; //A - var b = buffers[0] & 0x00ff; //B - var c = buffers[1] & 0xff00; //C - var d = buffers[1] & 0x00ff; //D - if (dataType.ToString().Contains("_1")) - { - newBuffers[0] = (ushort)(a + b); //AB - newBuffers[1] = (ushort)(c + d); //CD - } - else if (dataType.ToString().Contains("_2")) - { - newBuffers[0] = (ushort)((a >> 8) + (b << 8)); //BA - newBuffers[1] = (ushort)((c >> 8) + (d << 8)); //DC - } - else if (dataType.ToString().Contains("_3")) - { - newBuffers[0] = (ushort)((c >> 8) + (d << 8)); //DC - newBuffers[1] = (ushort)((a >> 8) + (b << 8)); //BA - } - else - { - newBuffers[0] = (ushort)(c + d); //CD - newBuffers[1] = (ushort)(a + b); //AB + } + + private static bool Is64Bit(DataTypeEnum dataType) + { + return dataType == DataTypeEnum.Uint64 || dataType == DataTypeEnum.Uint64 || dataType == DataTypeEnum.Double; + } + + private static bool Is32Bit(DataTypeEnum dataType) + { + return dataType == DataTypeEnum.Uint32 || dataType == DataTypeEnum.Int32 || dataType == DataTypeEnum.Bcd32 || dataType == DataTypeEnum.Float; + } + + //预留了大小端转换的 + private ushort[] ChangeBuffersOrder(ushort[] buffers, EndianEnum dataType) + { + int datalen = buffers.Length; + ushort[] newBuffers = new ushort[datalen]; + if (dataType == EndianEnum.None) + { + newBuffers = buffers; + } + else + { + + if (datalen == 1)//16位 + { + switch (dataType) + { + case EndianEnum.LittleEndian://BA + var ab = BitConverter.GetBytes(buffers[0]); + newBuffers[0] = BitConverter.ToUInt16(new byte[] { ab[1], ab[0] }); + break; + case EndianEnum.BigEndian://AB + default: + newBuffers[0] = buffers[0]; + break; + } + } + else if (datalen == 2)//32位 + { + newBuffers = new ushort[2]; + var ab = BitConverter.GetBytes(buffers[0]); + var cd = BitConverter.GetBytes(buffers[1]); + var _ab = new byte[2]; + var _cd = new byte[2]; + switch (dataType) + { + case EndianEnum.BigEndian://ABCD + _ab = ab; + _cd = cd; + break; + case EndianEnum.LittleEndian://DCBA + _ab[0] = cd[1]; + _ab[1] = cd[0]; + _cd[0] = ab[1]; + _cd[1] = ab[0]; + break; + case EndianEnum.BigEndianSwap://BADC + _ab[0] = ab[1]; + _ab[1] = ab[0]; + _cd[0] = cd[1]; + _cd[1] = cd[0]; + break; + case EndianEnum.LittleEndianSwap://CDAB + _ab[0] = cd[0]; + _ab[1] = cd[1]; + _cd[0] = ab[0]; + _cd[1] = ab[1]; + break; + default: + break; + } + newBuffers[0] = BitConverter.ToUInt16(_ab, 0); + newBuffers[1] = BitConverter.ToUInt16(_cd, 0); + } + else if (datalen == 4)//64位 + { + newBuffers = new ushort[2]; + var ab = BitConverter.GetBytes(buffers[0]); + var cd = BitConverter.GetBytes(buffers[1]); + var ef = BitConverter.GetBytes(buffers[2]); + var gh = BitConverter.GetBytes(buffers[3]); + var _ab = new byte[2]; + var _cd = new byte[2]; + var _ef = new byte[2]; + var _gh = new byte[2]; + switch (dataType) + { + case EndianEnum.BigEndian://AB CD EF GH + _ab = ab; + _cd = cd; + _ef = ef; + _gh = gh; + break; + case EndianEnum.LittleEndian://HG FE DC BA + _ab[0] = gh[1]; + _ab[1] = gh[0]; + _cd[0] = ef[1]; + _cd[1] = ef[0]; + + _ef[0] = cd[1]; + _ef[1] = cd[0]; + _gh[0] = ab[1]; + _gh[1] = ab[0]; + break; + case EndianEnum.BigEndianSwap://BA DC FE HG + _ab[0] = ab[1]; + _ab[1] = ab[0]; + _cd[0] = cd[1]; + _cd[1] = cd[0]; + + _ef[0] = ef[1]; + _ef[1] = ef[0]; + _gh[0] = gh[1]; + _gh[1] = gh[0]; + break; + case EndianEnum.LittleEndianSwap://GH EF CD AB + _ab[0] = gh[0]; + _ab[1] = gh[1]; + _cd[0] = ef[0]; + _cd[1] = ef[1]; + + _ef[0] = cd[0]; + _ef[1] = cd[1]; + _gh[0] = ab[0]; + _gh[1] = ab[1]; + break; + default: + break; + } + newBuffers[0] = BitConverter.ToUInt16(_ab, 0); + newBuffers[1] = BitConverter.ToUInt16(_cd, 0); + newBuffers[2] = BitConverter.ToUInt16(_ef, 0); + newBuffers[3] = BitConverter.ToUInt16(_gh, 0); + } + else + { + newBuffers = buffers; } } - else if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double")) - { - if (dataType.ToString().Contains("_1")) - { - } - else - { - newBuffers[0] = buffers[3]; - newBuffers[1] = buffers[2]; - newBuffers[2] = buffers[1]; - newBuffers[3] = buffers[0]; - } - } - else - { - if (dataType.ToString().Contains("_1")) - { - var h8 = buffers[0] & 0xf0; - var l8 = buffers[0] & 0x0f; - newBuffers[0] = (ushort)(h8 >> 8 + l8 << 8); - } - else - newBuffers[0] = buffers[0]; - } - return newBuffers; } @@ -461,10 +543,8 @@ namespace DriverModbusMaster List vs = new(); foreach (var retBuffer in retBuffers) { - vs.Add((byte)(retBuffer & 0xFF)); - vs.Add((byte)((retBuffer & 0xFF00) >> 8)); + vs.AddRange(BitConverter.GetBytes(retBuffer)); } - return vs; } diff --git a/Plugins/PluginInterface/DataTypeEnum.cs b/Plugins/PluginInterface/DataTypeEnum.cs index 3b49b08..d9d8de9 100644 --- a/Plugins/PluginInterface/DataTypeEnum.cs +++ b/Plugins/PluginInterface/DataTypeEnum.cs @@ -58,6 +58,7 @@ namespace PluginInterface [Display(Name = "自定义4")] Custome4, [Display(Name = "自定义5")] - Custome5, + Custome5, + ABCD, } } diff --git a/Plugins/PluginInterface/DriverAddressIoArgModel.cs b/Plugins/PluginInterface/DriverAddressIoArgModel.cs index e4cc8c1..21d4c02 100644 --- a/Plugins/PluginInterface/DriverAddressIoArgModel.cs +++ b/Plugins/PluginInterface/DriverAddressIoArgModel.cs @@ -12,9 +12,11 @@ namespace PluginInterface public string Address { get; set; } public object Value { get; set; } public DataTypeEnum ValueType { get; set; } + + public EndianEnum Endian { get; set; } public override string ToString() { - return $"变量ID:{ID},Address:{Address},Value:{Value},ValueType:{ValueType}"; + return $"变量ID:{ID},Address:{Address},Value:{Value},ValueType:{ValueType},Endian{Endian}"; } } } diff --git a/Plugins/PluginInterface/EndianEnum.cs b/Plugins/PluginInterface/EndianEnum.cs new file mode 100644 index 0000000..cd33efc --- /dev/null +++ b/Plugins/PluginInterface/EndianEnum.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; +using System.Xml.Linq; + +namespace PluginInterface +{ + public enum EndianEnum + { + [Display(Name = "无")] + None, + [Display(Name = "大端")] + BigEndian, + [Display(Name = "小端")] + LittleEndian, + [Display(Name = "大端交换")] + BigEndianSwap, + [Display(Name = "小端交换")] + LittleEndianSwap + } +}