diff --git a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs index a0663b7..fe11cc7 100644 --- a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs +++ b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO.Ports; using System.Net; using System.Net.Sockets; +using System.Text; namespace DriverModbusMaster { @@ -334,44 +335,51 @@ namespace DriverModbusMaster ret.StatusType = VaribaleStatusTypeEnum.Bad; else { - ushort startAddress; - if (!ushort.TryParse(ioarg.Address.Trim(), out startAddress)) - ret.StatusType = VaribaleStatusTypeEnum.AddressError; - else + ushort startAddress, count; + ret = AnalyseAddress(ioarg, out startAddress, out count); + if(ret.StatusType!= VaribaleStatusTypeEnum.Good) + return ret; + try { - var count = GetModbusReadCount(3, ioarg.ValueType); - try - { - var rawBuffers = new ushort[] { }; - if (FunCode == 3) - rawBuffers = master.ReadHoldingRegisters(SlaveAddress, startAddress, count); - else if (FunCode == 4) - rawBuffers = master.ReadInputRegisters(SlaveAddress, startAddress, count); + var rawBuffers = new ushort[] { }; + if (FunCode == 3) + rawBuffers = master.ReadHoldingRegisters(SlaveAddress, startAddress, count); + else if (FunCode == 4) + rawBuffers = master.ReadInputRegisters(SlaveAddress, startAddress, count); - var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType); - if (ioarg.ValueType.ToString().Contains("Uint16")) - ret.Value = retBuffers[0]; - else if (ioarg.ValueType.ToString().Contains("Int16")) - ret.Value = (short)retBuffers[0]; - else if (ioarg.ValueType.ToString().Contains("Uint32")) - ret.Value = (UInt32)(retBuffers[0] << 16) + retBuffers[1]; - else if (ioarg.ValueType.ToString().Contains("Int32")) - ret.Value = (Int32)(retBuffers[0] << 16) + retBuffers[1]; - else if (ioarg.ValueType.ToString().Contains("Float")) - { - var bytes = new byte[] { (byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff), (byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff) }; - ret.Value = BitConverter.ToSingle(bytes, 0); - } + var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType); + if (ioarg.ValueType == DataTypeEnum.AsciiString) + retBuffers = rawBuffers; - } - catch (Exception ex) + if (ioarg.ValueType.ToString().Contains("Uint16")) + ret.Value = retBuffers[0]; + else if (ioarg.ValueType.ToString().Contains("Int16")) + ret.Value = (short)retBuffers[0]; + else if (ioarg.ValueType.ToString().Contains("Uint32")) + ret.Value = (UInt32)(retBuffers[0] << 16) + retBuffers[1]; + else if (ioarg.ValueType.ToString().Contains("Int32")) + ret.Value = (Int32)(retBuffers[0] << 16) + retBuffers[1]; + else if (ioarg.ValueType.ToString().Contains("Float")) { - ret.StatusType = VaribaleStatusTypeEnum.Bad; - ret.Message = ex.Message; + var bytes = new byte[] { (byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff), (byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff) }; + ret.Value = BitConverter.ToSingle(bytes, 0); } + else if (ioarg.ValueType.ToString().Contains("AsciiString")) + { + var str= Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray()); + if (str.Contains('\0')) + str = str.Split('\0')[0]; + ret.Value = str; + } + + } + catch (Exception ex) + { + ret.StatusType = VaribaleStatusTypeEnum.Bad; + ret.Message = ex.Message; } - } + } return ret; } @@ -444,6 +452,47 @@ namespace DriverModbusMaster return newBuffers; } + private List GetBytes(ushort[] retBuffers) + { + + List vs = new(); + for (int i = 0; i < retBuffers.Length; i++) + { + vs.Add((byte)(retBuffers[i] & 0xFF)); + vs.Add((byte)((retBuffers[i] & 0xFF00) >> 8)); + } + + return vs; + } + + private DriverReturnValueModel AnalyseAddress(DriverAddressIoArgModel ioarg, out ushort StartAddress, out ushort ReadCount) + { + DriverReturnValueModel ret = new() { StatusType = VaribaleStatusTypeEnum.Good }; + try + { + if (ioarg.ValueType == DataTypeEnum.AsciiString) + { + StartAddress = ushort.Parse(ioarg.Address.Split(',')[0]); + ReadCount = ushort.Parse(ioarg.Address.Split(',')[1]); + } + else + { + StartAddress = ushort.Parse(ioarg.Address); + ReadCount = GetModbusReadCount(3, ioarg.ValueType); + } + return ret; + + } + catch (Exception ex) + { + ret.StatusType = VaribaleStatusTypeEnum.AddressError; + ret.Message = ex.Message; + StartAddress = 0; + ReadCount = 0; + return ret; + } + } + public async Task WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg) { RpcResponse rpcResponse = new() { IsSuccess = false };