From 8a58395bcf8383806bf14360df6360e66021161c Mon Sep 17 00:00:00 2001 From: tgreve85 Date: Mon, 13 Feb 2023 12:37:40 +0100 Subject: [PATCH 1/2] Update ModbusClient.cs Added parameter "modbusRtuOverEthernet" to send/receive ModbusRTU-Data over an RS485-to-Ethernet-Converter like Moxa NPort 5150 --- EasyModbus/ModbusClient.cs | 2087 +++++++++++++++++++++--------------- 1 file changed, 1212 insertions(+), 875 deletions(-) diff --git a/EasyModbus/ModbusClient.cs b/EasyModbus/ModbusClient.cs index b9e0285..99d4da8 100644 --- a/EasyModbus/ModbusClient.cs +++ b/EasyModbus/ModbusClient.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2018-2020 Rossmann-Engineering Permission is hereby granted, free of charge, to any person obtaining a copy of this software @@ -32,31 +32,32 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. namespace EasyModbus { - /// - /// Implements a ModbusClient. - /// - public partial class ModbusClient - { + /// + /// Implements a ModbusClient. + /// + public partial class ModbusClient + { public enum RegisterOrder { LowHigh = 0, HighLow = 1 }; - private bool debug=false; - private TcpClient tcpClient; - private string ipAddress = "127.0.0.1"; - private int port = 502; + private bool debug = false; + private TcpClient tcpClient; + private string ipAddress = "127.0.0.1"; + private int port = 502; + private bool modbusRtuOverEthernet = false; private uint transactionIdentifierInternal = 0; - private byte [] transactionIdentifier = new byte[2]; - private byte [] protocolIdentifier = new byte[2]; + private byte[] transactionIdentifier = new byte[2]; + private byte[] protocolIdentifier = new byte[2]; private byte[] crc = new byte[2]; - private byte [] length = new byte[2]; - private byte unitIdentifier = 0x01; - private byte functionCode; - private byte [] startingAddress = new byte[2]; - private byte [] quantity = new byte[2]; + private byte[] length = new byte[2]; + private byte unitIdentifier = 0x01; + private byte functionCode; + private byte[] startingAddress = new byte[2]; + private byte[] quantity = new byte[2]; private bool udpFlag = false; private int portOut; private int baudRate = 9600; private int connectTimeout = 1000; public byte[] receiveData; - public byte[] sendData; + public byte[] sendData; private SerialPort serialport; private Parity parity = Parity.Even; private StopBits stopBits = StopBits.One; @@ -66,7 +67,7 @@ public enum RegisterOrder { LowHigh = 0, HighLow = 1 }; public delegate void ReceiveDataChangedHandler(object sender); public event ReceiveDataChangedHandler ReceiveDataChanged; - + public delegate void SendDataChangedHandler(object sender); public event SendDataChangedHandler SendDataChanged; @@ -74,23 +75,24 @@ public enum RegisterOrder { LowHigh = 0, HighLow = 1 }; public event ConnectedChangedHandler ConnectedChanged; NetworkStream stream; - - /// - /// Constructor which determines the Master ip-address and the Master Port. - /// - /// IP-Address of the Master device - /// Listening port of the Master device (should be 502) - public ModbusClient(string ipAddress, int port) - { - if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-TCP, IPAddress: " + ipAddress + ", Port: "+port ,System.DateTime.Now); + + /// + /// Constructor which determines the Master ip-address and the Master Port. + /// + /// IP-Address of the Master device + /// Listening port of the Master device (should be 502) + public ModbusClient(string ipAddress, int port, bool modbusRtuOverEthernet = false) + { + if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-TCP, IPAddress: " + ipAddress + ", Port: " + port, System.DateTime.Now); #if (!COMMERCIAL) Console.WriteLine("EasyModbus Client Library Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine("Copyright (c) Stefan Rossmann Engineering Solutions"); Console.WriteLine(); #endif this.ipAddress = ipAddress; - this.port = port; - } + this.port = port; + this.modbusRtuOverEthernet = modbusRtuOverEthernet; + } /// /// Constructor which determines the Serial-Port @@ -98,7 +100,7 @@ public ModbusClient(string ipAddress, int port) /// Serial-Port Name e.G. "COM1" public ModbusClient(string serialPort) { - if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-RTU, COM-Port: " + serialPort ,System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-RTU, COM-Port: " + serialPort, System.DateTime.Now); #if (!COMMERCIAL) Console.WriteLine("EasyModbus Client Library Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine("Copyright (c) Stefan Rossmann Engineering Solutions"); @@ -111,8 +113,8 @@ public ModbusClient(string serialPort) serialport.StopBits = stopBits; serialport.WriteTimeout = 10000; serialport.ReadTimeout = connectTimeout; - - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); } /// @@ -120,24 +122,24 @@ public ModbusClient(string serialPort) /// public ModbusClient() { - if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-TCP" ,System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("EasyModbus library initialized for Modbus-TCP", System.DateTime.Now); #if (!COMMERCIAL) Console.WriteLine("EasyModbus Client Library Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine("Copyright (c) Stefan Rossmann Engineering Solutions"); Console.WriteLine(); #endif } - - /// - /// Establish connection to Master device in case of Modbus TCP. Opens COM-Port in case of Modbus RTU - /// - public void Connect() - { + + /// + /// Establish connection to Master device in case of Modbus TCP. Opens COM-Port in case of Modbus RTU + /// + public void Connect() + { if (serialport != null) { if (!serialport.IsOpen) { - if (debug) StoreLogData.Instance.Store("Open Serial port " + serialport.PortName,System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("Open Serial port " + serialport.PortName, System.DateTime.Now); serialport.BaudRate = baudRate; serialport.Parity = parity; serialport.StopBits = stopBits; @@ -145,8 +147,8 @@ public void Connect() serialport.ReadTimeout = connectTimeout; serialport.Open(); connected = true; - - + + } if (ConnectedChanged != null) try @@ -191,12 +193,12 @@ public void Connect() } } - - /// - /// Establish connection to Master device in case of Modbus TCP. - /// - public void Connect(string ipAddress, int port) - { + + /// + /// Establish connection to Master device in case of Modbus TCP. + /// + public void Connect(string ipAddress, int port) + { if (!udpFlag) { if (debug) StoreLogData.Instance.Store("Open TCP-Socket, IP-Address: " + ipAddress + ", Port: " + port, System.DateTime.Now); @@ -254,9 +256,9 @@ public static float ConvertRegistersToFloat(int[] registers) /// Connected float value public static float ConvertRegistersToFloat(int[] registers, RegisterOrder registerOrder) { - int [] swappedRegisters = {registers[0],registers[1]}; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] {registers[1],registers[0]}; + int[] swappedRegisters = { registers[0], registers[1] }; + if (registerOrder == RegisterOrder.HighLow) + swappedRegisters = new int[] { registers[1], registers[0] }; return ConvertRegistersToFloat(swappedRegisters); } @@ -396,16 +398,16 @@ public static double ConvertRegistersToDouble(int[] registers, RegisterOrder reg public static int[] ConvertFloatToRegisters(float floatValue) { byte[] floatBytes = BitConverter.GetBytes(floatValue); - byte[] highRegisterBytes = + byte[] highRegisterBytes = { floatBytes[2], floatBytes[3], 0, 0 }; - byte[] lowRegisterBytes = + byte[] lowRegisterBytes = { - + floatBytes[0], floatBytes[1], 0, @@ -442,16 +444,16 @@ public static int[] ConvertFloatToRegisters(float floatValue, RegisterOrder regi public static int[] ConvertIntToRegisters(Int32 intValue) { byte[] doubleBytes = BitConverter.GetBytes(intValue); - byte[] highRegisterBytes = + byte[] highRegisterBytes = { doubleBytes[2], doubleBytes[3], 0, 0 }; - byte[] lowRegisterBytes = + byte[] lowRegisterBytes = { - + doubleBytes[0], doubleBytes[1], 0, @@ -612,11 +614,11 @@ public static int[] ConvertDoubleToRegisters(double doubleValue, RegisterOrder r /// number of characters in String (must be even) /// Converted String public static string ConvertRegistersToString(int[] registers, int offset, int stringLength) - { - byte[] result = new byte[stringLength]; - byte[] registerResult = new byte[2]; - - for (int i = 0; i < stringLength/2; i++) + { + byte[] result = new byte[stringLength]; + byte[] registerResult = new byte[2]; + + for (int i = 0; i < stringLength / 2; i++) { registerResult = BitConverter.GetBytes(registers[offset + i]); result[i * 2] = registerResult[0]; @@ -637,7 +639,7 @@ public static int[] ConvertStringToRegisters(string stringToConvert) for (int i = 0; i < returnarray.Length; i++) { returnarray[i] = array[i * 2]; - if (i*2 +1< array.Length) + if (i * 2 + 1 < array.Length) { returnarray[i] = returnarray[i] | ((int)array[i * 2 + 1] << 8); } @@ -653,7 +655,7 @@ public static int[] ConvertStringToRegisters(string stringToConvert) /// Number of bytes to calculate CRC /// First byte in buffer to start calculating CRC public static UInt16 calculateCRC(byte[] data, UInt16 numberOfBytes, int startByte) - { + { byte[] auchCRCHi = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, @@ -674,7 +676,7 @@ public static UInt16 calculateCRC(byte[] data, UInt16 numberOfBytes, int startBy 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; - + byte[] auchCRCLo = { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, @@ -696,11 +698,11 @@ public static UInt16 calculateCRC(byte[] data, UInt16 numberOfBytes, int startBy 0x40 }; UInt16 usDataLen = numberOfBytes; - byte uchCRCHi = 0xFF ; - byte uchCRCLo = 0xFF ; + byte uchCRCHi = 0xFF; + byte uchCRCLo = 0xFF; int i = 0; - int uIndex ; - while (usDataLen>0) + int uIndex; + while (usDataLen > 0) { usDataLen--; if ((i + startByte) < data.Length) @@ -711,7 +713,7 @@ public static UInt16 calculateCRC(byte[] data, UInt16 numberOfBytes, int startBy } i++; } - return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); + return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); } private bool dataReceived = false; @@ -720,64 +722,64 @@ public static UInt16 calculateCRC(byte[] data, UInt16 numberOfBytes, int startBy private int bytesToRead = 0; private int akjjjctualPositionToRead = 0; DateTime dateTimeLastRead; -/* - private void DataReceivedHandler(object sender, - SerialDataReceivedEventArgs e) - { - long ticksWait = TimeSpan.TicksPerMillisecond * 2000; - SerialPort sp = (SerialPort)sender; - - if (bytesToRead == 0 || sp.BytesToRead == 0) - { - actualPositionToRead = 0; - sp.DiscardInBuffer(); - dataReceived = false; - receiveActive = false; - return; - } + /* + private void DataReceivedHandler(object sender, + SerialDataReceivedEventArgs e) + { + long ticksWait = TimeSpan.TicksPerMillisecond * 2000; + SerialPort sp = (SerialPort)sender; - if (actualPositionToRead == 0 && !dataReceived) - readBuffer = new byte[256]; + if (bytesToRead == 0 || sp.BytesToRead == 0) + { + actualPositionToRead = 0; + sp.DiscardInBuffer(); + dataReceived = false; + receiveActive = false; + return; + } - //if ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) > ticksWait) - //{ - // readBuffer = new byte[256]; - // actualPositionToRead = 0; - //} - int numberOfBytesInBuffer = sp.BytesToRead; - sp.Read(readBuffer, actualPositionToRead, ((numberOfBytesInBuffer + actualPositionToRead) > readBuffer.Length) ? 0 : numberOfBytesInBuffer); - actualPositionToRead = actualPositionToRead + numberOfBytesInBuffer; - //sp.DiscardInBuffer(); - //if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) - if (actualPositionToRead >= bytesToRead) - { + if (actualPositionToRead == 0 && !dataReceived) + readBuffer = new byte[256]; + + //if ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) > ticksWait) + //{ + // readBuffer = new byte[256]; + // actualPositionToRead = 0; + //} + int numberOfBytesInBuffer = sp.BytesToRead; + sp.Read(readBuffer, actualPositionToRead, ((numberOfBytesInBuffer + actualPositionToRead) > readBuffer.Length) ? 0 : numberOfBytesInBuffer); + actualPositionToRead = actualPositionToRead + numberOfBytesInBuffer; + //sp.DiscardInBuffer(); + //if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) + if (actualPositionToRead >= bytesToRead) + { - dataReceived = true; - bytesToRead = 0; - actualPositionToRead = 0; - if (debug) StoreLogData.Instance.Store("Received Serial-Data: " + BitConverter.ToString(readBuffer), System.DateTime.Now); + dataReceived = true; + bytesToRead = 0; + actualPositionToRead = 0; + if (debug) StoreLogData.Instance.Store("Received Serial-Data: " + BitConverter.ToString(readBuffer), System.DateTime.Now); - } + } - //dateTimeLastRead = DateTime.Now; - } - */ + //dateTimeLastRead = DateTime.Now; + } + */ + - private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { serialport.DataReceived -= DataReceivedHandler; //while (receiveActive | dataReceived) - // System.Threading.Thread.Sleep(10); - receiveActive = true; - - const long ticksWait = TimeSpan.TicksPerMillisecond * 2000;//((40*10000000) / this.baudRate); - - - SerialPort sp = (SerialPort)sender; + // System.Threading.Thread.Sleep(10); + receiveActive = true; + + const long ticksWait = TimeSpan.TicksPerMillisecond * 2000;//((40*10000000) / this.baudRate); + + + SerialPort sp = (SerialPort)sender; if (bytesToRead == 0) { sp.DiscardInBuffer(); @@ -786,50 +788,53 @@ private void DataReceivedHandler(object sender, return; } readBuffer = new byte[256]; - int numbytes=0; + int numbytes = 0; int actualPositionToRead = 0; DateTime dateTimeLastRead = DateTime.Now; - do{ - try { - dateTimeLastRead = DateTime.Now; - while ((sp.BytesToRead) == 0) - { - System.Threading.Thread.Sleep(10); - if ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) > ticksWait) - break; - } - numbytes=sp.BytesToRead; - - - byte[] rxbytearray = new byte[numbytes]; - sp.Read(rxbytearray, 0, numbytes); - Array.Copy(rxbytearray,0, readBuffer,actualPositionToRead, (actualPositionToRead + rxbytearray.Length) <= bytesToRead ? rxbytearray.Length : bytesToRead - actualPositionToRead); - - actualPositionToRead = actualPositionToRead + rxbytearray.Length; - - } - catch (Exception){ - - } + do + { + try + { + dateTimeLastRead = DateTime.Now; + while ((sp.BytesToRead) == 0) + { + System.Threading.Thread.Sleep(10); + if ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) > ticksWait) + break; + } + numbytes = sp.BytesToRead; + + + byte[] rxbytearray = new byte[numbytes]; + sp.Read(rxbytearray, 0, numbytes); + Array.Copy(rxbytearray, 0, readBuffer, actualPositionToRead, (actualPositionToRead + rxbytearray.Length) <= bytesToRead ? rxbytearray.Length : bytesToRead - actualPositionToRead); + + actualPositionToRead = actualPositionToRead + rxbytearray.Length; + + } + catch (Exception) + { + + } if (bytesToRead <= actualPositionToRead) break; - if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) + if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) break; } - while ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) < ticksWait) ; - + while ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) < ticksWait); + //10.000 Ticks in 1 ms receiveData = new byte[actualPositionToRead]; - Array.Copy(readBuffer, 0, receiveData, 0, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead: readBuffer.Length); - if (debug) StoreLogData.Instance.Store("Received Serial-Data: "+BitConverter.ToString(readBuffer) ,System.DateTime.Now); + Array.Copy(readBuffer, 0, receiveData, 0, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length); + if (debug) StoreLogData.Instance.Store("Received Serial-Data: " + BitConverter.ToString(readBuffer), System.DateTime.Now); bytesToRead = 0; - - + + dataReceived = true; receiveActive = false; serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); @@ -839,23 +844,23 @@ private void DataReceivedHandler(object sender, ReceiveDataChanged(this); } - + //sp.DiscardInBuffer(); } public static bool DetectValidModbusFrame(byte[] readBuffer, int length) { - // minimum length 6 bytes - if (length < 6) - return false; - //SlaveID correct - if ((readBuffer[0] < 1) | (readBuffer[0] > 247)) - return false; + // minimum length 6 bytes + if (length < 6) + return false; + //SlaveID correct + if ((readBuffer[0] < 1) | (readBuffer[0] > 247)) + return false; //CRC correct? byte[] crc = new byte[2]; - crc = BitConverter.GetBytes(calculateCRC(readBuffer, (ushort)(length-2), 0)); - if (crc[0] != readBuffer[length-2] | crc[1] != readBuffer[length-1]) - return false; + crc = BitConverter.GetBytes(calculateCRC(readBuffer, (ushort)(length - 2), 0)); + if (crc[0] != readBuffer[length - 2] | crc[1] != readBuffer[length - 1]) + return false; return true; } @@ -868,52 +873,52 @@ public static bool DetectValidModbusFrame(byte[] readBuffer, int length) /// Number of discrete Inputs to read /// Boolean Array which contains the discrete Inputs public bool[] ReadDiscreteInputs(int startingAddress, int quantity) - { - if (debug) StoreLogData.Instance.Store("FC2 (Read Discrete Inputs from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now); - transactionIdentifierInternal ++; + { + if (debug) StoreLogData.Instance.Store("FC2 (Read Discrete Inputs from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); + transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } - if (tcpClient == null & !udpFlag & serialport==null) - { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + } + if (tcpClient == null & !udpFlag & serialport == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - if (startingAddress > 65535 | quantity >2000) - { - if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); - throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); - } - bool[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x02; - this.startingAddress = BitConverter.GetBytes(startingAddress); - this.quantity = BitConverter.GetBytes(quantity); + } + if (startingAddress > 65535 | quantity > 2000) + { + if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); + throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); + } + bool[] response; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)0x0006); + this.functionCode = 0x02; + this.startingAddress = BitConverter.GetBytes(startingAddress); + this.quantity = BitConverter.GetBytes(quantity); Byte[] data = new byte[] - { + { this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - this.quantity[1], - this.quantity[0], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + this.quantity[1], + this.quantity[0], this.crc[0], this.crc[1] }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; if (serialport != null) { @@ -922,20 +927,20 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) bytesToRead = 5 + quantity / 8; else bytesToRead = 6 + quantity / 8; - // serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -946,24 +951,56 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) - sw_delay.SpinOnce(); - - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + sw_delay.SpinOnce(); + + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + if (quantity % 8 == 0) + bytesToRead = 5 + quantity / 8; + else + bytesToRead = 6 + quantity / 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -971,56 +1008,56 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) } else { - stream.Write(data, 0, data.Length-2); - if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } + stream.Write(data, 0, data.Length - 2); + if (debug) + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - } + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x82 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x82 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x82 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x82 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6)); + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8] + 3), 6)); if ((crc[0] != data[data[8] + 9] | crc[1] != data[data[8] + 10]) & dataReceived) { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1034,7 +1071,7 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) } else if (!dataReceived) { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1047,15 +1084,15 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) } } } - response = new bool[quantity]; - for (int i = 0; i < quantity; i++) - { - int intData = data[9+i/8]; - int mask = Convert.ToInt32(Math.Pow(2, (i%8))); - response[i] = Convert.ToBoolean((intData & mask)/mask); - } - return (response); - } + response = new bool[quantity]; + for (int i = 0; i < quantity; i++) + { + int intData = data[9 + i / 8]; + int mask = Convert.ToInt32(Math.Pow(2, (i % 8))); + response[i] = Convert.ToBoolean((intData & mask) / mask); + } + return (response); + } /// @@ -1065,73 +1102,73 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) /// Numer of coils to read /// Boolean Array which contains the coils public bool[] ReadCoils(int startingAddress, int quantity) - { - if (debug) StoreLogData.Instance.Store("FC1 (Read Coils from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("FC1 (Read Coils from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - if (startingAddress > 65535 | quantity >2000) - { - if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); - throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); - } - bool[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x01; - this.startingAddress = BitConverter.GetBytes(startingAddress); - this.quantity = BitConverter.GetBytes(quantity); - Byte[] data = new byte[]{ + } + if (startingAddress > 65535 | quantity > 2000) + { + if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); + throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); + } + bool[] response; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)0x0006); + this.functionCode = 0x01; + this.startingAddress = BitConverter.GetBytes(startingAddress); + this.quantity = BitConverter.GetBytes(quantity); + Byte[] data = new byte[]{ this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - this.quantity[1], - this.quantity[0], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + this.quantity[1], + this.quantity[0], this.crc[0], this.crc[1] }; crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; + data[12] = crc[0]; + data[13] = crc[1]; if (serialport != null) { dataReceived = false; if (quantity % 8 == 0) - bytesToRead = 5 + quantity/8; + bytesToRead = 5 + quantity / 8; else - bytesToRead = 6 + quantity/8; - // serialport.ReceivedBytesThreshold = bytesToRead; + bytesToRead = 6 + quantity / 8; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -1143,24 +1180,56 @@ public bool[] ReadCoils(int startingAddress, int quantity) { while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); - - data = new byte[2100]; - - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + + data = new byte[2100]; + + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } - else if (tcpClient.Client.Connected | udpFlag) - { + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + if (quantity % 8 == 0) + bytesToRead = 5 + quantity / 8; + else + bytesToRead = 6 + quantity / 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } + else if (tcpClient.Client.Connected | udpFlag) + { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -1168,57 +1237,57 @@ public bool[] ReadCoils(int startingAddress, int quantity) } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send MocbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send MocbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } - } + } if (data[7] == 0x81 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x81 & data[8] == 0x02) - { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x81 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x81 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6)); - if ((crc[0] != data[data[8]+9] | crc[1] != data[data[8]+10]) & dataReceived) + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8] + 3), 6)); + if ((crc[0] != data[data[8] + 9] | crc[1] != data[data[8] + 10]) & dataReceived) { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1232,7 +1301,7 @@ public bool[] ReadCoils(int startingAddress, int quantity) } else if (!dataReceived) { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1245,15 +1314,15 @@ public bool[] ReadCoils(int startingAddress, int quantity) } } } - response = new bool[quantity]; - for (int i = 0; i < quantity; i++) - { - int intData = data[9+i/8]; - int mask = Convert.ToInt32(Math.Pow(2, (i%8))); - response[i] = Convert.ToBoolean((intData & mask)/mask); - } - return (response); - } + response = new bool[quantity]; + for (int i = 0; i < quantity; i++) + { + int intData = data[9 + i / 8]; + int mask = Convert.ToInt32(Math.Pow(2, (i % 8))); + response[i] = Convert.ToBoolean((intData & mask) / mask); + } + return (response); + } /// @@ -1263,44 +1332,44 @@ public bool[] ReadCoils(int startingAddress, int quantity) /// Number of holding registers to be read /// Int Array which contains the holding registers public int[] ReadHoldingRegisters(int startingAddress, int quantity) - { - if (debug) StoreLogData.Instance.Store("FC3 (Read Holding Registers from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("FC3 (Read Holding Registers from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - if (startingAddress > 65535 | quantity >125) - { - if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); - throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125"); - } - int[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x03; - this.startingAddress = BitConverter.GetBytes(startingAddress); - this.quantity = BitConverter.GetBytes(quantity); - Byte[] data = new byte[]{ this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - this.quantity[1], - this.quantity[0], + } + if (startingAddress > 65535 | quantity > 125) + { + if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); + throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125"); + } + int[] response; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)0x0006); + this.functionCode = 0x03; + this.startingAddress = BitConverter.GetBytes(startingAddress); + this.quantity = BitConverter.GetBytes(quantity); + Byte[] data = new byte[]{ this.transactionIdentifier[1], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + this.quantity[1], + this.quantity[0], this.crc[0], this.crc[1] }; @@ -1311,50 +1380,88 @@ public int[] ReadHoldingRegisters(int startingAddress, int quantity) { dataReceived = false; bytesToRead = 5 + 2 * quantity; -// serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; - + DateTime dateTimeSend = DateTime.Now; byte receivedUnitIdentifier = 0xFF; SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } - else if (tcpClient.Client.Connected | udpFlag) - { + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 5 + 2 * quantity; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } + else if (tcpClient.Client.Connected | udpFlag) + { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -1362,57 +1469,57 @@ public int[] ReadHoldingRegisters(int startingAddress, int quantity) } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + } data = new Byte[256]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } - } + } if (data[7] == 0x83 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x83 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x83 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x83 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6)); - if ((crc[0] != data[data[8]+9] | crc[1] != data[data[8]+10])& dataReceived) + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8] + 3), 6)); + if ((crc[0] != data[data[8] + 9] | crc[1] != data[data[8] + 10]) & dataReceived) { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1426,7 +1533,7 @@ public int[] ReadHoldingRegisters(int startingAddress, int quantity) } else if (!dataReceived) { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1437,25 +1544,25 @@ public int[] ReadHoldingRegisters(int startingAddress, int quantity) countRetries++; return ReadHoldingRegisters(startingAddress, quantity); } - + } } - response = new int[quantity]; - for (int i = 0; i < quantity; i++) - { - byte lowByte; - byte highByte; - highByte = data[9+i*2]; - lowByte = data[9+i*2+1]; - - data[9+i*2] = lowByte; - data[9+i*2+1] = highByte; - - response[i] = BitConverter.ToInt16(data,(9+i*2)); - } - return (response); - } + response = new int[quantity]; + for (int i = 0; i < quantity; i++) + { + byte lowByte; + byte highByte; + highByte = data[9 + i * 2]; + lowByte = data[9 + i * 2 + 1]; + + data[9 + i * 2] = lowByte; + data[9 + i * 2 + 1] = highByte; + + response[i] = BitConverter.ToInt16(data, (9 + i * 2)); + } + return (response); + } @@ -1466,47 +1573,47 @@ public int[] ReadHoldingRegisters(int startingAddress, int quantity) /// Number of input registers to be read /// Int Array which contains the input registers public int[] ReadInputRegisters(int startingAddress, int quantity) - { - - if (debug) StoreLogData.Instance.Store("FC4 (Read Input Registers from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now); + { + + if (debug) StoreLogData.Instance.Store("FC4 (Read Input Registers from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - if (startingAddress > 65535 | quantity >125) - { - if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); - throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125"); - } - int[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x04; - this.startingAddress = BitConverter.GetBytes(startingAddress); - this.quantity = BitConverter.GetBytes(quantity); - Byte[] data = new byte[]{ this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - this.quantity[1], - this.quantity[0], + } + if (startingAddress > 65535 | quantity > 125) + { + if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); + throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125"); + } + int[] response; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)0x0006); + this.functionCode = 0x04; + this.startingAddress = BitConverter.GetBytes(startingAddress); + this.quantity = BitConverter.GetBytes(quantity); + Byte[] data = new byte[]{ this.transactionIdentifier[1], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + this.quantity[1], + this.quantity[0], this.crc[0], - this.crc[1] + this.crc[1] }; crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); data[12] = crc[0]; @@ -1517,20 +1624,20 @@ public int[] ReadInputRegisters(int startingAddress, int quantity) bytesToRead = 5 + 2 * quantity; - // serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -1540,26 +1647,67 @@ public int[] ReadInputRegisters(int startingAddress, int quantity) SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } - + if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } - else if (tcpClient.Client.Connected | udpFlag) - { + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 5 + 2 * quantity; + + + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } + else if (tcpClient.Client.Connected | udpFlag) + { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -1567,57 +1715,56 @@ public int[] ReadInputRegisters(int startingAddress, int quantity) } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } - if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } - + } } - } + } if (data[7] == 0x84 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x84 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x84 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x84 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6)); - if ((crc[0] != data[data[8]+9] | crc[1] != data[data[8]+10]) & dataReceived) + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8] + 3), 6)); + if ((crc[0] != data[data[8] + 9] | crc[1] != data[data[8] + 10]) & dataReceived) { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1631,59 +1778,59 @@ public int[] ReadInputRegisters(int startingAddress, int quantity) } else if (!dataReceived) { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; throw new TimeoutException("No Response from Modbus Slave"); - + } else { countRetries++; return ReadInputRegisters(startingAddress, quantity); } - - } - } - response = new int[quantity]; - for (int i = 0; i < quantity; i++) - { - byte lowByte; - byte highByte; - highByte = data[9+i*2]; - lowByte = data[9+i*2+1]; - - data[9+i*2] = lowByte; - data[9+i*2+1] = highByte; - - response[i] = BitConverter.ToInt16(data,(9+i*2)); - } - return (response); - } - - - /// - /// Write single Coil to Master device (FC5). - /// + + } + } + response = new int[quantity]; + for (int i = 0; i < quantity; i++) + { + byte lowByte; + byte highByte; + highByte = data[9 + i * 2]; + lowByte = data[9 + i * 2 + 1]; + + data[9 + i * 2] = lowByte; + data[9 + i * 2 + 1] = highByte; + + response[i] = BitConverter.ToInt16(data, (9 + i * 2)); + } + return (response); + } + + + /// + /// Write single Coil to Master device (FC5). + /// /// Coil to be written - /// Coil Value to be written + /// Coil Value to be written public void WriteSingleCoil(int startingAddress, bool value) { - - if (debug) StoreLogData.Instance.Store("FC5 (Write single coil to Master device), StartingAddress: "+ startingAddress+", Value: " + value, System.DateTime.Now); + + if (debug) StoreLogData.Instance.Store("FC5 (Write single coil to Master device), StartingAddress: " + startingAddress + ", Value: " + value, System.DateTime.Now); transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } + } byte[] coilValue = new byte[2]; this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); @@ -1698,20 +1845,20 @@ public void WriteSingleCoil(int startingAddress, bool value) { coilValue = BitConverter.GetBytes((int)0x0000); } - Byte[] data = new byte[]{ this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - coilValue[1], - coilValue[0], + Byte[] data = new byte[]{ this.transactionIdentifier[1], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + coilValue[1], + coilValue[0], this.crc[0], - this.crc[1] + this.crc[1] }; crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); data[12] = crc[0]; @@ -1720,20 +1867,20 @@ public void WriteSingleCoil(int startingAddress, bool value) { dataReceived = false; bytesToRead = 8; - // serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -1743,12 +1890,12 @@ public void WriteSingleCoil(int startingAddress, bool value) SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) @@ -1757,6 +1904,44 @@ public void WriteSingleCoil(int startingAddress, bool value) countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) @@ -1773,55 +1958,55 @@ public void WriteSingleCoil(int startingAddress, bool value) { stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - - } + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x85 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x85 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x85 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x85 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) + { + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1833,9 +2018,9 @@ public void WriteSingleCoil(int startingAddress, bool value) WriteSingleCoil(startingAddress, value); } } - else if (!dataReceived) - { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + else if (!dataReceived) + { + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -1859,41 +2044,41 @@ public void WriteSingleCoil(int startingAddress, bool value) /// Register Value to be written public void WriteSingleRegister(int startingAddress, int value) { - if (debug) StoreLogData.Instance.Store("FC6 (Write single register to Master device), StartingAddress: "+ startingAddress+", Value: " + value, System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FC6 (Write single register to Master device), StartingAddress: " + startingAddress + ", Value: " + value, System.DateTime.Now); transactionIdentifierInternal++; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } + } byte[] registerValue = new byte[2]; this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); this.length = BitConverter.GetBytes((int)0x0006); this.functionCode = 0x06; this.startingAddress = BitConverter.GetBytes(startingAddress); - registerValue = BitConverter.GetBytes((int)value); - - Byte[] data = new byte[]{ this.transactionIdentifier[1], - this.transactionIdentifier[0], - this.protocolIdentifier[1], - this.protocolIdentifier[0], - this.length[1], - this.length[0], - this.unitIdentifier, - this.functionCode, - this.startingAddress[1], - this.startingAddress[0], - registerValue[1], - registerValue[0], + registerValue = BitConverter.GetBytes((int)value); + + Byte[] data = new byte[]{ this.transactionIdentifier[1], + this.transactionIdentifier[0], + this.protocolIdentifier[1], + this.protocolIdentifier[0], + this.length[1], + this.length[0], + this.unitIdentifier, + this.functionCode, + this.startingAddress[1], + this.startingAddress[0], + registerValue[1], + registerValue[0], this.crc[0], - this.crc[1] + this.crc[1] }; crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); data[12] = crc[0]; @@ -1902,20 +2087,20 @@ public void WriteSingleRegister(int startingAddress, int value) { dataReceived = false; bytesToRead = 8; -// serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, 8); if (debug) { - byte [] debugData = new byte[8]; - Array.Copy(data, 6, debugData, 0, 8); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[8]; - Array.Copy(data, 6, sendData, 0, 8); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -1925,18 +2110,56 @@ public void WriteSingleRegister(int startingAddress, int value) SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, 8); + if (debug) + { + byte[] debugData = new byte[8]; + Array.Copy(data, 6, debugData, 0, 8); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(this); + + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) @@ -1953,55 +2176,55 @@ public void WriteSingleRegister(int startingAddress, int value) { stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } - if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x86 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x86 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x86 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x86 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) + { + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2013,9 +2236,9 @@ public void WriteSingleRegister(int startingAddress, int value) WriteSingleRegister(startingAddress, value); } } - else if (!dataReceived) - { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + else if (!dataReceived) + { + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2039,43 +2262,43 @@ public void WriteSingleRegister(int startingAddress, int value) public void WriteMultipleCoils(int startingAddress, bool[] values) { string debugString = ""; - for (int i = 0; i < values.Length;i++) - debugString = debugString + values[i] + " "; - if (debug) StoreLogData.Instance.Store("FC15 (Write multiple coils to Master device), StartingAddress: "+ startingAddress+", Values: " + debugString, System.DateTime.Now); + for (int i = 0; i < values.Length; i++) + debugString = debugString + values[i] + " "; + if (debug) StoreLogData.Instance.Store("FC15 (Write multiple coils to Master device), StartingAddress: " + startingAddress + ", Values: " + debugString, System.DateTime.Now); transactionIdentifierInternal++; - byte byteCount = (byte)((values.Length % 8 != 0 ? values.Length / 8 + 1: (values.Length / 8))); + byte byteCount = (byte)((values.Length % 8 != 0 ? values.Length / 8 + 1 : (values.Length / 8))); byte[] quantityOfOutputs = BitConverter.GetBytes((int)values.Length); byte singleCoilValue = 0; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } + } this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)(7+(byteCount))); + this.length = BitConverter.GetBytes((int)(7 + (byteCount))); this.functionCode = 0x0F; this.startingAddress = BitConverter.GetBytes(startingAddress); - Byte[] data = new byte[14 +2 + (values.Length % 8 != 0 ? values.Length/8 : (values.Length / 8)-1)]; + Byte[] data = new byte[14 + 2 + (values.Length % 8 != 0 ? values.Length / 8 : (values.Length / 8) - 1)]; data[0] = this.transactionIdentifier[1]; data[1] = this.transactionIdentifier[0]; data[2] = this.protocolIdentifier[1]; - data[3] = this.protocolIdentifier[0]; - data[4] = this.length[1]; - data[5] = this.length[0]; - data[6] = this.unitIdentifier; - data[7] = this.functionCode; - data[8] = this.startingAddress[1]; - data[9] = this.startingAddress[0]; + data[3] = this.protocolIdentifier[0]; + data[4] = this.length[1]; + data[5] = this.length[0]; + data[6] = this.unitIdentifier; + data[7] = this.functionCode; + data[8] = this.startingAddress[1]; + data[9] = this.startingAddress[0]; data[10] = quantityOfOutputs[1]; data[11] = quantityOfOutputs[0]; data[12] = byteCount; @@ -2090,9 +2313,9 @@ public void WriteMultipleCoils(int startingAddress, bool[] values) CoilValue = 0; - singleCoilValue = (byte)((int)CoilValue<<(i%8) | (int)singleCoilValue); + singleCoilValue = (byte)((int)CoilValue << (i % 8) | (int)singleCoilValue); - data[13 + (i / 8)] = singleCoilValue; + data[13 + (i / 8)] = singleCoilValue; } crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); data[data.Length - 2] = crc[0]; @@ -2101,20 +2324,20 @@ public void WriteMultipleCoils(int startingAddress, bool[] values) { dataReceived = false; bytesToRead = 8; - // serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, data.Length - 6); if (debug) { - byte [] debugData = new byte[data.Length - 6]; - Array.Copy(data, 6, debugData, 0, data.Length - 6); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[data.Length - 6]; - Array.Copy(data, 6, sendData, 0, data.Length - 6); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -2124,83 +2347,121 @@ public void WriteMultipleCoils(int startingAddress, bool[] values) SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, data.Length - 6); + if (debug) + { + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); + + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); + data = udpClient.Receive(ref endPoint); } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - - } + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x8F & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x8F & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x8F & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x8F & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) + { + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2212,9 +2473,9 @@ public void WriteMultipleCoils(int startingAddress, bool[] values) WriteMultipleCoils(startingAddress, values); } } - else if (!dataReceived) - { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + else if (!dataReceived) + { + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2238,30 +2499,30 @@ public void WriteMultipleCoils(int startingAddress, bool[] values) public void WriteMultipleRegisters(int startingAddress, int[] values) { string debugString = ""; - for (int i = 0; i < values.Length;i++) - debugString = debugString + values[i] + " "; - if (debug) StoreLogData.Instance.Store("FC16 (Write multiple Registers to Server device), StartingAddress: "+ startingAddress+", Values: " + debugString, System.DateTime.Now); + for (int i = 0; i < values.Length; i++) + debugString = debugString + values[i] + " "; + if (debug) StoreLogData.Instance.Store("FC16 (Write multiple Registers to Server device), StartingAddress: " + startingAddress + ", Values: " + debugString, System.DateTime.Now); transactionIdentifierInternal++; byte byteCount = (byte)(values.Length * 2); byte[] quantityOfOutputs = BitConverter.GetBytes((int)values.Length); if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } + } this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)(7+values.Length*2)); + this.length = BitConverter.GetBytes((int)(7 + values.Length * 2)); this.functionCode = 0x10; this.startingAddress = BitConverter.GetBytes(startingAddress); - Byte[] data = new byte[13+2 + values.Length*2]; + Byte[] data = new byte[13 + 2 + values.Length * 2]; data[0] = this.transactionIdentifier[1]; data[1] = this.transactionIdentifier[0]; data[2] = this.protocolIdentifier[1]; @@ -2278,8 +2539,8 @@ public void WriteMultipleRegisters(int startingAddress, int[] values) for (int i = 0; i < values.Length; i++) { byte[] singleRegisterValue = BitConverter.GetBytes((int)values[i]); - data[13 + i*2] = singleRegisterValue[1]; - data[14 + i*2] = singleRegisterValue[0]; + data[13 + i * 2] = singleRegisterValue[1]; + data[14 + i * 2] = singleRegisterValue[0]; } crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); data[data.Length - 2] = crc[0]; @@ -2288,21 +2549,21 @@ public void WriteMultipleRegisters(int startingAddress, int[] values) { dataReceived = false; bytesToRead = 8; -// serialport.ReceivedBytesThreshold = bytesToRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, data.Length - 6); if (debug) { - byte [] debugData = new byte[data.Length - 6]; - Array.Copy(data, 6, debugData, 0, data.Length - 6); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); } - if (SendDataChanged != null) - { - sendData = new byte[data.Length - 6]; - Array.Copy(data, 6, sendData, 0, data.Length - 6); - SendDataChanged(this); - + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); + } data = new byte[2100]; readBuffer = new byte[256]; @@ -2312,25 +2573,64 @@ public void WriteMultipleRegisters(int startingAddress, int[] values) SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 8; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, data.Length - 6); + + if (debug) + { + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); + + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -2338,56 +2638,56 @@ public void WriteMultipleRegisters(int startingAddress, int[] values) } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } - if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + } data = new Byte[2100]; int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x90 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x90 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x90 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x90 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } if (serialport != null) { - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - if ((crc[0] != data[12] | crc[1] != data[13]) &dataReceived) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + if ((crc[0] != data[12] | crc[1] != data[13]) & dataReceived) + { + if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2399,9 +2699,9 @@ public void WriteMultipleRegisters(int startingAddress, int[] values) WriteMultipleRegisters(startingAddress, values); } } - else if (!dataReceived) - { - if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); + else if (!dataReceived) + { + if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now); if (NumberOfRetries <= countRetries) { countRetries = 0; @@ -2429,31 +2729,31 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea { string debugString = ""; - for (int i = 0; i < values.Length;i++) - debugString = debugString + values[i] + " "; - if (debug) StoreLogData.Instance.Store("FC23 (Read and Write multiple Registers to Server device), StartingAddress Read: "+ startingAddressRead+ ", Quantity Read: "+quantityRead+", startingAddressWrite: " + startingAddressWrite +", Values: " + debugString, System.DateTime.Now); + for (int i = 0; i < values.Length; i++) + debugString = debugString + values[i] + " "; + if (debug) StoreLogData.Instance.Store("FC23 (Read and Write multiple Registers to Server device), StartingAddress Read: " + startingAddressRead + ", Quantity Read: " + quantityRead + ", startingAddressWrite: " + startingAddressWrite + ", Values: " + debugString, System.DateTime.Now); transactionIdentifierInternal++; - byte [] startingAddressReadLocal = new byte[2]; - byte [] quantityReadLocal = new byte[2]; + byte[] startingAddressReadLocal = new byte[2]; + byte[] quantityReadLocal = new byte[2]; byte[] startingAddressWriteLocal = new byte[2]; byte[] quantityWriteLocal = new byte[2]; byte writeByteCountLocal = 0; if (serialport != null) if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - } + } if (tcpClient == null & !udpFlag & serialport == null) { - if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } + } if (startingAddressRead > 65535 | quantityRead > 125 | startingAddressWrite > 65535 | values.Length > 121) { - if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); - throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); - } + if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now); + throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); + } int[] response; this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); @@ -2464,30 +2764,30 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea startingAddressWriteLocal = BitConverter.GetBytes(startingAddressWrite); quantityWriteLocal = BitConverter.GetBytes(values.Length); writeByteCountLocal = Convert.ToByte(values.Length * 2); - Byte[] data = new byte[17 +2+ values.Length*2]; - data[0] = this.transactionIdentifier[1]; - data[1] = this.transactionIdentifier[0]; - data[2] = this.protocolIdentifier[1]; - data[3] = this.protocolIdentifier[0]; - data[4] = this.length[1]; - data[5] = this.length[0]; - data[6] = this.unitIdentifier; - data[7] = this.functionCode; - data[8] = startingAddressReadLocal[1]; - data[9] = startingAddressReadLocal[0]; - data[10] = quantityReadLocal[1]; - data[11] = quantityReadLocal[0]; - data[12] = startingAddressWriteLocal[1]; - data[13] = startingAddressWriteLocal[0]; - data[14] = quantityWriteLocal[1]; - data[15] = quantityWriteLocal[0]; - data[16] = writeByteCountLocal; + Byte[] data = new byte[17 + 2 + values.Length * 2]; + data[0] = this.transactionIdentifier[1]; + data[1] = this.transactionIdentifier[0]; + data[2] = this.protocolIdentifier[1]; + data[3] = this.protocolIdentifier[0]; + data[4] = this.length[1]; + data[5] = this.length[0]; + data[6] = this.unitIdentifier; + data[7] = this.functionCode; + data[8] = startingAddressReadLocal[1]; + data[9] = startingAddressReadLocal[0]; + data[10] = quantityReadLocal[1]; + data[11] = quantityReadLocal[0]; + data[12] = startingAddressWriteLocal[1]; + data[13] = startingAddressWriteLocal[0]; + data[14] = quantityWriteLocal[1]; + data[15] = quantityWriteLocal[0]; + data[16] = writeByteCountLocal; for (int i = 0; i < values.Length; i++) { byte[] singleRegisterValue = BitConverter.GetBytes((int)values[i]); - data[17 + i*2] = singleRegisterValue[1]; - data[18 + i*2] = singleRegisterValue[0]; + data[17 + i * 2] = singleRegisterValue[1]; + data[18 + i * 2] = singleRegisterValue[0]; } crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); data[data.Length - 2] = crc[0]; @@ -2495,21 +2795,21 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea if (serialport != null) { dataReceived = false; - bytesToRead = 5 + 2*quantityRead; - // serialport.ReceivedBytesThreshold = bytesToRead; + bytesToRead = 5 + 2 * quantityRead; + // serialport.ReceivedBytesThreshold = bytesToRead; serialport.Write(data, 6, data.Length - 6); if (debug) { - byte [] debugData = new byte[data.Length - 6]; - Array.Copy(data, 6, debugData, 0, data.Length - 6); - if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); } - if (SendDataChanged != null) - { - sendData = new byte[data.Length - 6]; - Array.Copy(data, 6, sendData, 0, data.Length - 6); - SendDataChanged(this); - } data = new byte[2100]; readBuffer = new byte[256]; DateTime dateTimeSend = DateTime.Now; @@ -2518,25 +2818,62 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea SpinWait sw_delay = new SpinWait(); while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) { - while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) sw_delay.SpinOnce(); data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; } if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; + data = new byte[2100]; else countRetries = 0; } + else if (tcpClient.Client.Connected && modbusRtuOverEthernet) + { + dataReceived = false; + bytesToRead = 5 + 2 * quantityRead; + // serialport.ReceivedBytesThreshold = bytesToRead; + stream.Write(data, 6, data.Length - 6); + if (debug) + { + byte[] debugData = new byte[data.Length - 6]; + Array.Copy(data, 6, debugData, 0, data.Length - 6); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Serial-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(this); + } + Byte[] tempdata = new Byte[2100]; + data = new Byte[2100]; + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } + if (ReceiveDataChanged != null) + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Serial-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); + ReceiveDataChanged(this); + } + } else if (tcpClient.Client.Connected | udpFlag) { if (udpFlag) { UdpClient udpClient = new UdpClient(); IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length-2, endPoint); + udpClient.Send(data, data.Length - 2, endPoint); portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; udpClient.Client.ReceiveTimeout = 5000; endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); @@ -2544,49 +2881,49 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea } else { - stream.Write(data, 0, data.Length-2); + stream.Write(data, 0, data.Length - 2); if (debug) - { - byte [] debugData = new byte[data.Length-2]; - Array.Copy(data, 0, debugData, 0, data.Length-2); - if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now); - } - if (SendDataChanged != null) - { - sendData = new byte[data.Length-2]; - Array.Copy(data, 0, sendData, 0, data.Length-2); - SendDataChanged(this); - - } + { + byte[] debugData = new byte[data.Length - 2]; + Array.Copy(data, 0, debugData, 0, data.Length - 2); + if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: " + BitConverter.ToString(debugData), System.DateTime.Now); + } + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(this); + + } data = new Byte[2100]; - int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = stream.Read(data, 0, data.Length); if (ReceiveDataChanged != null) - { - receiveData = new byte[NumberOfBytes]; - Array.Copy(data, 0, receiveData, 0, NumberOfBytes); + { + receiveData = new byte[NumberOfBytes]; + Array.Copy(data, 0, receiveData, 0, NumberOfBytes); if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now); ReceiveDataChanged(this); - } + } } } if (data[7] == 0x97 & data[8] == 0x01) { - if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master"); } if (data[7] == 0x97 & data[8] == 0x02) { - if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"); } if (data[7] == 0x97 & data[8] == 0x03) { - if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); } if (data[7] == 0x97 & data[8] == 0x04) { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); throw new EasyModbus.Exceptions.ModbusException("error reading"); } response = new int[quantityRead]; @@ -2604,13 +2941,13 @@ public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRea } return (response); } - - /// - /// Close connection to Master Device. - /// - public void Disconnect() - { - if (debug) StoreLogData.Instance.Store("Disconnect", System.DateTime.Now); + + /// + /// Close connection to Master Device. + /// + public void Disconnect() + { + if (debug) StoreLogData.Instance.Store("Disconnect", System.DateTime.Now); if (serialport != null) { if (serialport.IsOpen & !this.receiveActive) @@ -2620,9 +2957,9 @@ public void Disconnect() return; } if (stream != null) - stream.Close(); + stream.Close(); if (tcpClient != null) - tcpClient.Close(); + tcpClient.Close(); connected = false; if (ConnectedChanged != null) ConnectedChanged(this); @@ -2632,30 +2969,30 @@ public void Disconnect() /// /// Destructor - Close connection to Master Device. /// - ~ ModbusClient() - { - if (debug) StoreLogData.Instance.Store("Destructor called - automatically disconnect", System.DateTime.Now); + ~ModbusClient() + { + if (debug) StoreLogData.Instance.Store("Destructor called - automatically disconnect", System.DateTime.Now); if (serialport != null) { if (serialport.IsOpen) serialport.Close(); return; } - if (tcpClient != null & !udpFlag) - { - if (stream !=null) - stream.Close(); - tcpClient.Close(); - } - } + if (tcpClient != null & !udpFlag) + { + if (stream != null) + stream.Close(); + tcpClient.Close(); + } + } /// /// Returns "TRUE" if Client is connected to Server and "FALSE" if not. In case of Modbus RTU returns if COM-Port is opened /// public bool Connected - { - get - { + { + get + { if (serialport != null) { return (serialport.IsOpen); @@ -2671,8 +3008,8 @@ public bool Connected } - } - } + } + } public bool Available(int timeout) { @@ -2697,31 +3034,31 @@ public bool Available(int timeout) /// Gets or Sets the IP-Address of the Server. /// public string IPAddress - { - get - { - return ipAddress; - } - set - { - ipAddress = value; - } - } + { + get + { + return ipAddress; + } + set + { + ipAddress = value; + } + } /// /// Gets or Sets the Port were the Modbus-TCP Server is reachable (Standard is 502). /// public int Port - { - get - { - return port; - } - set - { - port = value; - } - } + { + get + { + return port; + } + set + { + port = value; + } + } /// /// Gets or Sets the UDP-Flag to activate Modbus UDP. @@ -2843,7 +3180,7 @@ public string SerialPort if (serialport != null) serialport.Close(); this.serialport = new SerialPort(); - this.serialport.PortName = value; + this.serialport.PortName = value; serialport.BaudRate = baudRate; serialport.Parity = parity; serialport.StopBits = stopBits; From 69d263e901c357c8dd3e86f1956c427612bc136d Mon Sep 17 00:00:00 2001 From: tgreve85 Date: Wed, 15 Feb 2023 15:14:36 +0100 Subject: [PATCH 2/2] Update ModbusClient.cs forgot to improve stream.Read() in function ReadDiscreteInputs() and ReadCoils() as well --- EasyModbus/ModbusClient.cs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/EasyModbus/ModbusClient.cs b/EasyModbus/ModbusClient.cs index 99d4da8..d45a5d5 100644 --- a/EasyModbus/ModbusClient.cs +++ b/EasyModbus/ModbusClient.cs @@ -26,8 +26,6 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System.Net; using System.IO.Ports; using System.Reflection; -using System.Text; -using System.Collections.Generic; using System.Threading; namespace EasyModbus @@ -984,8 +982,17 @@ public bool[] ReadDiscreteInputs(int startingAddress, int quantity) SendDataChanged(this); } + Byte[] tempdata = new Byte[2100]; data = new Byte[2100]; - int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } if (ReceiveDataChanged != null) { receiveData = new byte[NumberOfBytes]; @@ -1213,8 +1220,17 @@ public bool[] ReadCoils(int startingAddress, int quantity) SendDataChanged(this); } + Byte[] tempdata = new Byte[2100]; data = new Byte[2100]; - int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = 0; + DateTime dateTimeSend = DateTime.Now; + while ((NumberOfBytes < bytesToRead) & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout)) + { + int bytes = stream.Read(tempdata, 0, tempdata.Length); + Array.Copy(tempdata, 0, data, NumberOfBytes, bytes); + NumberOfBytes += bytes; + dataReceived = true; + } if (ReceiveDataChanged != null) { receiveData = new byte[NumberOfBytes];