diff --git a/SCADA/Program/ModbusDriver/ModbusRTUDriver.cs b/SCADA/Program/ModbusDriver/ModbusRTUDriver.cs index 637ac97..b69532f 100644 --- a/SCADA/Program/ModbusDriver/ModbusRTUDriver.cs +++ b/SCADA/Program/ModbusDriver/ModbusRTUDriver.cs @@ -1,11 +1,10 @@ -using System; +using DataService; +using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.IO.Ports; using System.Text; -using System.Timers; -using DataService; namespace ModbusDriver { @@ -111,8 +110,8 @@ namespace ModbusDriver _serialPort.DataBits = 8; _serialPort.Parity = Parity.Even; _serialPort.StopBits = StopBits.One; - if (!string.IsNullOrEmpty(spare1)) byte.TryParse(spare1, out _slaveId); } + private SerialPort _serialPort; /* @@ -125,10 +124,10 @@ namespace ModbusDriver    Long:代表有符号的64位整数,范围从-9223372036854775808 ~ 9223372036854775808    Ulong:代表无符号的64位整数,范围从0 ~ 18446744073709551615。 */ - private byte[] CreateReadHeader(int startAddress, ushort length, byte function) + private byte[] CreateReadHeader(int id, int startAddress, ushort length, byte function) { byte[] data = new byte[8]; - data[0] = _slaveId; // Slave id high byte 从站地址 + data[0] = (byte)id; // Slave id high byte 从站地址 data[1] = function; // Message size byte[] _adr = BitConverter.GetBytes((short)startAddress);//以字节数组的形式返回指定的 16 位无符号整数值。 //apply on small endian, TODO:support big endian @@ -145,10 +144,10 @@ namespace ModbusDriver } #region 写单个线圈或单个离散输出 功能码:0x05 - public byte[] WriteSingleCoils(int startAddress, bool OnOff) + public byte[] WriteSingleCoils(int id, int startAddress, bool OnOff) { byte[] data = new byte[8]; - data[0] = _slaveId; // Slave id high byte + data[0] = (byte)id; // Slave id high byte data[1] = Modbus.fctWriteSingleCoil; // Function code byte[] _adr = BitConverter.GetBytes((short)startAddress); data[2] = _adr[1]; // Start address @@ -162,11 +161,11 @@ namespace ModbusDriver #endregion #region 写多个线圈 功能码:0x0F 15 - public byte[] WriteMultipleCoils(int startAddress, ushort numBits, byte[] values) + public byte[] WriteMultipleCoils(int id, int startAddress, ushort numBits, byte[] values) { int len = values.Length; byte[] data = new byte[len + 9]; - data[0] = _slaveId; // Slave id high byte 从站地址高八位 + data[0] = (byte)id; // Slave id high byte 从站地址高八位 data[1] = Modbus.fctWriteMultipleCoils; // Function code 功能码 byte[] _adr = BitConverter.GetBytes((short)startAddress); data[2] = _adr[1]; // Start address 开始地址高八位 @@ -184,10 +183,10 @@ namespace ModbusDriver #endregion #region 写单个保持寄存器 功能码:0x06 - public byte[] WriteSingleRegister(int startAddress, byte[] values) + public byte[] WriteSingleRegister(int id, int startAddress, byte[] values) { byte[] data = new byte[8]; - data[0] = _slaveId; // Slave id high byte 从站地址高八位 + data[0] = (byte)id; // Slave id high byte 从站地址高八位 data[1] = Modbus.fctWriteSingleRegister; // Function code 功能码 byte[] _adr = BitConverter.GetBytes((short)startAddress); data[2] = _adr[1]; // Start address 开始地址高八位 @@ -202,12 +201,12 @@ namespace ModbusDriver #endregion #region 写多个保持寄存器 功能码:0x10 16 - public byte[] WriteMultipleRegister(int startAddress, byte[] values) + public byte[] WriteMultipleRegister(int id, int startAddress, byte[] values) { int len = values.Length; if (len % 2 > 0) len++; byte[] data = new byte[len + 9]; - data[0] = _slaveId; // Slave id high byte 从站地址 + data[0] = (byte)id; // Slave id high byte 从站地址 data[1] = Modbus.fctWriteMultipleRegister; // Function code 功能码 byte[] _adr = BitConverter.GetBytes((short)startAddress); data[2] = _adr[1]; // Start address 开始地址高八位 @@ -237,47 +236,47 @@ namespace ModbusDriver get { return 0xFD; } //0xFD 十进制为253 } - byte _slaveId;//设备ID 单元号 字节号 - /// - /// 设备ID 单元号 字节号 - /// - public byte SlaveId - { - get { return _slaveId; } - set { _slaveId = value; } - } - public DeviceAddress GetDeviceAddress(string address) { DeviceAddress dv = DeviceAddress.Empty; if (string.IsNullOrEmpty(address)) return dv; + var sindex = address.IndexOf(':'); + if (sindex > 0) + { + int slaveId; + if (int.TryParse(address.Substring(0, sindex), out slaveId)) + dv.Area = slaveId; + address = address.Substring(sindex + 1); + } switch (address[0]) { case '0': { - dv.Area = Modbus.fctReadCoil; + dv.DBNumber = Modbus.fctReadCoil; int st; int.TryParse(address, out st); dv.Bit = (byte)(st % 16); st /= 16; dv.Start = st; + dv.Bit--; } break; case '1': { - dv.Area = Modbus.fctReadDiscreteInputs; + dv.DBNumber = Modbus.fctReadDiscreteInputs; int st; int.TryParse(address.Substring(1), out st); dv.Bit = (byte)(st % 16); st /= 16; dv.Start = st; + dv.Bit--; } break; case '4': { int index = address.IndexOf('.'); - dv.Area = Modbus.fctReadHoldingRegister; + dv.DBNumber = Modbus.fctReadHoldingRegister; if (index > 0) { dv.Start = int.Parse(address.Substring(1, index - 1)); @@ -286,12 +285,14 @@ namespace ModbusDriver else dv.Start = int.Parse(address.Substring(1)); dv.Start--; + dv.Bit--; + dv.ByteOrder = ByteOrder.Network; } break; case '3': { int index = address.IndexOf('.'); - dv.Area = Modbus.fctReadInputRegister; + dv.DBNumber = Modbus.fctReadInputRegister; if (index > 0) { dv.Start = int.Parse(address.Substring(1, index - 1)); @@ -300,10 +301,11 @@ namespace ModbusDriver else dv.Start = int.Parse(address.Substring(1)); dv.Start--; + dv.Bit--; + dv.ByteOrder = ByteOrder.Network; } break; } - dv.Bit--; return dv; } @@ -317,11 +319,11 @@ namespace ModbusDriver object _async = new object(); public byte[] ReadBytes(DeviceAddress address, ushort size) { - int area = address.Area; + var func = (byte)address.DBNumber; try { - byte[] header = area == Modbus.fctReadCoil ? CreateReadHeader(address.Start * 16, (ushort)(16 * size), (byte)area) : - CreateReadHeader(address.Start, size, (byte)area); + byte[] header = func < 3 ? CreateReadHeader(address.Area, address.Start * 16, (ushort)(16 * size), func) : + CreateReadHeader(address.Area, address.Start, size, func); _serialPort.Write(header, 0, header.Length); byte[] frameBytes = new byte[size * 2 + 5]; byte[] data = new byte[size * 2]; @@ -330,7 +332,7 @@ namespace ModbusDriver { while (numBytesRead != frameBytes.Length) numBytesRead += _serialPort.Read(frameBytes, numBytesRead, frameBytes.Length - numBytesRead); - if (frameBytes[0] == _slaveId && Utility.CheckSumCRC(frameBytes)) + if (frameBytes[0] == func && Utility.CheckSumCRC(frameBytes)) { Array.Copy(frameBytes, 3, data, 0, data.Length); return data; @@ -348,14 +350,14 @@ namespace ModbusDriver public ItemData ReadInt32(DeviceAddress address) { - byte[] bit = ReadBytes(address, 4); + byte[] bit = ReadBytes(address, 2); return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : new ItemData(BitConverter.ToInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD); } public ItemData ReadUInt32(DeviceAddress address) { - byte[] bit = ReadBytes(address, 4); + byte[] bit = ReadBytes(address, 2); return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : new ItemData(BitConverter.ToUInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD); } @@ -409,7 +411,7 @@ namespace ModbusDriver public int WriteBytes(DeviceAddress address, byte[] bit) { - var data = WriteMultipleRegister(address.Start, bit); + var data = WriteMultipleRegister(address.Area, address.Start, bit); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -418,7 +420,7 @@ namespace ModbusDriver public int WriteBit(DeviceAddress address, bool bit) { - var data = WriteSingleCoils(address.Start + address.Bit, bit); + var data = WriteSingleCoils(address.Area, address.Start + address.Bit, bit); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -427,7 +429,7 @@ namespace ModbusDriver public int WriteBits(DeviceAddress address, byte bits) { - var data = WriteSingleRegister(address.Start, new byte[] { bits }); + var data = WriteSingleRegister(address.Area, address.Start, new byte[] { bits }); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -436,7 +438,7 @@ namespace ModbusDriver public int WriteInt16(DeviceAddress address, short value) { - var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value)); + var data = WriteSingleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); _serialPort.Write(data, 0, data.Length); var chr = _serialPort.ReadByte(); return (chr & 0x80) > 0 ? -1 : 0; @@ -444,7 +446,7 @@ namespace ModbusDriver public int WriteUInt16(DeviceAddress address, ushort value) { - var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value)); + var data = WriteSingleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); _serialPort.Write(data, 0, data.Length); var chr = _serialPort.ReadByte(); return (chr & 0x80) > 0 ? -1 : 0; @@ -452,7 +454,7 @@ namespace ModbusDriver public int WriteUInt32(DeviceAddress address, uint value) { - var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -461,7 +463,7 @@ namespace ModbusDriver public int WriteInt32(DeviceAddress address, int value) { - var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -470,7 +472,7 @@ namespace ModbusDriver public int WriteFloat(DeviceAddress address, float value) { - var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); @@ -479,11 +481,11 @@ namespace ModbusDriver public int WriteString(DeviceAddress address, string str) { - var data = WriteMultipleRegister(address.Start, Encoding.ASCII.GetBytes(str)); + var data = WriteMultipleRegister(address.Area, address.Start, Encoding.ASCII.GetBytes(str)); _serialPort.Write(data, 0, data.Length); _serialPort.ReadByte(); var chr = _serialPort.ReadByte(); - return chr == _slaveId ? -1 : 0; + return chr == address.DBNumber ? -1 : 0; } public int WriteValue(DeviceAddress address, object value) diff --git a/SCADA/Program/ModbusDriver/ModbusTCPDriver.cs b/SCADA/Program/ModbusDriver/ModbusTCPDriver.cs index 71d5d37..48e05f2 100644 --- a/SCADA/Program/ModbusDriver/ModbusTCPDriver.cs +++ b/SCADA/Program/ModbusDriver/ModbusTCPDriver.cs @@ -32,7 +32,14 @@ namespace ModbusDriver DeviceAddress dv = DeviceAddress.Empty; if (string.IsNullOrEmpty(address)) return dv; - dv.Area = _slaveId; + var sindex = address.IndexOf(':'); + if (sindex > 0) + { + int slaveId; + if (int.TryParse(address.Substring(0, sindex), out slaveId)) + dv.Area = slaveId; + address = address.Substring(sindex + 1); + } switch (address[0]) { case '0': @@ -145,16 +152,6 @@ namespace ModbusDriver set { _timeout = value; } } - byte _slaveId;//设备ID 单元号 字节号 - /// - /// 设备ID 单元号 字节号 - /// - public byte SlaveId - { - get { return _slaveId; } - set { _slaveId = value; } - } - List _grps = new List(20); public IEnumerable Groups { @@ -167,14 +164,13 @@ namespace ModbusDriver get { return _server; } } - public ModbusTCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = "0", string spare2 = null) + public ModbusTCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = null, string spare2 = null) { _id = id; _name = name; _server = server; _ip = ip; _timeout = timeOut; - if (!string.IsNullOrEmpty(spare1)) byte.TryParse(spare1, out _slaveId); } public bool Connect() diff --git a/SCADA/dll/ModbusDriver.dll b/SCADA/dll/ModbusDriver.dll index f316ef7..b10193d 100644 Binary files a/SCADA/dll/ModbusDriver.dll and b/SCADA/dll/ModbusDriver.dll differ