mirror of
https://gitee.com/iioter/iotgateway.git
synced 2024-12-02 03:38:01 +08:00
ModBus 优化和大小端 (#35)
* 1. 使用枚举直接对比性能更好。 2. 初步加入大小端转换 * 忽略本地sqlite文件等。 * 修改大小端
This commit is contained in:
parent
adb20fdae0
commit
b5e3afe40d
2
.gitignore
vendored
2
.gitignore
vendored
@ -18,3 +18,5 @@ bin-release/
|
|||||||
# information for Eclipse / Flash Builder.
|
# information for Eclipse / Flash Builder.
|
||||||
/.vs
|
/.vs
|
||||||
/IoTGateway/wwwroot/3d
|
/IoTGateway/wwwroot/3d
|
||||||
|
/IoTGateway/iotgateway.db-wal
|
||||||
|
/IoTGateway/iotgateway.db-shm
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
<None Remove="ClientApp\**" />
|
<None Remove="ClientApp\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="iotgateway.db-shm" />
|
||||||
|
<None Remove="iotgateway.db-wal" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
||||||
<PackageReference Include="MQTTnet" Version="4.1.2.350" />
|
<PackageReference Include="MQTTnet" Version="4.1.2.350" />
|
||||||
|
@ -348,19 +348,19 @@ namespace DriverModbusMaster
|
|||||||
else if (funCode == 4)
|
else if (funCode == 4)
|
||||||
rawBuffers = _master.ReadInputRegisters(SlaveAddress, startAddress, count);
|
rawBuffers = _master.ReadInputRegisters(SlaveAddress, startAddress, count);
|
||||||
|
|
||||||
var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType);
|
var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.Endian);
|
||||||
if (ioarg.ValueType == DataTypeEnum.AsciiString)
|
if (ioarg.ValueType == DataTypeEnum.AsciiString)
|
||||||
retBuffers = rawBuffers;
|
retBuffers = rawBuffers;
|
||||||
|
|
||||||
if (ioarg.ValueType.ToString().Contains("Uint16"))
|
if (ioarg.ValueType== DataTypeEnum.Uint16)
|
||||||
ret.Value = retBuffers[0];
|
ret.Value = retBuffers[0];
|
||||||
else if (ioarg.ValueType.ToString().Contains("Int16"))
|
else if (ioarg.ValueType== DataTypeEnum.Int16)
|
||||||
ret.Value = (short)retBuffers[0];
|
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];
|
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];
|
ret.Value = (retBuffers[0] << 16) + retBuffers[1];
|
||||||
else if (ioarg.ValueType.ToString().Contains("Float"))
|
else if (ioarg.ValueType== DataTypeEnum.Float)
|
||||||
{
|
{
|
||||||
var bytes = new[]
|
var bytes = new[]
|
||||||
{
|
{
|
||||||
@ -369,7 +369,7 @@ namespace DriverModbusMaster
|
|||||||
};
|
};
|
||||||
ret.Value = BitConverter.ToSingle(bytes, 0);
|
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());
|
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray());
|
||||||
if (str.Contains('\0'))
|
if (str.Contains('\0'))
|
||||||
@ -390,69 +390,151 @@ namespace DriverModbusMaster
|
|||||||
|
|
||||||
private ushort GetModbusReadCount(uint functionCode, DataTypeEnum dataType)
|
private ushort GetModbusReadCount(uint functionCode, DataTypeEnum dataType)
|
||||||
{
|
{
|
||||||
if (dataType.ToString().Contains("32") || dataType.ToString().Contains("Float"))
|
if (Is32Bit(dataType))
|
||||||
return 2;
|
return 2;
|
||||||
if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double"))
|
if (Is64Bit(dataType))
|
||||||
return 4;
|
return 4;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//预留了大小端转换的
|
private static bool Is64Bit(DataTypeEnum dataType)
|
||||||
private ushort[] ChangeBuffersOrder(ushort[] buffers, DataTypeEnum dataType)
|
|
||||||
{
|
{
|
||||||
var newBuffers = new ushort[buffers.Length];
|
return dataType == DataTypeEnum.Uint64 || dataType == DataTypeEnum.Uint64 || dataType == DataTypeEnum.Double;
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
return newBuffers;
|
return newBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,10 +543,8 @@ namespace DriverModbusMaster
|
|||||||
List<byte> vs = new();
|
List<byte> vs = new();
|
||||||
foreach (var retBuffer in retBuffers)
|
foreach (var retBuffer in retBuffers)
|
||||||
{
|
{
|
||||||
vs.Add((byte)(retBuffer & 0xFF));
|
vs.AddRange(BitConverter.GetBytes(retBuffer));
|
||||||
vs.Add((byte)((retBuffer & 0xFF00) >> 8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vs;
|
return vs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,5 +59,6 @@ namespace PluginInterface
|
|||||||
Custome4,
|
Custome4,
|
||||||
[Display(Name = "自定义5")]
|
[Display(Name = "自定义5")]
|
||||||
Custome5,
|
Custome5,
|
||||||
|
ABCD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,11 @@ namespace PluginInterface
|
|||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
public object Value { get; set; }
|
public object Value { get; set; }
|
||||||
public DataTypeEnum ValueType { get; set; }
|
public DataTypeEnum ValueType { get; set; }
|
||||||
|
|
||||||
|
public EndianEnum Endian { get; set; }
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"变量ID:{ID},Address:{Address},Value:{Value},ValueType:{ValueType}";
|
return $"变量ID:{ID},Address:{Address},Value:{Value},ValueType:{ValueType},Endian{Endian}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
Plugins/PluginInterface/EndianEnum.cs
Normal file
19
Plugins/PluginInterface/EndianEnum.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user