diff --git a/ConsoleAppStd/ConsoleAppStd.csproj b/ConsoleAppStd/ConsoleAppStd.csproj deleted file mode 100644 index 820f23d..0000000 --- a/ConsoleAppStd/ConsoleAppStd.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - net5.0 - - - - - - - diff --git a/ConsoleAppStd/Program.cs b/ConsoleAppStd/Program.cs deleted file mode 100644 index 423e386..0000000 --- a/ConsoleAppStd/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace ConsoleAppStd -{ - class Program - { - - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - - EasyModbus.ModbusClient modbusClient = new EasyModbus.ModbusClient(); - modbusClient.Connect("127.0.0.1", 502); - bool[] response = modbusClient.ReadDiscreteInputs(0, 2); - - modbusClient.Disconnect(); - Console.WriteLine("Value of Discrete Input #1: " + response[0].ToString()); - Console.WriteLine("Value of Discrete Input #2: " + response[1].ToString()); - Console.ReadKey(); - } - } -} diff --git a/EasyModbus/EasyModbus_Net40.csproj b/EasyModbus/EasyModbus_Net40.csproj index 41db91d..027a2ec 100644 --- a/EasyModbus/EasyModbus_Net40.csproj +++ b/EasyModbus/EasyModbus_Net40.csproj @@ -67,15 +67,11 @@ - - + - - - - \ No newline at end of file + diff --git a/EasyModbus/ModbusClient.cs b/EasyModbus/ModbusClient.cs index b9e0285..1938c3c 100644 --- a/EasyModbus/ModbusClient.cs +++ b/EasyModbus/ModbusClient.cs @@ -1,2876 +1,2473 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -using System; -using System.Net.Sockets; -using System.Net; -using System.IO.Ports; -using System.Reflection; -using System.Text; -using System.Collections.Generic; -using System.Threading; - -namespace EasyModbus -{ - /// - /// 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 uint transactionIdentifierInternal = 0; - 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 bool udpFlag = false; - private int portOut; - private int baudRate = 9600; - private int connectTimeout = 1000; - public byte[] receiveData; - public byte[] sendData; - private SerialPort serialport; - private Parity parity = Parity.Even; - private StopBits stopBits = StopBits.One; - private bool connected = false; - public int NumberOfRetries { get; set; } = 3; - private int countRetries = 0; - - public delegate void ReceiveDataChangedHandler(object sender); - public event ReceiveDataChangedHandler ReceiveDataChanged; - - public delegate void SendDataChangedHandler(object sender); - public event SendDataChangedHandler SendDataChanged; - - public delegate void ConnectedChangedHandler(object sender); - 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); -#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; - } - - /// - /// Constructor which determines the Serial-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 (!COMMERCIAL) - Console.WriteLine("EasyModbus Client Library Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); - Console.WriteLine("Copyright (c) Stefan Rossmann Engineering Solutions"); - Console.WriteLine(); -#endif - this.serialport = new SerialPort(); - serialport.PortName = serialPort; - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - } - - /// - /// Parameterless constructor - /// - public ModbusClient() - { - 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() - { - if (serialport != null) - { - if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("Open Serial port " + serialport.PortName,System.DateTime.Now); - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - serialport.Open(); - connected = true; - - - } - if (ConnectedChanged != null) - try - { - ConnectedChanged(this); - } - catch - { - - } - return; - } - if (!udpFlag) - { - if (debug) StoreLogData.Instance.Store("Open TCP-Socket, IP-Address: " + ipAddress + ", Port: " + port, System.DateTime.Now); - tcpClient = new TcpClient(); - var result = tcpClient.BeginConnect(ipAddress, port, null, null); - var success = result.AsyncWaitHandle.WaitOne(connectTimeout); - if (!success) - { - throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); - } - tcpClient.EndConnect(result); - - //tcpClient = new TcpClient(ipAddress, port); - stream = tcpClient.GetStream(); - stream.ReadTimeout = connectTimeout; - connected = true; - } - else - { - tcpClient = new TcpClient(); - connected = true; - } - if (ConnectedChanged != null) - try - { - ConnectedChanged(this); - } - catch - { - - } - } - - /// - /// 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); - tcpClient = new TcpClient(); - var result = tcpClient.BeginConnect(ipAddress, port, null, null); - var success = result.AsyncWaitHandle.WaitOne(connectTimeout); - if (!success) - { - throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); - } - tcpClient.EndConnect(result); - - //tcpClient = new TcpClient(ipAddress, port); - stream = tcpClient.GetStream(); - stream.ReadTimeout = connectTimeout; - connected = true; - } - else - { - tcpClient = new TcpClient(); - connected = true; - } - - if (ConnectedChanged != null) - ConnectedChanged(this); - } - - /// - /// Converts two ModbusRegisters to Float - Example: EasyModbus.ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(19,2)) - /// - /// Two Register values received from Modbus - /// Connected float value - public static float ConvertRegistersToFloat(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] floatBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToSingle(floatBytes, 0); - } - - /// - /// Converts two ModbusRegisters to Float, Registers can by swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// 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]}; - return ConvertRegistersToFloat(swappedRegisters); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer value - /// - /// Two Register values received from Modbus - /// Connected 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] doubleBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt32(doubleBytes, 0); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer Value - Registers can be swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connecteds 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers, RegisterOrder registerOrder) - { - int[] swappedRegisters = { registers[0], registers[1] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[1], registers[0] }; - return ConvertRegistersToInt(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - public static Int64 ConvertRegistersToLong(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt64(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected 64 Bit Integer value - public static Int64 ConvertRegistersToLong(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToLong(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - public static double ConvertRegistersToDouble(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToDouble(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected double prec. float value - public static double ConvertRegistersToDouble(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToDouble(swappedRegisters); - } - - /// - /// Converts float to two ModbusRegisters - Example: modbusClient.WriteMultipleRegisters(24, EasyModbus.ModbusClient.ConvertFloatToTwoRegisters((float)1.22)); - /// - /// Float value which has to be converted into two registers - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue) - { - byte[] floatBytes = BitConverter.GetBytes(floatValue); - byte[] highRegisterBytes = - { - floatBytes[2], - floatBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - floatBytes[0], - floatBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts float to two ModbusRegisters Registers - Registers can be swapped - /// - /// Float value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertFloatToRegisters(floatValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters - /// - /// Int value which has to be converted into two registers - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue) - { - byte[] doubleBytes = BitConverter.GetBytes(intValue); - byte[] highRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters Registers - Registers can be swapped - /// - /// Double value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertIntToRegisters(intValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - /// - /// long value which has to be converted into four registers - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue) - { - byte[] longBytes = BitConverter.GetBytes(longValue); - byte[] highRegisterBytes = - { - longBytes[6], - longBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - longBytes[4], - longBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - longBytes[2], - longBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - longBytes[0], - longBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - Registers can be swapped - /// - /// long value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertLongToRegisters(longValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec Value to four ModbusRegisters - /// - /// double value which has to be converted into four registers - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue) - { - byte[] doubleBytes = BitConverter.GetBytes(doubleValue); - byte[] highRegisterBytes = - { - doubleBytes[6], - doubleBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - doubleBytes[4], - doubleBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec. Value to four ModbusRegisters - Registers can be swapped - /// - /// double value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertDoubleToRegisters(doubleValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 16 - Bit Register values to String - /// - /// Register array received via Modbus - /// First Register containing the String to convert - /// 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++) - { - registerResult = BitConverter.GetBytes(registers[offset + i]); - result[i * 2] = registerResult[0]; - result[i * 2 + 1] = registerResult[1]; - } - return System.Text.Encoding.Default.GetString(result); - } - - /// - /// Converts a String to 16 - Bit Registers - /// - /// Register array received via Modbus - /// Converted String - public static int[] ConvertStringToRegisters(string stringToConvert) - { - byte[] array = System.Text.Encoding.ASCII.GetBytes(stringToConvert); - int[] returnarray = new int[stringToConvert.Length / 2 + stringToConvert.Length % 2]; - for (int i = 0; i < returnarray.Length; i++) - { - returnarray[i] = array[i * 2]; - if (i*2 +1< array.Length) - { - returnarray[i] = returnarray[i] | ((int)array[i * 2 + 1] << 8); - } - } - return returnarray; - } - - - /// - /// Calculates the CRC16 for Modbus-RTU - /// - /// Byte buffer to send - /// 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, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, - 0xC0, 0x80, 0x41, 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, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, - 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 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, 0x80, 0x41, 0x01, - 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 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, - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, - 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, - 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, - 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, - 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, - 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, - 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, - 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, - 0x40 - }; - UInt16 usDataLen = numberOfBytes; - byte uchCRCHi = 0xFF ; - byte uchCRCLo = 0xFF ; - int i = 0; - int uIndex ; - while (usDataLen>0) - { - usDataLen--; - if ((i + startByte) < data.Length) - { - uIndex = uchCRCLo ^ data[i + startByte]; - uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]); - uchCRCHi = auchCRCLo[uIndex]; - } - i++; - } - return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); - } - - private bool dataReceived = false; - private bool receiveActive = false; - private byte[] readBuffer = new byte[256]; - 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; - } - - 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); - - } - - - //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; - if (bytesToRead == 0) - { - sp.DiscardInBuffer(); - receiveActive = false; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - return; - } - readBuffer = new byte[256]; - 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){ - - } - - if (bytesToRead <= actualPositionToRead) - break; - - if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) - break; - } - 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); - bytesToRead = 0; - - - - - dataReceived = true; - receiveActive = false; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - if (ReceiveDataChanged != null) - { - - 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; - //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; - return true; - } - - - - /// - /// Read Discrete Inputs from Server device (FC2). - /// - /// First discrete input to read - /// 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 (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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); - 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] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - - if (serialport != null) - { - dataReceived = false; - if (quantity % 8 == 0) - bytesToRead = 5 + quantity / 8; - else - 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); - } - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x82 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadDiscreteInputs(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 ReadDiscreteInputs(startingAddress, 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); - } - - - /// - /// Read Coils from Server device (FC1). - /// - /// First coil to read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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[]{ - 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] - }; - - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - if (quantity % 8 == 0) - bytesToRead = 5 + quantity/8; - else - 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); - } - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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 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); - - } - 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-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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x81 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadCoils(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 ReadCoils(startingAddress, 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); - } - - - /// - /// Read Holding Registers from Master device (FC3). - /// - /// First holding register to be read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 5 + 2 * quantity; -// 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); - } - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - if (SendDataChanged != null) - { - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x83 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadHoldingRegisters(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 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); - } - - - - /// - /// Read Input Registers from Master device (FC4). - /// - /// First input register to be read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 5 + 2 * quantity; - - - // 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); - } - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x84 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadInputRegisters(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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). - /// - /// Coil 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - byte[] coilValue = new byte[2]; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x05; - this.startingAddress = BitConverter.GetBytes(startingAddress); - if (value == true) - { - coilValue = BitConverter.GetBytes((int)0xFF00); - } - else - { - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 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); - } - 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)) - 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]; - else - countRetries = 0; - - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x85 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteSingleCoil(startingAddress, value); - } - } - else if (!dataReceived) - { - 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++; - WriteSingleCoil(startingAddress, value); - } - } - } - } - - - /// - /// Write single Register to Master device (FC6). - /// - /// Register to be written - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 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); - } - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x86 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteSingleRegister(startingAddress, value); - } - } - else if (!dataReceived) - { - 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++; - WriteSingleRegister(startingAddress, value); - } - } - } - } - - /// - /// Write multiple coils to Master device (FC15). - /// - /// First coil to be written - /// Coil Values to be written - 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); - transactionIdentifierInternal++; - 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); - 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); - 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.functionCode = 0x0F; - this.startingAddress = BitConverter.GetBytes(startingAddress); - - - - 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[10] = quantityOfOutputs[1]; - data[11] = quantityOfOutputs[0]; - data[12] = byteCount; - for (int i = 0; i < values.Length; i++) - { - if ((i % 8) == 0) - singleCoilValue = 0; - byte CoilValue; - if (values[i] == true) - CoilValue = 1; - else - CoilValue = 0; - - - singleCoilValue = (byte)((int)CoilValue<<(i%8) | (int)singleCoilValue); - - data[13 + (i / 8)] = singleCoilValue; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 8; - // 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); - } - 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; - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x8F & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteMultipleCoils(startingAddress, values); - } - } - else if (!dataReceived) - { - 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++; - WriteMultipleCoils(startingAddress, values); - } - } - } - } - - /// - /// Write multiple registers to Master device (FC16). - /// - /// First register to be written - /// register Values to be written - 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); - 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); - 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); - 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.functionCode = 0x10; - this.startingAddress = BitConverter.GetBytes(startingAddress); - - Byte[] data = new byte[13+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] = this.startingAddress[1]; - data[9] = this.startingAddress[0]; - data[10] = quantityOfOutputs[1]; - data[11] = quantityOfOutputs[0]; - data[12] = byteCount; - 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]; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 8; -// 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); - } - 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; - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x90 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteMultipleRegisters(startingAddress, values); - } - } - else if (!dataReceived) - { - 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++; - WriteMultipleRegisters(startingAddress, values); - } - } - } - } - - /// - /// Read/Write Multiple Registers (FC23). - /// - /// First input register to read - /// Number of input registers to read - /// First input register to write - /// Values to write - /// Int Array which contains the Holding registers - public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRead, int startingAddressWrite, int[] values) - { - - 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); - transactionIdentifierInternal++; - 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); - 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); - 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"); - } - int[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)11 + values.Length * 2); - this.functionCode = 0x17; - startingAddressReadLocal = BitConverter.GetBytes(startingAddressRead); - quantityReadLocal = BitConverter.GetBytes(quantityRead); - 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; - - 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]; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - 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); - } - 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; - 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)) - 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]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x97 & data[8] == 0x04) - { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); - throw new EasyModbus.Exceptions.ModbusException("error reading"); - } - response = new int[quantityRead]; - for (int i = 0; i < quantityRead; 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); - } - - /// - /// 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) - serialport.Close(); - if (ConnectedChanged != null) - ConnectedChanged(this); - return; - } - if (stream != null) - stream.Close(); - if (tcpClient != null) - tcpClient.Close(); - connected = false; - if (ConnectedChanged != null) - ConnectedChanged(this); - - } - - /// - /// Destructor - Close connection to Master Device. - /// - ~ 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(); - } - } - - /// - /// 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 - { - if (serialport != null) - { - return (serialport.IsOpen); - } - - if (udpFlag & tcpClient != null) - return true; - if (tcpClient == null) - return false; - else - { - return connected; - - } - - } - } - - public bool Available(int timeout) - { - // Ping's the local machine. - System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping(); - IPAddress address = System.Net.IPAddress.Parse(ipAddress); - - // Create a buffer of 32 bytes of data to be transmitted. - string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - byte[] buffer = System.Text.Encoding.ASCII.GetBytes(data); - - // Wait 10 seconds for a reply. - System.Net.NetworkInformation.PingReply reply = pingSender.Send(address, timeout, buffer); - - if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) - return true; - else - return false; - } - - /// - /// Gets or Sets the IP-Address of the Server. - /// - public string IPAddress - { - 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; - } - } - - /// - /// Gets or Sets the UDP-Flag to activate Modbus UDP. - /// - public bool UDPFlag - { - get - { - return udpFlag; - } - set - { - udpFlag = value; - } - } - - /// - /// Gets or Sets the Unit identifier in case of serial connection (Default = 0) - /// - public byte UnitIdentifier - { - get - { - return unitIdentifier; - } - set - { - unitIdentifier = value; - } - } - - - /// - /// Gets or Sets the Baudrate for serial connection (Default = 9600) - /// - public int Baudrate - { - get - { - return baudRate; - } - set - { - baudRate = value; - } - } - - /// - /// Gets or Sets the of Parity in case of serial connection - /// - public Parity Parity - { - get - { - if (serialport != null) - return parity; - else - return Parity.Even; - } - set - { - if (serialport != null) - parity = value; - } - } - - - /// - /// Gets or Sets the number of stopbits in case of serial connection - /// - public StopBits StopBits - { - get - { - if (serialport != null) - return stopBits; - else - return StopBits.One; - } - set - { - if (serialport != null) - stopBits = value; - } - } - - /// - /// Gets or Sets the connection Timeout in case of ModbusTCP connection - /// - public int ConnectionTimeout - { - get - { - return connectTimeout; - } - set - { - connectTimeout = value; - } - } - - /// - /// Gets or Sets the serial Port - /// - public string SerialPort - { - get - { - - return serialport.PortName; - } - set - { - if (value == null) - { - serialport = null; - return; - } - if (serialport != null) - serialport.Close(); - this.serialport = new SerialPort(); - this.serialport.PortName = value; - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - } - } - - /// - /// Gets or Sets the Filename for the LogFile - /// - public string LogFileFilename - { - get - { - return StoreLogData.Instance.Filename; - } - set - { - StoreLogData.Instance.Filename = value; - if (StoreLogData.Instance.Filename != null) - debug = true; - else - debug = false; - } - } - - } -} +/* +Copyright (c) 2018-2020 Rossmann-Engineering +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software +and associated documentation files (the "Software"), +to deal in the Software without restriction, +including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission +notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*************************************************************************************** +李锦上lijinshang@126.com修改版:从机 +*************************************************************************************** +2023-6-29:删除numberOfClientsChanged、NumberOfConnectedClientsChanged事件 +2020-8-13:解决ModbusUDP无法二次启动问题 关闭未结束线程 listenerThread +2020-8-2:增加ReceiveDataChanged(Byte[] data) SendDataChanged(Byte[] data)回调 +2020-8-2:解决从机模式接收数据debug信息全部为00的问题 +2020-8-1:增加ModbusType 规范化编程 +2020-8-1:解决UDP从机模式关闭后不能打开的问题 +2020-7-30:解决ModbusRTU从机模式下数据接收错误的问题 详见:SerialHandler -李锦上 +*************************************************************************************** +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Net.Sockets; +using System.Net; +using System.Threading; +using System.Net.NetworkInformation; +using System.IO.Ports; + +namespace EasyModbus +{ + #region class ModbusProtocol + /// + /// Modbus Protocol informations. + /// + public class ModbusProtocol + { + //public enum ProtocolType { ModbusTCP = 0, ModbusUDP = 1, ModbusRTU = 2 }; + public DateTime timeStamp; + public bool request; + public bool response; + public UInt16 transactionIdentifier; + public UInt16 protocolIdentifier; + public UInt16 length; + public byte unitIdentifier; + public byte functionCode; + public UInt16 startingAdress; + public UInt16 startingAddressRead; + public UInt16 startingAddressWrite; + public UInt16 quantity; + public UInt16 quantityRead; + public UInt16 quantityWrite; + public byte byteCount; + public byte exceptionCode; + public byte errorCode; + public UInt16[] receiveCoilValues; + public UInt16[] receiveRegisterValues; + public Int16[] sendRegisterValues; + public bool[] sendCoilValues; + public UInt16 crc; + } + #endregion + + #region structs + struct NetworkConnectionParameter + { + public NetworkStream stream; //For TCP-Connection only + public Byte[] bytes; + public int portIn; //For UDP-Connection only + public IPAddress ipAddressIn; //For UDP-Connection only + } + #endregion + + #region TCPHandler class + internal class TCPHandler + { + public delegate void DataChanged(object networkConnectionParameter); + public event DataChanged dataChanged; + + //public delegate void NumberOfClientsChanged(); + //public event NumberOfClientsChanged numberOfClientsChanged; + + TcpListener server = null; + + + private List tcpClientLastRequestList = new List(); + + public int NumberOfConnectedClients { get; set; } + + public string ipAddress = null; + + /// When making a server TCP listen socket, will listen to this IP address. + public IPAddress LocalIPAddress + { + get { return localIPAddress; } + } + private IPAddress localIPAddress = IPAddress.Any; + + /// + /// Listen to all network interfaces. + /// + /// TCP port to listen + public TCPHandler(int port) + { + server = new TcpListener(LocalIPAddress, port); + server.Start(); + server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); + } + + /// + /// Listen to a specific network interface. + /// + /// IP address of network interface to listen + /// TCP port to listen + public TCPHandler(IPAddress localIPAddress, int port) + { + this.localIPAddress = localIPAddress; + server = new TcpListener(LocalIPAddress, port); + server.Start(); + server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); + } + + + private void AcceptTcpClientCallback(IAsyncResult asyncResult) + { + TcpClient tcpClient = new TcpClient(); + try + { + tcpClient = server.EndAcceptTcpClient(asyncResult); + tcpClient.ReceiveTimeout = 1000; + if (ipAddress != null) + { + string ipEndpoint = tcpClient.Client.RemoteEndPoint.ToString(); + ipEndpoint = ipEndpoint.Split(':')[0]; + if (ipEndpoint != ipAddress) + { + tcpClient.Client.Disconnect(false); + return; + } + } + } + catch{ } + try + { + server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); + Client client = new Client(tcpClient); + NetworkStream networkStream = client.NetworkStream; + networkStream.ReadTimeout = 1000; + networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); + } + catch{ } + } + + private int GetAndCleanNumberOfConnectedClients(Client client) + { + lock (this) + { + bool objetExists = false; + foreach (Client clientLoop in tcpClientLastRequestList) + { + if (client.Equals(clientLoop)) + objetExists = true; + } + try + { + tcpClientLastRequestList.RemoveAll(delegate (Client c) + { + return ((TimeSpan.FromTicks(DateTime.Now.Ticks - c.Ticks).TotalMilliseconds) > 4000); + }); + } + catch{ } + if (!objetExists) + tcpClientLastRequestList.Add(client); + + + return tcpClientLastRequestList.Count; + } + } + + private void ReadCallback(IAsyncResult asyncResult) + { + NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); + Client client = asyncResult.AsyncState as Client; + client.Ticks = DateTime.Now.Ticks; + NumberOfConnectedClients = GetAndCleanNumberOfConnectedClients(client); + //if (numberOfClientsChanged != null) + // numberOfClientsChanged(); + if (client != null) + { + int read; + NetworkStream networkStream = null; + try + { + networkStream = client.NetworkStream; + + read = networkStream.EndRead(asyncResult); + } + catch + { + return; + } + + + if (read == 0) + { + //OnClientDisconnected(client.TcpClient); + //connectedClients.Remove(client); + return; + } + byte[] data = new byte[read]; + Buffer.BlockCopy(client.Buffer, 0, data, 0, read); + networkConnectionParameter.bytes = data; + networkConnectionParameter.stream = networkStream; + if (dataChanged != null) + dataChanged(networkConnectionParameter); + try + { + networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); + } + catch + { + } + } + } + + public void Disconnect() + { + try + { + foreach (Client clientLoop in tcpClientLastRequestList) + { + clientLoop.NetworkStream.Close(00); + } + } + catch (Exception) { } + server.Stop(); + + } + + + internal class Client + { + private readonly TcpClient tcpClient; + private readonly byte[] buffer; + public long Ticks { get; set; } + + public Client(TcpClient tcpClient) + { + this.tcpClient = tcpClient; + int bufferSize = tcpClient.ReceiveBufferSize; + buffer = new byte[bufferSize]; + } + + public TcpClient TcpClient + { + get { return tcpClient; } + } + + public byte[] Buffer + { + get { return buffer; } + } + + public NetworkStream NetworkStream + { + get + { + + return tcpClient.GetStream(); + + } + } + } + } + #endregion + + /// + /// Modbus TCP Server. + /// + public class ModbusClient + { + public enum ModbusType { ModbusTCP, ModbusUDP, ModbusRTU }; + private ModbusType modbusType; + private bool debug = false; + Int32 port = 502; + //ModbusProtocol receiveData; + ModbusProtocol sendData = new ModbusProtocol(); + Byte[] bytes = new Byte[2100]; + //public Int16[] _holdingRegisters = new Int16[65535]; + public HoldingRegisters holdingRegisters; + public InputRegisters inputRegisters; + public Coils coils; + public DiscreteInputs discreteInputs; + private int numberOfConnections = 0; + private int baudrate = 9600; + private System.IO.Ports.Parity parity = Parity.Even; + private System.IO.Ports.StopBits stopBits = StopBits.One; + private string serialPort = "COM1"; + private SerialPort serialport; + private byte unitIdentifier = 1; + private int portIn; + private IPAddress ipAddressIn; + private UdpClient udpClient; + private IPEndPoint iPEndPoint; + private TCPHandler tcpHandler; + private int connectTimeout = 1000; + Thread listenerThread; + private ModbusProtocol[] modbusLogData = new ModbusProtocol[100]; + public bool FunctionCode1Disabled { get; set; } + public bool FunctionCode2Disabled { get; set; } + public bool FunctionCode3Disabled { get; set; } + public bool FunctionCode4Disabled { get; set; } + public bool FunctionCode5Disabled { get; set; } + public bool FunctionCode6Disabled { get; set; } + public bool FunctionCode15Disabled { get; set; } + public bool FunctionCode16Disabled { get; set; } + public bool FunctionCode23Disabled { get; set; } + public bool PortChanged { get; set; } + object lockCoils = new object(); + object lockHoldingRegisters = new object(); + private volatile bool shouldStop; + + private IPAddress localIPAddress = IPAddress.Any; + + public delegate void ReceiveDataChangedHandler(Byte[] data); + public event ReceiveDataChangedHandler ReceiveDataChanged; + + public delegate void SendDataChangedHandler(Byte[] data); + public event SendDataChangedHandler SendDataChanged; + + /// + /// When creating a TCP or UDP socket, the local IP address to attach to. + /// + public IPAddress LocalIPAddress + { + get { return localIPAddress; } + set { if (listenerThread == null) localIPAddress = value; } + } + + + public ModbusClient() + { + holdingRegisters = new HoldingRegisters(this); + inputRegisters = new InputRegisters(this); + coils = new Coils(this); + discreteInputs = new DiscreteInputs(this); + + } + + #region events + public delegate void CoilsChangedHandler(int coil, int numberOfCoils); + public event CoilsChangedHandler CoilsChanged; + + public delegate void HoldingRegistersChangedHandler(int register, int numberOfRegisters); + public event HoldingRegistersChangedHandler HoldingRegistersChanged; + + //public delegate void NumberOfConnectedClientsChangedHandler(); + //public event NumberOfConnectedClientsChangedHandler NumberOfConnectedClientsChanged; + + public delegate void LogDataChangedHandler(); + public event LogDataChangedHandler LogDataChanged; + #endregion + + public void Listen() + { + + listenerThread = new Thread(ListenerThread); + listenerThread.Start(); + } + + public void StopListening() + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + + if (serialport != null) + { + if (serialport.IsOpen) + serialport.Close(); + //shouldStop = true; + } + break; + case ModbusType.ModbusTCP: + try + { + if (tcpHandler != null) + tcpHandler.Disconnect(); + listenerThread.Abort(); + + } + catch (Exception) { } + break; + case ModbusType.ModbusUDP: + try + { + if (udpClient != null) + udpClient.Close(); + listenerThread.Abort(); + + } + catch (Exception) { } + break; + } + shouldStop = true; + listenerThread.Join(); + } + + private void ListenerThread() + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (serialport == null) + { + if (debug) StoreLogData.Instance.Store("EasyModbus RTU-Server listing for incomming data at Serial Port " + serialPort, System.DateTime.Now); + serialport = new SerialPort(); + serialport.PortName = serialPort; + serialport.BaudRate = this.baudrate; + serialport.Parity = this.parity; + serialport.StopBits = stopBits; + serialport.WriteTimeout = connectTimeout; + serialport.ReadTimeout = connectTimeout; + serialport.ReceivedBytesThreshold = 1; + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + serialport.Open(); + } + break; + case ModbusType.ModbusTCP: + tcpHandler = new TCPHandler(LocalIPAddress, port); + if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); + tcpHandler.dataChanged += new TCPHandler.DataChanged(ProcessReceivedData); + //tcpHandler.numberOfClientsChanged += new TCPHandler.NumberOfClientsChanged(numberOfClientsChanged); + break; + case ModbusType.ModbusUDP: + //while (!shouldStop) + { + IPEndPoint localEndoint = new IPEndPoint(LocalIPAddress, port); + udpClient = new UdpClient(localEndoint); + if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); + udpClient.Client.ReceiveTimeout = connectTimeout; + iPEndPoint = new IPEndPoint(IPAddress.Any, port); + PortChanged = false; + + try + { + bytes = udpClient.Receive(ref iPEndPoint); + portIn = iPEndPoint.Port; + NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); + networkConnectionParameter.bytes = bytes; + ipAddressIn = iPEndPoint.Address; + networkConnectionParameter.portIn = portIn; + networkConnectionParameter.ipAddressIn = ipAddressIn; + ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); + Thread processDataThread = new Thread(pts); + processDataThread.Start(networkConnectionParameter); + } + catch (Exception) + { + } + } + break; + } + } + + #region SerialHandler + private byte[] readBuffer = new byte[2094]; + //private DateTime lastReceive; + //private int nextSign = 0; + private void DataReceivedHandler(object sender, + SerialDataReceivedEventArgs e) + { + + const long ticksWait = TimeSpan.TicksPerMillisecond * 2000;//((40*10000000) / this.baudRate); + + + SerialPort sp = (SerialPort)sender; + + readBuffer = new byte[256]; + int numbytes = 0; + int actualPositionToRead = 0; + DateTime dateTimeLastRead = DateTime.Now; + //接收数据 + do + { + try + { + dateTimeLastRead = DateTime.Now; + while ((sp.BytesToRead) == 0) + { + System.Threading.Thread.Sleep(1); + 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, numbytes); + + actualPositionToRead = actualPositionToRead + rxbytearray.Length; + + } + catch (Exception) + { + + } + + //if (bytesToRead <= actualPositionToRead) + // break; + + if (ModbusPoll.DetectValidModbusFrame(readBuffer, actualPositionToRead)) + break; + } + while ((DateTime.Now.Ticks - dateTimeLastRead.Ticks) < ticksWait); + + Byte[] receiveBuffer = new byte[actualPositionToRead]; + Array.Copy(readBuffer, 0, receiveBuffer, 0, actualPositionToRead);//receiveBuffer完整帧数据 + + //帧处理 + NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); + networkConnectionParameter.bytes = receiveBuffer; + ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); + Thread processDataThread = new Thread(pts); + processDataThread.Start(networkConnectionParameter); + } + #endregion + + //#region Method numberOfClientsChanged + //private void numberOfClientsChanged() + //{ + // numberOfConnections = tcpHandler.NumberOfConnectedClients; + // if (NumberOfConnectedClientsChanged != null) + // NumberOfConnectedClientsChanged(); + //} + //#endregion + + object lockProcessReceivedData = new object(); + #region Method ProcessReceivedData + private void ProcessReceivedData(object networkConnectionParameter) + { + lock (lockProcessReceivedData) + { + Byte[] bytes = new byte[((NetworkConnectionParameter)networkConnectionParameter).bytes.Length]; + NetworkStream stream = ((NetworkConnectionParameter)networkConnectionParameter).stream; + int portIn = ((NetworkConnectionParameter)networkConnectionParameter).portIn; + IPAddress ipAddressIn = ((NetworkConnectionParameter)networkConnectionParameter).ipAddressIn; + + + Array.Copy(((NetworkConnectionParameter)networkConnectionParameter).bytes, 0, bytes, 0, ((NetworkConnectionParameter)networkConnectionParameter).bytes.Length); + if (debug) StoreLogData.Instance.Store("Received Data: " + BitConverter.ToString(bytes), System.DateTime.Now); + if (ReceiveDataChanged != null) + { + ReceiveDataChanged(bytes); + } + + ModbusProtocol receiveDataThread = new ModbusProtocol(); + ModbusProtocol sendDataThread = new ModbusProtocol(); + + try + { + UInt16[] wordData = new UInt16[1]; + byte[] byteData = new byte[2]; + receiveDataThread.timeStamp = DateTime.Now; + receiveDataThread.request = true; + if (modbusType == ModbusType.ModbusTCP || modbusType == ModbusType.ModbusUDP) + { + //Lese Transaction identifier + byteData[1] = bytes[0]; + byteData[0] = bytes[1]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.transactionIdentifier = wordData[0]; + + //Lese Protocol identifier + byteData[1] = bytes[2]; + byteData[0] = bytes[3]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.protocolIdentifier = wordData[0]; + + //Lese length + byteData[1] = bytes[4]; + byteData[0] = bytes[5]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.length = wordData[0]; + } + + //Lese unit identifier + receiveDataThread.unitIdentifier = bytes[6 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + //Check UnitIdentifier + if ((receiveDataThread.unitIdentifier != this.unitIdentifier) & (receiveDataThread.unitIdentifier != 0)) + return; + + // Lese function code + receiveDataThread.functionCode = bytes[7 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + // Lese starting address + byteData[1] = bytes[8 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[9 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.startingAdress = wordData[0]; + + if (receiveDataThread.functionCode <= 4) + { + // Lese quantity + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.quantity = wordData[0]; + } + if (receiveDataThread.functionCode == 5) + { + receiveDataThread.receiveCoilValues = new ushort[1]; + // Lese Value + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveCoilValues, 0, 2); + } + if (receiveDataThread.functionCode == 6) + { + receiveDataThread.receiveRegisterValues = new ushort[1]; + // Lese Value + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, 0, 2); + } + if (receiveDataThread.functionCode == 15) + { + // Lese quantity + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.quantity = wordData[0]; + + receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + if ((receiveDataThread.byteCount % 2) != 0) + receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2 + 1]; + else + receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2]; + // Lese Value + Buffer.BlockCopy(bytes, 13 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU), receiveDataThread.receiveCoilValues, 0, receiveDataThread.byteCount); + } + if (receiveDataThread.functionCode == 16) + { + // Lese quantity + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.quantity = wordData[0]; + + receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantity]; + for (int i = 0; i < receiveDataThread.quantity; i++) + { + // Lese Value + byteData[1] = bytes[13 + i * 2 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[14 + i * 2 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); + } + + } + if (receiveDataThread.functionCode == 23) + { + // Lese starting Address Read + byteData[1] = bytes[8 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[9 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.startingAddressRead = wordData[0]; + // Lese quantity Read + byteData[1] = bytes[10 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[11 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.quantityRead = wordData[0]; + // Lese starting Address Write + byteData[1] = bytes[12 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[13 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.startingAddressWrite = wordData[0]; + // Lese quantity Write + byteData[1] = bytes[14 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[15 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, wordData, 0, 2); + receiveDataThread.quantityWrite = wordData[0]; + + receiveDataThread.byteCount = bytes[16 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantityWrite]; + for (int i = 0; i < receiveDataThread.quantityWrite; i++) + { + // Lese Value + byteData[1] = bytes[17 + i * 2 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + byteData[0] = bytes[18 + i * 2 - 6 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); + } + } + } + catch{ } + this.CreateAnswer(receiveDataThread, sendDataThread, stream, portIn, ipAddressIn); + //this.sendAnswer(); + this.CreateLogData(receiveDataThread, sendDataThread); + + if (LogDataChanged != null) + LogDataChanged(); + } + } + #endregion + + #region Method CreateAnswer + private void CreateAnswer(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + + switch (receiveData.functionCode) + { + // Read Coils + case 1: + if (!FunctionCode1Disabled) + this.ReadCoils(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + break; + // Read Input Registers + case 2: + if (!FunctionCode2Disabled) + this.ReadDiscreteInputs(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Read Holding Registers + case 3: + if (!FunctionCode3Disabled) + this.ReadHoldingRegisters(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Read Input Registers + case 4: + if (!FunctionCode4Disabled) + this.ReadInputRegisters(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Write single coil + case 5: + if (!FunctionCode5Disabled) + this.WriteSingleCoil(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Write single register + case 6: + if (!FunctionCode6Disabled) + this.WriteSingleRegister(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Write Multiple coils + case 15: + if (!FunctionCode15Disabled) + this.WriteMultipleCoils(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Write Multiple registers + case 16: + if (!FunctionCode16Disabled) + this.WriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Error: Function Code not supported + case 23: + if (!FunctionCode23Disabled) + this.ReadWriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); + else + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + } + + break; + // Error: Function Code not supported + default: + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 1; + sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); + break; + } + sendData.timeStamp = DateTime.Now; + } + #endregion + + private void ReadCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + if ((receiveData.quantity % 8) == 0) + sendData.byteCount = (byte)(receiveData.quantity / 8); + else + sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); + + sendData.sendCoilValues = new bool[receiveData.quantity]; + lock (lockCoils) + Array.Copy(coils.localArray, receiveData.startingAdress, sendData.sendCoilValues, 0, receiveData.quantity); + } + if (true) + { + Byte[] data; + + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + //ByteCount + data[8] = sendData.byteCount; + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendCoilValues = null; + } + + if (sendData.sendCoilValues != null) + for (int i = 0; i < (sendData.byteCount); i++) + { + byteData = new byte[2]; + for (int j = 0; j < 8; j++) + { + + byte boolValue; + if (sendData.sendCoilValues[i * 8 + j] == true) + boolValue = 1; + else + boolValue = 0; + byteData[1] = (byte)((byteData[1]) | (boolValue << j)); + if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) + break; + } + data[9 + i] = byteData[1]; + } + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + } + } + + private void ReadDiscreteInputs(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + if ((receiveData.quantity % 8) == 0) + sendData.byteCount = (byte)(receiveData.quantity / 8); + else + sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); + + sendData.sendCoilValues = new bool[receiveData.quantity]; + Array.Copy(discreteInputs.localArray, receiveData.startingAdress, sendData.sendCoilValues, 0, receiveData.quantity); + } + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + //ByteCount + data[8] = sendData.byteCount; + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendCoilValues = null; + } + + if (sendData.sendCoilValues != null) + for (int i = 0; i < (sendData.byteCount); i++) + { + byteData = new byte[2]; + for (int j = 0; j < 8; j++) + { + + byte boolValue; + if (sendData.sendCoilValues[i * 8 + j] == true) + boolValue = 1; + else + boolValue = 0; + byteData[1] = (byte)((byteData[1]) | (boolValue << j)); + if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) + break; + } + data[9 + i] = byteData[1]; + } + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + } + } + + private void ReadHoldingRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + sendData.byteCount = (byte)(2 * receiveData.quantity); + sendData.sendRegisterValues = new Int16[receiveData.quantity]; + lock (lockHoldingRegisters) + Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAdress * 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = (ushort)(0x03 + sendData.byteCount); + + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + //ByteCount + data[8] = sendData.byteCount; + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + + + if (sendData.sendRegisterValues != null) + for (int i = 0; i < (sendData.byteCount / 2); i++) + { + byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); + data[9 + i * 2] = byteData[1]; + data[10 + i * 2] = byteData[0]; + } + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + } + } + + private void ReadInputRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + sendData.byteCount = (byte)(2 * receiveData.quantity); + sendData.sendRegisterValues = new Int16[receiveData.quantity]; + Buffer.BlockCopy(inputRegisters.localArray, receiveData.startingAdress * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = (ushort)(0x03 + sendData.byteCount); + + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + //ByteCount + data[8] = sendData.byteCount; + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + + + if (sendData.sendRegisterValues != null) + for (int i = 0; i < (sendData.byteCount / 2); i++) + { + byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); + data[9 + i * 2] = byteData[1]; + data[10 + i * 2] = byteData[0]; + } + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + } + } + + private void WriteSingleCoil(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + sendData.startingAdress = receiveData.startingAdress; + sendData.receiveCoilValues = receiveData.receiveCoilValues; + if ((receiveData.receiveCoilValues[0] != 0x0000) & (receiveData.receiveCoilValues[0] != 0xFF00)) //Invalid Value + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + if (receiveData.receiveCoilValues[0] == 0xFF00) + { + lock (lockCoils) + coils[receiveData.startingAdress] = true; + } + if (receiveData.receiveCoilValues[0] == 0x0000) + { + lock (lockCoils) + coils[receiveData.startingAdress] = false; + } + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = 0x06; + + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[12 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + else + { + byteData = BitConverter.GetBytes((int)receiveData.startingAdress); + data[8] = byteData[1]; + data[9] = byteData[0]; + byteData = BitConverter.GetBytes((int)receiveData.receiveCoilValues[0]); + data[10] = byteData[1]; + data[11] = byteData[0]; + } + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + if (CoilsChanged != null) + CoilsChanged(receiveData.startingAdress, 1); + } + } + + private void WriteSingleRegister(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + sendData.startingAdress = receiveData.startingAdress; + sendData.receiveRegisterValues = receiveData.receiveRegisterValues; + + if ((receiveData.receiveRegisterValues[0] < 0x0000) | (receiveData.receiveRegisterValues[0] > 0xFFFF)) //Invalid Value + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if (((receiveData.startingAdress + 1) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + lock (lockHoldingRegisters) + holdingRegisters[receiveData.startingAdress] = unchecked((short)receiveData.receiveRegisterValues[0]); + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = 0x06; + + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[12 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + else + { + byteData = BitConverter.GetBytes((int)receiveData.startingAdress); + data[8] = byteData[1]; + data[9] = byteData[0]; + byteData = BitConverter.GetBytes((int)receiveData.receiveRegisterValues[0]); + data[10] = byteData[1]; + data[11] = byteData[0]; + } + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + if (HoldingRegistersChanged != null) + HoldingRegistersChanged(receiveData.startingAdress, 1); + } + } + + private void WriteMultipleCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + sendData.startingAdress = receiveData.startingAdress; + sendData.quantity = receiveData.quantity; + + if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if ((((int)receiveData.startingAdress + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + lock (lockCoils) + for (int i = 0; i < receiveData.quantity; i++) + { + int shift = i % 16; + /* if ((i == receiveData.quantity - 1) & (receiveData.quantity % 2 != 0)) + { + if (shift < 8) + shift = shift + 8; + else + shift = shift - 8; + }*/ + int mask = 0x1; + mask = mask << (shift); + if ((receiveData.receiveCoilValues[i / 16] & (ushort)mask) == 0) + + coils[receiveData.startingAdress + i] = false; + else + + coils[receiveData.startingAdress + i] = true; + + } + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = 0x06; + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[12 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + else + { + byteData = BitConverter.GetBytes((int)receiveData.startingAdress); + data[8] = byteData[1]; + data[9] = byteData[0]; + byteData = BitConverter.GetBytes((int)receiveData.quantity); + data[10] = byteData[1]; + data[11] = byteData[0]; + } + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + if (CoilsChanged != null) + CoilsChanged(receiveData.startingAdress, receiveData.quantity); + } + } + + private void WriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + sendData.startingAdress = receiveData.startingAdress; + sendData.quantity = receiveData.quantity; + + if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if ((((int)receiveData.startingAdress + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + lock (lockHoldingRegisters) + for (int i = 0; i < receiveData.quantity; i++) + { + holdingRegisters[receiveData.startingAdress + i] = unchecked((short)receiveData.receiveRegisterValues[i]); + } + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = 0x06; + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[12 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + else + { + byteData = BitConverter.GetBytes((int)receiveData.startingAdress); + data[8] = byteData[1]; + data[9] = byteData[0]; + byteData = BitConverter.GetBytes((int)receiveData.quantity); + data[10] = byteData[1]; + data[11] = byteData[0]; + } + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + if (HoldingRegistersChanged != null) + HoldingRegistersChanged(receiveData.startingAdress, receiveData.quantity); + } + } + + private void ReadWriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = this.unitIdentifier; + sendData.functionCode = receiveData.functionCode; + + + if ((receiveData.quantityRead < 0x0001) | (receiveData.quantityRead > 0x007D) | (receiveData.quantityWrite < 0x0001) | (receiveData.quantityWrite > 0x0079) | (receiveData.byteCount != (receiveData.quantityWrite * 2))) //Invalid Quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 3; + } + if ((((int)receiveData.startingAddressRead + 1 + (int)receiveData.quantityRead) > 65535) | (((int)receiveData.startingAddressWrite + 1 + (int)receiveData.quantityWrite) > 65535) | (receiveData.quantityWrite < 0) | (receiveData.quantityRead < 0)) //Invalid Starting adress or Starting address + quantity + { + sendData.errorCode = (byte)(receiveData.functionCode + 0x80); + sendData.exceptionCode = 2; + } + if (sendData.exceptionCode == 0) + { + sendData.sendRegisterValues = new Int16[receiveData.quantityRead]; + lock (lockHoldingRegisters) + Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAddressRead * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantityRead * 2); + + lock (holdingRegisters) + for (int i = 0; i < receiveData.quantityWrite; i++) + { + holdingRegisters[receiveData.startingAddressWrite + i + 1] = unchecked((short)receiveData.receiveRegisterValues[i]); + } + sendData.byteCount = (byte)(2 * receiveData.quantityRead); + } + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = Convert.ToUInt16(3 + 2 * receiveData.quantityRead); + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + + Byte[] byteData = new byte[2]; + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + //Function Code + data[7] = sendData.functionCode; + + //ByteCount + data[8] = sendData.byteCount; + + + if (sendData.exceptionCode > 0) + { + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + sendData.sendRegisterValues = null; + } + else + { + if (sendData.sendRegisterValues != null) + for (int i = 0; i < (sendData.byteCount / 2); i++) + { + byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); + data[9 + i * 2] = byteData[1]; + data[10 + i * 2] = byteData[0]; + } + + } + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + 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) + { + SendDataChanged(debugData); + } + + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + if (HoldingRegistersChanged != null) + HoldingRegistersChanged(receiveData.startingAddressWrite + 1, receiveData.quantityWrite); + } + } + + private void sendException(int errorCode, int exceptionCode, ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) + { + sendData.response = true; + + sendData.transactionIdentifier = receiveData.transactionIdentifier; + sendData.protocolIdentifier = receiveData.protocolIdentifier; + + sendData.unitIdentifier = receiveData.unitIdentifier; + sendData.errorCode = (byte)errorCode; + sendData.exceptionCode = (byte)exceptionCode; + + if (sendData.exceptionCode > 0) + sendData.length = 0x03; + else + sendData.length = (ushort)(0x03 + sendData.byteCount); + + if (true) + { + Byte[] data; + if (sendData.exceptionCode > 0) + data = new byte[9 + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + else + data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(modbusType == ModbusType.ModbusRTU)]; + Byte[] byteData = new byte[2]; + sendData.length = (byte)(data.Length - 6); + + //Send Transaction identifier + byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); + data[0] = byteData[1]; + data[1] = byteData[0]; + + //Send Protocol identifier + byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); + data[2] = byteData[1]; + data[3] = byteData[0]; + + //Send length + byteData = BitConverter.GetBytes((int)sendData.length); + data[4] = byteData[1]; + data[5] = byteData[0]; + + //Unit Identifier + data[6] = sendData.unitIdentifier; + + + data[7] = sendData.errorCode; + data[8] = sendData.exceptionCode; + + + try + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + if (!serialport.IsOpen) + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + //Create CRC + sendData.crc = ModbusPoll.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); + byteData = BitConverter.GetBytes((int)sendData.crc); + data[data.Length - 2] = byteData[0]; + data[data.Length - 1] = byteData[1]; + serialport.Write(data, 6, data.Length - 6); + + 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) + { + SendDataChanged(debugData); + } + } + break; + case ModbusType.ModbusUDP: + { + //UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); + udpClient.Send(data, data.Length, endPoint); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + + } + break; + case ModbusType.ModbusTCP: + { + stream.Write(data, 0, data.Length); + if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); + if (SendDataChanged != null) + { + SendDataChanged(data); + } + } + break; + } + } + catch (Exception) { } + } + } + + private void CreateLogData(ModbusProtocol receiveData, ModbusProtocol sendData) + { + for (int i = 0; i < 98; i++) + { + modbusLogData[99 - i] = modbusLogData[99 - i - 2]; + + } + modbusLogData[0] = receiveData; + modbusLogData[1] = sendData; + + } + + /// + /// Gets or Sets the connection Timeout in case of ModbusTCP connection + /// + public int ConnectionTimeout + { + get + { + return connectTimeout; + } + set + { + connectTimeout = value; + } + } + + + public int NumberOfConnections + { + get + { + return numberOfConnections; + } + } + + public ModbusProtocol[] ModbusLogData + { + get + { + return modbusLogData; + } + } + + public int Port + { + get + { + return port; + } + set + { + port = value; + + + } + } + + //[DescriptionAttribute("Activate Modbus UDP; Disable Modbus TCP")] + //[CategoryAttribute("ModbusProperties")] + public ModbusType ModbusTypeSelection + { + get + { + return modbusType; + } + set + { + modbusType = value; + } + } + + public int Baudrate + { + get + { + return baudrate; + } + set + { + baudrate = value; + } + } + + public System.IO.Ports.Parity Parity + { + get + { + return parity; + } + set + { + parity = value; + } + } + + public System.IO.Ports.StopBits StopBits + { + get + { + return stopBits; + } + set + { + stopBits = value; + } + } + + public string SerialPort + { + get + { + return serialPort; + } + set + { + serialPort = value; + //if (serialPort != null) + // serialFlag = true; + //else + // serialFlag = false; + } + } + + public byte UnitIdentifier + { + get + { + return unitIdentifier; + } + set + { + unitIdentifier = value; + } + } + + + + + /// + /// Gets or Sets the Filename for the LogFile + /// + public string LogFileFilename + { + get + { + return StoreLogData.Instance.Filename; + } + set + { + StoreLogData.Instance.Filename = value; + if (StoreLogData.Instance.Filename != null) + debug = true; + else + debug = false; + } + } + + + + + public class HoldingRegisters + { + public Int16[] localArray = new Int16[65535]; + ModbusClient modbusServer; + + public HoldingRegisters(EasyModbus.ModbusClient modbusServer) + { + this.modbusServer = modbusServer; + } + + public Int16 this[int x] + { + get { return this.localArray[x]; } + set + { + this.localArray[x] = value; + + } + } + } + + public class InputRegisters + { + public Int16[] localArray = new Int16[65535]; + ModbusClient modbusServer; + + public InputRegisters(EasyModbus.ModbusClient modbusServer) + { + this.modbusServer = modbusServer; + } + + public Int16 this[int x] + { + get { return this.localArray[x]; } + set + { + this.localArray[x] = value; + + } + } + } + + public class Coils + { + public bool[] localArray = new bool[65535]; + ModbusClient modbusServer; + + public Coils(EasyModbus.ModbusClient modbusServer) + { + this.modbusServer = modbusServer; + } + + public bool this[int x] + { + get { return this.localArray[x]; } + set + { + this.localArray[x] = value; + + } + } + } + + public class DiscreteInputs + { + public bool[] localArray = new bool[65535]; + ModbusClient modbusServer; + + public DiscreteInputs(EasyModbus.ModbusClient modbusServer) + { + this.modbusServer = modbusServer; + } + + public bool this[int x] + { + get { return this.localArray[x]; } + set + { + this.localArray[x] = value; + + } + } + + + } + } +} diff --git a/EasyModbus/ModbusPoll.cs b/EasyModbus/ModbusPoll.cs new file mode 100644 index 0000000..28a2102 --- /dev/null +++ b/EasyModbus/ModbusPoll.cs @@ -0,0 +1,3550 @@ +/* +Copyright (c) 2018-2020 Rossmann-Engineering +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software +and associated documentation files (the "Software"), +to deal in the Software without restriction, +including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission +notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*************************************************************************************** +李锦上lijinshang@126.com修改版:主机 +*************************************************************************************** +2023-6-27:修复NumberOfRetries无效错误 if (NumberOfRetries > countRetries) +2023-6-27:修复TCP连接断线无法触发ConnectedChanged的问题 +2020-8-15:增加响应延时属性ResposeDelay 事件ResposeDelayChanged +2020-8-11:修正Modbus主机模式下退出报不能为Null异常错误 详见:~ModbusClient() +2020-8-11:修正UDP连接connected属性一直为True的问题 +2020-8-2:规范化ReceiveDataChanged(Byte[] data) SendDataChanged(Byte[] data)回调 +2020-8-1:增加ModbusType 规范化编程 +2020-8-1:增加UDP模式发送回传(全模式支持发送、接收通信数据回传) +2020-7-31:修正Modbus主机模式下连接超时 详见:connectTimeout +*************************************************************************************** + */ +using System; +using System.Net.Sockets; +using System.Net; +using System.IO.Ports; +using System.Reflection; +using System.Text; +using System.Collections.Generic; +using System.Timers; +using static EasyModbus.TCPHandler; +using System.Diagnostics; + +namespace EasyModbus +{ + /// + /// Implements a ModbusClient. + /// + public partial class ModbusPoll + { + public enum ModbusType { ModbusTCP, ModbusUDP, ModbusRTU }; + private ModbusType modbusType; + private uint resposeDelay; + 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 uint transactionIdentifierInternal = 0; + 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 int portOut; + private int baudRate = 9600; + private int connectTimeout = 1000; + public byte[] receiveData; + public byte[] sendData; + private SerialPort serialport; + private Parity parity = Parity.Even; + private StopBits stopBits = StopBits.One; + private bool connected = false; + public int NumberOfRetries { get; set; } = 3; + private int countRetries = 0; + + public delegate void ReceiveDataChangedHandler(Byte[] data); + public event ReceiveDataChangedHandler ReceiveDataChanged; + + public delegate void SendDataChangedHandler(Byte[] data); + public event SendDataChangedHandler SendDataChanged; + + public delegate void ConnectedChangedHandler(object sender); + public event ConnectedChangedHandler ConnectedChanged; + + public delegate void ResposeDelayChangedHandler(uint ResposeDelay); + public event ResposeDelayChangedHandler ResposeDelayChanged; + + NetworkStream stream; + + private System.Timers.Timer timerTCPCheck; + + /// + /// 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 ModbusPoll(string ipAddress, int port) + { + 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; + } + + /// + /// Constructor which determines the Serial-Port + /// + /// Serial-Port Name e.G. "COM1" + public ModbusPoll(string serialPort) + { + 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"); + Console.WriteLine(); +#endif + this.serialport = new SerialPort(); + serialport.PortName = serialPort; + serialport.BaudRate = baudRate; + serialport.Parity = parity; + serialport.StopBits = stopBits; + serialport.WriteTimeout = connectTimeout; + serialport.ReadTimeout = connectTimeout; + + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + } + + /// + /// Parameterless constructor + /// + public ModbusPoll() + { + 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() + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("Open Serial port " + serialport.PortName, System.DateTime.Now); + serialport.BaudRate = baudRate; + serialport.Parity = parity; + serialport.StopBits = stopBits; + serialport.WriteTimeout = connectTimeout; + serialport.ReadTimeout = connectTimeout; + serialport.Open(); + connected = true; + } + break; + case ModbusType.ModbusTCP: + if (debug) StoreLogData.Instance.Store("Open TCP-Socket, IP-Address: " + ipAddress + ", Port: " + port, System.DateTime.Now); + tcpClient = new TcpClient(); + var result = tcpClient.BeginConnect(ipAddress, port, null, null); + var success = result.AsyncWaitHandle.WaitOne(connectTimeout); + if (!success) + { + throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); + } + tcpClient.EndConnect(result); + + //tcpClient = new TcpClient(ipAddress, port); + stream = tcpClient.GetStream(); + stream.ReadTimeout = connectTimeout; + connected = true; + + timerTCPCheck = new System.Timers.Timer(1000); // 1s检测一次连接状态 + timerTCPCheck.Elapsed += CheckConnected; // 添加事件处理程序 + timerTCPCheck.Start(); // 启动计时器 + + break; + case ModbusType.ModbusUDP: + //tcpClient = new TcpClient(); + connected = true;//UDP connected标志由发送/接收方法处理 + + break; + } + if (ConnectedChanged != null) + ConnectedChanged(this); + } + + /// + /// Establish connection to Master device in case of Modbus TCP. + /// + public void Connect(string ipAddress, int port) + { + switch (modbusType) + { + case ModbusType.ModbusTCP: + if (debug) StoreLogData.Instance.Store("Open TCP-Socket, IP-Address: " + ipAddress + ", Port: " + port, System.DateTime.Now); + tcpClient = new TcpClient(); + var result = tcpClient.BeginConnect(ipAddress, port, null, null); + var success = result.AsyncWaitHandle.WaitOne(connectTimeout); + if (!success) + { + throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); + } + tcpClient.EndConnect(result); + + //tcpClient = new TcpClient(ipAddress, port); + stream = tcpClient.GetStream(); + stream.ReadTimeout = connectTimeout; + connected = true; + + timerTCPCheck = new System.Timers.Timer(1000); // 1s检测一次连接状态 + timerTCPCheck.Elapsed += CheckConnected; // 添加事件处理程序 + timerTCPCheck.Start(); // 启动计时器 + + break; + case ModbusType.ModbusUDP: + //tcpClient = new TcpClient(); + connected = true;//UDP connected标志由发送/接收方法处理 + break; + } + if (ConnectedChanged != null) + ConnectedChanged(this); + } + void CheckConnected(object sender, System.Timers.ElapsedEventArgs e) + { + bool TcpConnected = false; + try + { + TcpConnected = !(tcpClient.Client.Poll(1, SelectMode.SelectRead) && tcpClient.Client.Available == 0); + } + catch (SocketException) + { + TcpConnected = false; + } + + if (!TcpConnected) + { + Debug.WriteLine("TCP连接已断开"); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + timerTCPCheck.Stop(); // 关闭定时器 + } + else + { + Debug.WriteLine("TCP连接正常"); + } + } + /// + /// Converts two ModbusRegisters to Float - Example: EasyModbus.ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(19,2)) + /// + /// Two Register values received from Modbus + /// Connected float value + public static float ConvertRegistersToFloat(int[] registers) + { + if (registers.Length != 2) + throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); + int highRegister = registers[1]; + int lowRegister = registers[0]; + byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); + byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); + byte[] floatBytes = { + lowRegisterBytes[0], + lowRegisterBytes[1], + highRegisterBytes[0], + highRegisterBytes[1] + }; + return BitConverter.ToSingle(floatBytes, 0); + } + + /// + /// Converts two ModbusRegisters to Float, Registers can by swapped + /// + /// Two Register values received from Modbus + /// Desired Word Order (Low Register first or High Register first + /// 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] }; + return ConvertRegistersToFloat(swappedRegisters); + } + + /// + /// Converts two ModbusRegisters to 32 Bit Integer value + /// + /// Two Register values received from Modbus + /// Connected 32 Bit Integer value + public static Int32 ConvertRegistersToInt(int[] registers) + { + if (registers.Length != 2) + throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); + int highRegister = registers[1]; + int lowRegister = registers[0]; + byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); + byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); + byte[] doubleBytes = { + lowRegisterBytes[0], + lowRegisterBytes[1], + highRegisterBytes[0], + highRegisterBytes[1] + }; + return BitConverter.ToInt32(doubleBytes, 0); + } + + /// + /// Converts two ModbusRegisters to 32 Bit Integer Value - Registers can be swapped + /// + /// Two Register values received from Modbus + /// Desired Word Order (Low Register first or High Register first + /// Connecteds 32 Bit Integer value + public static Int32 ConvertRegistersToInt(int[] registers, RegisterOrder registerOrder) + { + int[] swappedRegisters = { registers[0], registers[1] }; + if (registerOrder == RegisterOrder.HighLow) + swappedRegisters = new int[] { registers[1], registers[0] }; + return ConvertRegistersToInt(swappedRegisters); + } + + /// + /// Convert four 16 Bit Registers to 64 Bit Integer value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word + /// + /// four Register values received from Modbus + /// 64 bit value + public static Int64 ConvertRegistersToLong(int[] registers) + { + if (registers.Length != 4) + throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); + int highRegister = registers[3]; + int highLowRegister = registers[2]; + int lowHighRegister = registers[1]; + int lowRegister = registers[0]; + byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); + byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); + byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); + byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); + byte[] longBytes = { + lowRegisterBytes[0], + lowRegisterBytes[1], + lowHighRegisterBytes[0], + lowHighRegisterBytes[1], + highLowRegisterBytes[0], + highLowRegisterBytes[1], + highRegisterBytes[0], + highRegisterBytes[1] + }; + return BitConverter.ToInt64(longBytes, 0); + } + + /// + /// Convert four 16 Bit Registers to 64 Bit Integer value - Registers can be swapped + /// + /// four Register values received from Modbus + /// Desired Word Order (Low Register first or High Register first + /// Connected 64 Bit Integer value + public static Int64 ConvertRegistersToLong(int[] registers, RegisterOrder registerOrder) + { + if (registers.Length != 4) + throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); + int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; + if (registerOrder == RegisterOrder.HighLow) + swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; + return ConvertRegistersToLong(swappedRegisters); + } + + /// + /// Convert four 16 Bit Registers to 64 Bit double prec. value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word + /// + /// four Register values received from Modbus + /// 64 bit value + public static double ConvertRegistersToDouble(int[] registers) + { + if (registers.Length != 4) + throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); + int highRegister = registers[3]; + int highLowRegister = registers[2]; + int lowHighRegister = registers[1]; + int lowRegister = registers[0]; + byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); + byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); + byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); + byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); + byte[] longBytes = { + lowRegisterBytes[0], + lowRegisterBytes[1], + lowHighRegisterBytes[0], + lowHighRegisterBytes[1], + highLowRegisterBytes[0], + highLowRegisterBytes[1], + highRegisterBytes[0], + highRegisterBytes[1] + }; + return BitConverter.ToDouble(longBytes, 0); + } + + /// + /// Convert four 16 Bit Registers to 64 Bit double prec. value - Registers can be swapped + /// + /// four Register values received from Modbus + /// Desired Word Order (Low Register first or High Register first + /// Connected double prec. float value + public static double ConvertRegistersToDouble(int[] registers, RegisterOrder registerOrder) + { + if (registers.Length != 4) + throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); + int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; + if (registerOrder == RegisterOrder.HighLow) + swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; + return ConvertRegistersToDouble(swappedRegisters); + } + + /// + /// Converts float to two ModbusRegisters - Example: modbusClient.WriteMultipleRegisters(24, EasyModbus.ModbusClient.ConvertFloatToTwoRegisters((float)1.22)); + /// + /// Float value which has to be converted into two registers + /// Register values + public static int[] ConvertFloatToRegisters(float floatValue) + { + byte[] floatBytes = BitConverter.GetBytes(floatValue); + byte[] highRegisterBytes = + { + floatBytes[2], + floatBytes[3], + 0, + 0 + }; + byte[] lowRegisterBytes = + { + + floatBytes[0], + floatBytes[1], + 0, + 0 + }; + int[] returnValue = + { + BitConverter.ToInt32(lowRegisterBytes,0), + BitConverter.ToInt32(highRegisterBytes,0) + }; + return returnValue; + } + + /// + /// Converts float to two ModbusRegisters Registers - Registers can be swapped + /// + /// Float value which has to be converted into two registers + /// Desired Word Order (Low Register first or High Register first + /// Register values + public static int[] ConvertFloatToRegisters(float floatValue, RegisterOrder registerOrder) + { + int[] registerValues = ConvertFloatToRegisters(floatValue); + int[] returnValue = registerValues; + if (registerOrder == RegisterOrder.HighLow) + returnValue = new Int32[] { registerValues[1], registerValues[0] }; + return returnValue; + } + + /// + /// Converts 32 Bit Value to two ModbusRegisters + /// + /// Int value which has to be converted into two registers + /// Register values + public static int[] ConvertIntToRegisters(Int32 intValue) + { + byte[] doubleBytes = BitConverter.GetBytes(intValue); + byte[] highRegisterBytes = + { + doubleBytes[2], + doubleBytes[3], + 0, + 0 + }; + byte[] lowRegisterBytes = + { + + doubleBytes[0], + doubleBytes[1], + 0, + 0 + }; + int[] returnValue = + { + BitConverter.ToInt32(lowRegisterBytes,0), + BitConverter.ToInt32(highRegisterBytes,0) + }; + return returnValue; + } + + /// + /// Converts 32 Bit Value to two ModbusRegisters Registers - Registers can be swapped + /// + /// Double value which has to be converted into two registers + /// Desired Word Order (Low Register first or High Register first + /// Register values + public static int[] ConvertIntToRegisters(Int32 intValue, RegisterOrder registerOrder) + { + int[] registerValues = ConvertIntToRegisters(intValue); + int[] returnValue = registerValues; + if (registerOrder == RegisterOrder.HighLow) + returnValue = new Int32[] { registerValues[1], registerValues[0] }; + return returnValue; + } + + /// + /// Converts 64 Bit Value to four ModbusRegisters + /// + /// long value which has to be converted into four registers + /// Register values + public static int[] ConvertLongToRegisters(Int64 longValue) + { + byte[] longBytes = BitConverter.GetBytes(longValue); + byte[] highRegisterBytes = + { + longBytes[6], + longBytes[7], + 0, + 0 + }; + byte[] highLowRegisterBytes = + { + longBytes[4], + longBytes[5], + 0, + 0 + }; + byte[] lowHighRegisterBytes = + { + longBytes[2], + longBytes[3], + 0, + 0 + }; + byte[] lowRegisterBytes = + { + + longBytes[0], + longBytes[1], + 0, + 0 + }; + int[] returnValue = + { + BitConverter.ToInt32(lowRegisterBytes,0), + BitConverter.ToInt32(lowHighRegisterBytes,0), + BitConverter.ToInt32(highLowRegisterBytes,0), + BitConverter.ToInt32(highRegisterBytes,0) + }; + return returnValue; + } + + /// + /// Converts 64 Bit Value to four ModbusRegisters - Registers can be swapped + /// + /// long value which has to be converted into four registers + /// Desired Word Order (Low Register first or High Register first + /// Register values + public static int[] ConvertLongToRegisters(Int64 longValue, RegisterOrder registerOrder) + { + int[] registerValues = ConvertLongToRegisters(longValue); + int[] returnValue = registerValues; + if (registerOrder == RegisterOrder.HighLow) + returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; + return returnValue; + } + + /// + /// Converts 64 Bit double prec Value to four ModbusRegisters + /// + /// double value which has to be converted into four registers + /// Register values + public static int[] ConvertDoubleToRegisters(double doubleValue) + { + byte[] doubleBytes = BitConverter.GetBytes(doubleValue); + byte[] highRegisterBytes = + { + doubleBytes[6], + doubleBytes[7], + 0, + 0 + }; + byte[] highLowRegisterBytes = + { + doubleBytes[4], + doubleBytes[5], + 0, + 0 + }; + byte[] lowHighRegisterBytes = + { + doubleBytes[2], + doubleBytes[3], + 0, + 0 + }; + byte[] lowRegisterBytes = + { + + doubleBytes[0], + doubleBytes[1], + 0, + 0 + }; + int[] returnValue = + { + BitConverter.ToInt32(lowRegisterBytes,0), + BitConverter.ToInt32(lowHighRegisterBytes,0), + BitConverter.ToInt32(highLowRegisterBytes,0), + BitConverter.ToInt32(highRegisterBytes,0) + }; + return returnValue; + } + + /// + /// Converts 64 Bit double prec. Value to four ModbusRegisters - Registers can be swapped + /// + /// double value which has to be converted into four registers + /// Desired Word Order (Low Register first or High Register first + /// Register values + public static int[] ConvertDoubleToRegisters(double doubleValue, RegisterOrder registerOrder) + { + int[] registerValues = ConvertDoubleToRegisters(doubleValue); + int[] returnValue = registerValues; + if (registerOrder == RegisterOrder.HighLow) + returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; + return returnValue; + } + + /// + /// Converts 16 - Bit Register values to String + /// + /// Register array received via Modbus + /// First Register containing the String to convert + /// 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++) + { + registerResult = BitConverter.GetBytes(registers[offset + i]); + result[i * 2] = registerResult[0]; + result[i * 2 + 1] = registerResult[1]; + } + return System.Text.Encoding.Default.GetString(result); + } + + /// + /// Converts a String to 16 - Bit Registers + /// + /// Register array received via Modbus + /// Converted String + public static int[] ConvertStringToRegisters(string stringToConvert) + { + byte[] array = System.Text.Encoding.ASCII.GetBytes(stringToConvert); + int[] returnarray = new int[stringToConvert.Length / 2 + stringToConvert.Length % 2]; + for (int i = 0; i < returnarray.Length; i++) + { + returnarray[i] = array[i * 2]; + if (i * 2 + 1 < array.Length) + { + returnarray[i] = returnarray[i] | ((int)array[i * 2 + 1] << 8); + } + } + return returnarray; + } + + + /// + /// Calculates the CRC16 for Modbus-RTU + /// + /// Byte buffer to send + /// 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, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, + 0xC0, 0x80, 0x41, 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, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, + 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 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, 0x80, 0x41, 0x01, + 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 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, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, + 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, + 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, + 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, + 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, + 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, + 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, + 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, + 0x40 + }; + UInt16 usDataLen = numberOfBytes; + byte uchCRCHi = 0xFF; + byte uchCRCLo = 0xFF; + int i = 0; + int uIndex; + while (usDataLen > 0) + { + usDataLen--; + if ((i + startByte) < data.Length) + { + uIndex = uchCRCLo ^ data[i + startByte]; + uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]); + uchCRCHi = auchCRCLo[uIndex]; + } + i++; + } + return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); + } + + private bool dataReceived = false; + private bool receiveActive = false; + private byte[] readBuffer = new byte[256]; + 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; + // } + + // 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); + + // } + + + // //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; + if (bytesToRead == 0) + { + sp.DiscardInBuffer(); + receiveActive = false; + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + return; + } + readBuffer = new byte[256]; + 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) + { + + } + + if (bytesToRead <= actualPositionToRead) + break; + + if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) + break; + } + 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); + bytesToRead = 0; + + + + + dataReceived = true; + receiveActive = false; + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + if (ReceiveDataChanged != null) + { + ReceiveDataChanged(receiveData); + } + + //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; + //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; + return true; + } + + + + /// + /// Read Discrete Inputs from Server device (FC2). + /// + /// First discrete input to read + /// Number of discrete Inputs to read + /// Boolean Array which contains the discrete Inputs + public bool[] ReadDiscreteInputs(int startingAddress, int quantity) + { + DateTime Send_DateTime; + if (debug) StoreLogData.Instance.Store("FC2 (Read Discrete Inputs from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); + transactionIdentifierInternal++; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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.crc[0], + this.crc[1] + }; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + if (quantity % 8 == 0) + bytesToRead = 5 + quantity / 8; + else + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + + + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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 (NumberOfRetries > countRetries) + { + countRetries = 0; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + return ReadDiscreteInputs(startingAddress, quantity); + } + } + else if (!dataReceived) + { + 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 ReadDiscreteInputs(startingAddress, quantity); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x82 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x82 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + response = new bool[quantity]; + try + { + 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); + } + } + catch { } + return (response); + } + + + /// + /// Read Coils from Server device (FC1). + /// + /// First coil to read + /// Numer of coils to read + /// Boolean Array which contains the coils + public bool[] ReadCoils(int startingAddress, int quantity) + { + DateTime Send_DateTime; + if (debug) StoreLogData.Instance.Store("FC1 (Read Coils from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); + transactionIdentifierInternal++; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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.crc[0], + this.crc[1] + }; + + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + if (quantity % 8 == 0) + bytesToRead = 5 + quantity / 8; + else + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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 (NumberOfRetries > countRetries) + { + countRetries = 0; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + return ReadCoils(startingAddress, quantity); + } + } + else if (!dataReceived) + { + 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 ReadCoils(startingAddress, quantity); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x81 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x81 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + response = new bool[quantity]; + try + { + 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); + } + } + catch { } + return (response); + } + + + /// + /// Read Holding Registers from Master device (FC3). + /// + /// First holding register to be read + /// Number of holding registers to be read + /// Int Array which contains the holding registers + public int[] ReadHoldingRegisters(int startingAddress, int quantity) + { + DateTime Send_DateTime; + if (debug) StoreLogData.Instance.Store("FC3 (Read Holding Registers from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); + transactionIdentifierInternal++; + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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] + }; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 5 + 2 * quantity; + // 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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 (NumberOfRetries > countRetries) + { + countRetries = 0; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + return ReadHoldingRegisters(startingAddress, quantity); + } + } + else if (!dataReceived) + { + 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 ReadHoldingRegisters(startingAddress, quantity); + } + + + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + + } + data = new Byte[256]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x83 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x83 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + response = new int[quantity]; + try + { + 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)); + } + } + catch { } + return (response); + } + + + + /// + /// Read Input Registers from Master device (FC4). + /// + /// First input register to be read + /// Number of input registers to be read + /// Int Array which contains the input registers + public int[] ReadInputRegisters(int startingAddress, int quantity) + { + DateTime Send_DateTime; + if (debug) StoreLogData.Instance.Store("FC4 (Read Input Registers from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity, System.DateTime.Now); + transactionIdentifierInternal++; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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] + }; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 5 + 2 * quantity; + + + // 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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 (NumberOfRetries > countRetries) + { + countRetries = 0; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + return ReadInputRegisters(startingAddress, quantity); + } + } + else if (!dataReceived) + { + 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); + } + + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x84 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x84 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + response = new int[quantity]; + try + { + 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)); + } + } + catch { } + return (response); + } + + + /// + /// Write single Coil to Master device (FC5). + /// + /// Coil to be written + /// Coil Value to be written + public void WriteSingleCoil(int startingAddress, bool value) + { + DateTime Send_DateTime; + + if (debug) StoreLogData.Instance.Store("FC5 (Write single coil to Master device), StartingAddress: " + startingAddress + ", Value: " + value, System.DateTime.Now); + transactionIdentifierInternal++; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + byte[] coilValue = new byte[2]; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)0x0006); + this.functionCode = 0x05; + this.startingAddress = BitConverter.GetBytes(startingAddress); + if (value == true) + { + coilValue = BitConverter.GetBytes((int)0xFF00); + } + else + { + 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], + this.crc[0], + this.crc[1] + }; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + WriteSingleCoil(startingAddress, value); + } + } + else if (!dataReceived) + { + 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++; + WriteSingleCoil(startingAddress, value); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x85 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x85 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + } + + + /// + /// Write single Register to Master device (FC6). + /// + /// Register to be written + /// Register Value to be written + public void WriteSingleRegister(int startingAddress, int value) + { + DateTime Send_DateTime; + if (debug) StoreLogData.Instance.Store("FC6 (Write single register to Master device), StartingAddress: " + startingAddress + ", Value: " + value, System.DateTime.Now); + transactionIdentifierInternal++; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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], + this.crc[0], + this.crc[1] + }; + crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); + data[12] = crc[0]; + data[13] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[8]; + Array.Copy(data, 6, sendData, 0, 8); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + WriteSingleRegister(startingAddress, value); + } + } + else if (!dataReceived) + { + 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++; + WriteSingleRegister(startingAddress, value); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x86 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x86 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + } + + /// + /// Write multiple coils to Master device (FC15). + /// + /// First coil to be written + /// Coil Values to be written + public void WriteMultipleCoils(int startingAddress, bool[] values) + { + DateTime Send_DateTime; + 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); + transactionIdentifierInternal++; + byte byteCount = (byte)((values.Length % 8 != 0 ? values.Length / 8 + 1 : (values.Length / 8))); + byte[] quantityOfOutputs = BitConverter.GetBytes((int)values.Length); + byte singleCoilValue = 0; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + 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)]; + 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[10] = quantityOfOutputs[1]; + data[11] = quantityOfOutputs[0]; + data[12] = byteCount; + for (int i = 0; i < values.Length; i++) + { + if ((i % 8) == 0) + singleCoilValue = 0; + byte CoilValue; + if (values[i] == true) + CoilValue = 1; + else + CoilValue = 0; + + + singleCoilValue = (byte)((int)CoilValue << (i % 8) | (int)singleCoilValue); + + data[13 + (i / 8)] = singleCoilValue; + } + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); + data[data.Length - 2] = crc[0]; + data[data.Length - 1] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 8; + // 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + WriteMultipleCoils(startingAddress, values); + } + } + else if (!dataReceived) + { + 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++; + WriteMultipleCoils(startingAddress, values); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x8F & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x8F & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + } + + /// + /// Write multiple registers to Master device (FC16). + /// + /// First register to be written + /// register Values to be written + public void WriteMultipleRegisters(int startingAddress, int[] values) + { + DateTime Send_DateTime; + 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); + transactionIdentifierInternal++; + byte byteCount = (byte)(values.Length * 2); + byte[] quantityOfOutputs = BitConverter.GetBytes((int)values.Length); + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + 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]; + 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[10] = quantityOfOutputs[1]; + data[11] = quantityOfOutputs[0]; + data[12] = byteCount; + 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]; + } + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); + data[data.Length - 2] = crc[0]; + data[data.Length - 1] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + bytesToRead = 8; + // 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(sendData); + + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + 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; + throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); + } + else + { + countRetries++; + WriteMultipleRegisters(startingAddress, values); + } + } + else if (!dataReceived) + { + 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++; + WriteMultipleRegisters(startingAddress, values); + } + } + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x90 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x90 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + + } + + /// + /// Read/Write Multiple Registers (FC23). + /// + /// First input register to read + /// Number of input registers to read + /// First input register to write + /// Values to write + /// Int Array which contains the Holding registers + public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRead, int startingAddressWrite, int[] values) + { + DateTime Send_DateTime; + 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); + transactionIdentifierInternal++; + byte[] startingAddressReadLocal = new byte[2]; + byte[] quantityReadLocal = new byte[2]; + byte[] startingAddressWriteLocal = new byte[2]; + byte[] quantityWriteLocal = new byte[2]; + byte writeByteCountLocal = 0; + + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (!serialport.IsOpen) + { + if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); + } + break; + case ModbusType.ModbusTCP: + if (tcpClient == null) + { + if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ConnectionException("connection error"); + } + break; + } + 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"); + } + int[] response; + this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); + this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); + this.length = BitConverter.GetBytes((int)11 + values.Length * 2); + this.functionCode = 0x17; + startingAddressReadLocal = BitConverter.GetBytes(startingAddressRead); + quantityReadLocal = BitConverter.GetBytes(quantityRead); + 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; + + 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]; + } + crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); + data[data.Length - 2] = crc[0]; + data[data.Length - 1] = crc[1]; + switch (modbusType) + { + case ModbusType.ModbusRTU: + { + dataReceived = false; + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 6]; + Array.Copy(data, 6, sendData, 0, data.Length - 6); + SendDataChanged(sendData); + } + data = new byte[2100]; + readBuffer = new byte[256]; + DateTime dateTimeSend = DateTime.Now; + byte receivedUnitIdentifier = 0xFF; + 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)) + System.Threading.Thread.Sleep(1); + data = new byte[2100]; + Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); + receivedUnitIdentifier = data[6]; + } + if (receivedUnitIdentifier != this.unitIdentifier) + data = new byte[2100]; + else + countRetries = 0; + } + break; + case ModbusType.ModbusUDP: + try + { + UdpClient udpClient = new UdpClient(); + IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); + udpClient.Send(data, data.Length - 2, endPoint); + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + } + portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + udpClient.Client.ReceiveTimeout = connectTimeout; + endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); + data = udpClient.Receive(ref endPoint); + + //int NumberOfBytes = stream.Read(data, 0, data.Length); + int NumberOfBytes = data.Length; + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + if (connected == false) + { + connected = true; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + catch + { + Array.Clear(data, 0, data.Length); + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + case ModbusType.ModbusTCP: + if (tcpClient.Client.Connected) + { + 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); + } + Send_DateTime = DateTime.Now; + if (SendDataChanged != null) + { + sendData = new byte[data.Length - 2]; + Array.Copy(data, 0, sendData, 0, data.Length - 2); + SendDataChanged(sendData); + + } + data = new Byte[2100]; + int NumberOfBytes = stream.Read(data, 0, data.Length); + resposeDelay = (uint)((DateTime.Now.Ticks - Send_DateTime.Ticks) / 10000); + if (ResposeDelayChanged != null) + { + ResposeDelayChanged(resposeDelay); + } + if (ReceiveDataChanged != null) + { + 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(receiveData); + } + } + else + { + if (connected == true) + { + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + } + } + break; + } + if (data[7] == 0x97 & data[8] == 0x01) + { + 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); + 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); + throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); + } + if (data[7] == 0x97 & data[8] == 0x04) + { + if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); + throw new EasyModbus.Exceptions.ModbusException("error reading"); + } + response = new int[quantityRead]; + for (int i = 0; i < quantityRead; 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); + } + + /// + /// Close connection to Master Device. + /// + public void Disconnect() + { + if (debug) StoreLogData.Instance.Store("Disconnect", System.DateTime.Now); + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (serialport.IsOpen & !this.receiveActive) + serialport.Close(); + if (ConnectedChanged != null) + ConnectedChanged(this); + break; + case ModbusType.ModbusTCP: + case ModbusType.ModbusUDP: + if (stream != null) + stream.Close(); + if (tcpClient != null) + tcpClient.Close(); + connected = false; + if (ConnectedChanged != null) + ConnectedChanged(this); + break; + } + + } + + /// + /// Destructor - Close connection to Master Device. + /// + ~ModbusPoll() + { + if (debug) StoreLogData.Instance.Store("Destructor called - automatically disconnect", System.DateTime.Now); + switch (modbusType) + { + case ModbusType.ModbusRTU: + if (serialport != null && serialport.IsOpen) + serialport.Close(); + break; + case ModbusType.ModbusTCP: + case ModbusType.ModbusUDP: + if (stream != null) + stream.Close(); + if (tcpClient != null) + tcpClient.Close(); + break; + } + } + + /// + /// 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 + { + switch (modbusType) + { + case ModbusType.ModbusRTU: + return (serialport.IsOpen); + break; + case ModbusType.ModbusTCP: + case ModbusType.ModbusUDP: + + //if (modbusType == ModbusType.ModbusUDP && tcpClient != null) + // return true; + //if (tcpClient == null) + // return false; + //else + return connected; + break; + + } + return false; + } + } + + public bool Available(int timeout) + { + // Ping's the local machine. + System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping(); + IPAddress address = System.Net.IPAddress.Parse(ipAddress); + + // Create a buffer of 32 bytes of data to be transmitted. + string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + byte[] buffer = System.Text.Encoding.ASCII.GetBytes(data); + + // Wait 10 seconds for a reply. + System.Net.NetworkInformation.PingReply reply = pingSender.Send(address, timeout, buffer); + + if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) + return true; + else + return false; + } + + /// + /// Gets or Sets the IP-Address of the Server. + /// + public string IPAddress + { + 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; + } + } + + //[DescriptionAttribute("Activate Modbus UDP; Disable Modbus TCP")] + //[CategoryAttribute("ModbusProperties")] + public ModbusType ModbusTypeSelection + { + get + { + return modbusType; + } + set + { + modbusType = value; + } + } + /// + /// 反应延时 + /// + public uint ResposeDelay + { + get { return resposeDelay; } + } + + + /// + /// Gets or Sets the Unit identifier in case of serial connection (Default = 0) + /// + public byte UnitIdentifier + { + get + { + return unitIdentifier; + } + set + { + unitIdentifier = value; + } + } + + + /// + /// Gets or Sets the Baudrate for serial connection (Default = 9600) + /// + public int Baudrate + { + get + { + return baudRate; + } + set + { + baudRate = value; + } + } + + /// + /// Gets or Sets the of Parity in case of serial connection + /// + public Parity Parity + { + get + { + return parity; + } + set + { + parity = value; + } + } + + + /// + /// Gets or Sets the number of stopbits in case of serial connection + /// + public StopBits StopBits + { + get + { + return stopBits; + } + set + { + stopBits = value; + } + } + + /// + /// Gets or Sets the connection Timeout in case of ModbusTCP connection + /// + public int ConnectionTimeout + { + get + { + return connectTimeout; + } + set + { + connectTimeout = value; + } + } + + /// + /// Gets or Sets the serial Port + /// + public string SerialPort + { + get + { + + return serialport.PortName; + } + set + { + if (value == null) + { + serialport = null; + return; + } + if (serialport != null) + serialport.Close(); + this.serialport = new SerialPort(); + this.serialport.PortName = value; + serialport.BaudRate = baudRate; + serialport.Parity = parity; + serialport.StopBits = stopBits; + serialport.WriteTimeout = connectTimeout; + serialport.ReadTimeout = connectTimeout; + serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + } + } + + /// + /// Gets or Sets the Filename for the LogFile + /// + public string LogFileFilename + { + get + { + return StoreLogData.Instance.Filename; + } + set + { + StoreLogData.Instance.Filename = value; + if (StoreLogData.Instance.Filename != null) + debug = true; + else + debug = false; + } + } + + } +} diff --git a/EasyModbus/ModbusServer.cs b/EasyModbus/ModbusServer.cs deleted file mode 100644 index 13374cd..0000000 --- a/EasyModbus/ModbusServer.cs +++ /dev/null @@ -1,2266 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Net.Sockets; -using System.Net; -using System.Threading; -using System.Net.NetworkInformation; -using System.IO.Ports; - -namespace EasyModbus -{ -#region class ModbusProtocol - /// - /// Modbus Protocol informations. - /// - public class ModbusProtocol - { - public enum ProtocolType { ModbusTCP = 0, ModbusUDP = 1, ModbusRTU = 2}; - public DateTime timeStamp; - public bool request; - public bool response; - public UInt16 transactionIdentifier; - public UInt16 protocolIdentifier; - public UInt16 length; - public byte unitIdentifier; - public byte functionCode; - public UInt16 startingAdress; - public UInt16 startingAddressRead; - public UInt16 startingAddressWrite; - public UInt16 quantity; - public UInt16 quantityRead; - public UInt16 quantityWrite; - public byte byteCount; - public byte exceptionCode; - public byte errorCode; - public UInt16[] receiveCoilValues; - public UInt16[] receiveRegisterValues; - public Int16[] sendRegisterValues; - public bool[] sendCoilValues; - public UInt16 crc; - } -#endregion - -#region structs - struct NetworkConnectionParameter - { - public NetworkStream stream; //For TCP-Connection only - public Byte[] bytes; - public int portIn; //For UDP-Connection only - public IPAddress ipAddressIn; //For UDP-Connection only - } -#endregion - -#region TCPHandler class - internal class TCPHandler - { - public delegate void DataChanged(object networkConnectionParameter); - public event DataChanged dataChanged; - - public delegate void NumberOfClientsChanged(); - public event NumberOfClientsChanged numberOfClientsChanged; - - TcpListener server = null; - - - private List tcpClientLastRequestList = new List(); - - public int NumberOfConnectedClients { get; set; } - - public string ipAddress = null; - - /// When making a server TCP listen socket, will listen to this IP address. - public IPAddress LocalIPAddress { - get { return localIPAddress; } - } - private IPAddress localIPAddress = IPAddress.Any; - - /// - /// Listen to all network interfaces. - /// - /// TCP port to listen - public TCPHandler(int port) - { - server = new TcpListener(LocalIPAddress, port); - server.Start(); - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - } - - /// - /// Listen to a specific network interface. - /// - /// IP address of network interface to listen - /// TCP port to listen - public TCPHandler(IPAddress localIPAddress, int port) - { - this.localIPAddress = localIPAddress; - server = new TcpListener(LocalIPAddress, port); - server.Start(); - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - } - - - private void AcceptTcpClientCallback(IAsyncResult asyncResult) - { - TcpClient tcpClient = new TcpClient(); - try - { - tcpClient = server.EndAcceptTcpClient(asyncResult); - tcpClient.ReceiveTimeout = 4000; - if (ipAddress != null) - { - string ipEndpoint = tcpClient.Client.RemoteEndPoint.ToString(); - ipEndpoint = ipEndpoint.Split(':')[0]; - if (ipEndpoint != ipAddress) - { - tcpClient.Client.Disconnect(false); - return; - } - } - } - catch (Exception) { } - try - { - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - Client client = new Client(tcpClient); - NetworkStream networkStream = client.NetworkStream; - networkStream.ReadTimeout = 4000; - networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); - } - catch (Exception) { } - } - - private int GetAndCleanNumberOfConnectedClients(Client client) - { - lock (this) - { - int i = 0; - bool objetExists = false; - foreach (Client clientLoop in tcpClientLastRequestList) - { - if (client.Equals(clientLoop)) - objetExists = true; - } - try - { - tcpClientLastRequestList.RemoveAll(delegate (Client c) - { - return ((DateTime.Now.Ticks - c.Ticks) > 40000000); - } - - ); - } - catch (Exception) { } - if (!objetExists) - tcpClientLastRequestList.Add(client); - - - return tcpClientLastRequestList.Count; - } - } - - private void ReadCallback(IAsyncResult asyncResult) - { - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - Client client = asyncResult.AsyncState as Client; - client.Ticks = DateTime.Now.Ticks; - NumberOfConnectedClients = GetAndCleanNumberOfConnectedClients(client); - if (numberOfClientsChanged != null) - numberOfClientsChanged(); - if (client != null) - { - int read; - NetworkStream networkStream = null; - try - { - networkStream = client.NetworkStream; - - read = networkStream.EndRead(asyncResult); - } - catch (Exception ex) - { - return; - } - - - if (read == 0) - { - //OnClientDisconnected(client.TcpClient); - //connectedClients.Remove(client); - return; - } - byte[] data = new byte[read]; - Buffer.BlockCopy(client.Buffer, 0, data, 0, read); - networkConnectionParameter.bytes = data; - networkConnectionParameter.stream = networkStream; - if (dataChanged != null) - dataChanged(networkConnectionParameter); - try - { - networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); - } - catch (Exception) - { - } - } - } - - public void Disconnect() - { - try - { - foreach (Client clientLoop in tcpClientLastRequestList) - { - clientLoop.NetworkStream.Close(00); - } - } - catch (Exception) { } - server.Stop(); - - } - - - internal class Client - { - private readonly TcpClient tcpClient; - private readonly byte[] buffer; - public long Ticks { get; set; } - - public Client(TcpClient tcpClient) - { - this.tcpClient = tcpClient; - int bufferSize = tcpClient.ReceiveBufferSize; - buffer = new byte[bufferSize]; - } - - public TcpClient TcpClient - { - get { return tcpClient; } - } - - public byte[] Buffer - { - get { return buffer; } - } - - public NetworkStream NetworkStream - { - get { - - return tcpClient.GetStream(); - - } - } - } - } -#endregion - - /// - /// Modbus TCP Server. - /// - public class ModbusServer - { - private bool debug = false; - Int32 port = 502; - ModbusProtocol receiveData; - ModbusProtocol sendData = new ModbusProtocol(); - Byte[] bytes = new Byte[2100]; - //public Int16[] _holdingRegisters = new Int16[65535]; - public HoldingRegisters holdingRegisters; - public InputRegisters inputRegisters; - public Coils coils; - public DiscreteInputs discreteInputs; - private int numberOfConnections = 0; - private bool udpFlag; - private bool serialFlag; - private int baudrate = 9600; - private System.IO.Ports.Parity parity = Parity.Even; - private System.IO.Ports.StopBits stopBits = StopBits.One; - private string serialPort = "COM1"; - private SerialPort serialport; - private byte unitIdentifier = 1; - private int portIn; - private IPAddress ipAddressIn; - private UdpClient udpClient; - private IPEndPoint iPEndPoint; - private TCPHandler tcpHandler; - Thread listenerThread; - Thread clientConnectionThread; - private ModbusProtocol[] modbusLogData = new ModbusProtocol[100]; - public bool FunctionCode1Disabled {get; set;} - public bool FunctionCode2Disabled { get; set; } - public bool FunctionCode3Disabled { get; set; } - public bool FunctionCode4Disabled { get; set; } - public bool FunctionCode5Disabled { get; set; } - public bool FunctionCode6Disabled { get; set; } - public bool FunctionCode15Disabled { get; set; } - public bool FunctionCode16Disabled { get; set; } - public bool FunctionCode23Disabled { get; set; } - public bool PortChanged { get; set; } - object lockCoils = new object(); - object lockHoldingRegisters = new object(); - private volatile bool shouldStop; - - private IPAddress localIPAddress = IPAddress.Any; - - /// - /// When creating a TCP or UDP socket, the local IP address to attach to. - /// - public IPAddress LocalIPAddress - { - get { return localIPAddress; } - set { if (listenerThread == null) localIPAddress = value; } - } - - public ModbusServer() - { - holdingRegisters = new HoldingRegisters(this); - inputRegisters = new InputRegisters(this); - coils = new Coils(this); - discreteInputs = new DiscreteInputs(this); - - } - - #region events - public delegate void CoilsChangedHandler(int coil, int numberOfCoils); - public event CoilsChangedHandler CoilsChanged; - - public delegate void HoldingRegistersChangedHandler(int register, int numberOfRegisters); - public event HoldingRegistersChangedHandler HoldingRegistersChanged; - - public delegate void NumberOfConnectedClientsChangedHandler(); - public event NumberOfConnectedClientsChangedHandler NumberOfConnectedClientsChanged; - - public delegate void LogDataChangedHandler(); - public event LogDataChangedHandler LogDataChanged; - #endregion - - public void Listen() - { - - listenerThread = new Thread(ListenerThread); - listenerThread.Start(); - } - - public void StopListening() - { - if (SerialFlag & (serialport != null)) - { - if (serialport.IsOpen) - serialport.Close(); - shouldStop = true; - } - try - { - tcpHandler.Disconnect(); - listenerThread.Abort(); - - } - catch (Exception) { } - listenerThread.Join(); - try - { - - clientConnectionThread.Abort(); - } - catch (Exception) { } - } - - private void ListenerThread() - { - if (!udpFlag & !serialFlag) - { - if (udpClient != null) - { - try - { - udpClient.Close(); - } - catch (Exception) { } - } - tcpHandler = new TCPHandler(LocalIPAddress, port); - if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); - tcpHandler.dataChanged += new TCPHandler.DataChanged(ProcessReceivedData); - tcpHandler.numberOfClientsChanged += new TCPHandler.NumberOfClientsChanged(numberOfClientsChanged); - } - else if (serialFlag) - { - if (serialport == null) - { - if (debug) StoreLogData.Instance.Store("EasyModbus RTU-Server listing for incomming data at Serial Port " + serialPort, System.DateTime.Now); - serialport = new SerialPort(); - serialport.PortName = serialPort; - serialport.BaudRate = this.baudrate; - serialport.Parity = this.parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = 1000; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - serialport.Open(); - } - } - else - while (!shouldStop) - { - if (udpFlag) - { - if (udpClient == null | PortChanged) - { - IPEndPoint localEndoint = new IPEndPoint(LocalIPAddress, port); - udpClient = new UdpClient(localEndoint); - if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); - udpClient.Client.ReceiveTimeout = 1000; - iPEndPoint = new IPEndPoint(IPAddress.Any, port); - PortChanged = false; - } - if (tcpHandler != null) - tcpHandler.Disconnect(); - try - { - bytes = udpClient.Receive(ref iPEndPoint); - portIn = iPEndPoint.Port; - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - networkConnectionParameter.bytes = bytes; - ipAddressIn = iPEndPoint.Address; - networkConnectionParameter.portIn = portIn; - networkConnectionParameter.ipAddressIn = ipAddressIn; - ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); - Thread processDataThread = new Thread(pts); - processDataThread.Start(networkConnectionParameter); - } - catch (Exception) - { - } - } - - } - } - - #region SerialHandler - private bool dataReceived = false; - private byte[] readBuffer = new byte[2094]; - private DateTime lastReceive; - private int nextSign = 0; - private void DataReceivedHandler(object sender, - SerialDataReceivedEventArgs e) - { - int silence = 4000 / baudrate; - if ((DateTime.Now.Ticks - lastReceive.Ticks) > TimeSpan.TicksPerMillisecond*silence) - nextSign = 0; - - - SerialPort sp = (SerialPort)sender; - - int numbytes = sp.BytesToRead; - byte[] rxbytearray = new byte[numbytes]; - - sp.Read(rxbytearray, 0, numbytes); - - Array.Copy(rxbytearray, 0, readBuffer, nextSign, rxbytearray.Length); - lastReceive= DateTime.Now; - nextSign = numbytes+ nextSign; - if (ModbusClient.DetectValidModbusFrame(readBuffer, nextSign)) - { - - dataReceived = true; - nextSign= 0; - - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - networkConnectionParameter.bytes = readBuffer; - ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); - Thread processDataThread = new Thread(pts); - processDataThread.Start(networkConnectionParameter); - dataReceived = false; - - } - else - dataReceived = false; - } - #endregion - - #region Method numberOfClientsChanged - private void numberOfClientsChanged() - { - numberOfConnections = tcpHandler.NumberOfConnectedClients; - if (NumberOfConnectedClientsChanged != null) - NumberOfConnectedClientsChanged(); - } - #endregion - - object lockProcessReceivedData = new object(); - #region Method ProcessReceivedData - private void ProcessReceivedData(object networkConnectionParameter) - { - lock (lockProcessReceivedData) - { - Byte[] bytes = new byte[((NetworkConnectionParameter)networkConnectionParameter).bytes.Length]; - if (debug) StoreLogData.Instance.Store("Received Data: " + BitConverter.ToString(bytes), System.DateTime.Now); - NetworkStream stream = ((NetworkConnectionParameter)networkConnectionParameter).stream; - int portIn = ((NetworkConnectionParameter)networkConnectionParameter).portIn; - IPAddress ipAddressIn = ((NetworkConnectionParameter)networkConnectionParameter).ipAddressIn; - - - Array.Copy(((NetworkConnectionParameter)networkConnectionParameter).bytes, 0, bytes, 0, ((NetworkConnectionParameter)networkConnectionParameter).bytes.Length); - - ModbusProtocol receiveDataThread = new ModbusProtocol(); - ModbusProtocol sendDataThread = new ModbusProtocol(); - - try - { - UInt16[] wordData = new UInt16[1]; - byte[] byteData = new byte[2]; - receiveDataThread.timeStamp = DateTime.Now; - receiveDataThread.request = true; - if (!serialFlag) - { - //Lese Transaction identifier - byteData[1] = bytes[0]; - byteData[0] = bytes[1]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.transactionIdentifier = wordData[0]; - - //Lese Protocol identifier - byteData[1] = bytes[2]; - byteData[0] = bytes[3]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.protocolIdentifier = wordData[0]; - - //Lese length - byteData[1] = bytes[4]; - byteData[0] = bytes[5]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.length = wordData[0]; - } - - //Lese unit identifier - receiveDataThread.unitIdentifier = bytes[6 - 6 * Convert.ToInt32(serialFlag)]; - //Check UnitIdentifier - if ((receiveDataThread.unitIdentifier != this.unitIdentifier) & (receiveDataThread.unitIdentifier != 0)) - return; - - // Lese function code - receiveDataThread.functionCode = bytes[7 - 6 * Convert.ToInt32(serialFlag)]; - - // Lese starting address - byteData[1] = bytes[8 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[9 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAdress = wordData[0]; - - if (receiveDataThread.functionCode <= 4) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - } - if (receiveDataThread.functionCode == 5) - { - receiveDataThread.receiveCoilValues = new ushort[1]; - // Lese Value - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveCoilValues, 0, 2); - } - if (receiveDataThread.functionCode == 6) - { - receiveDataThread.receiveRegisterValues = new ushort[1]; - // Lese Value - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, 0, 2); - } - if (receiveDataThread.functionCode == 15) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - - receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - - if ((receiveDataThread.byteCount % 2) != 0) - receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2 + 1]; - else - receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2]; - // Lese Value - Buffer.BlockCopy(bytes, 13 - 6 * Convert.ToInt32(serialFlag), receiveDataThread.receiveCoilValues, 0, receiveDataThread.byteCount); - } - if (receiveDataThread.functionCode == 16) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - - receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantity]; - for (int i = 0; i < receiveDataThread.quantity; i++) - { - // Lese Value - byteData[1] = bytes[13 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[14 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); - } - - } - if (receiveDataThread.functionCode == 23) - { - // Lese starting Address Read - byteData[1] = bytes[8 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[9 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAddressRead = wordData[0]; - // Lese quantity Read - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantityRead = wordData[0]; - // Lese starting Address Write - byteData[1] = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[13 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAddressWrite = wordData[0]; - // Lese quantity Write - byteData[1] = bytes[14 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[15 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantityWrite = wordData[0]; - - receiveDataThread.byteCount = bytes[16 - 6 * Convert.ToInt32(serialFlag)]; - receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantityWrite]; - for (int i = 0; i < receiveDataThread.quantityWrite; i++) - { - // Lese Value - byteData[1] = bytes[17 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[18 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); - } - } - } - catch (Exception exc) - { } - this.CreateAnswer(receiveDataThread, sendDataThread, stream, portIn, ipAddressIn); - //this.sendAnswer(); - this.CreateLogData(receiveDataThread, sendDataThread); - - if (LogDataChanged != null) - LogDataChanged(); - } - } - #endregion - - #region Method CreateAnswer - private void CreateAnswer(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - - switch (receiveData.functionCode) - { - // Read Coils - case 1: - if (!FunctionCode1Disabled) - this.ReadCoils(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - break; - // Read Input Registers - case 2: - if (!FunctionCode2Disabled) - this.ReadDiscreteInputs(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Read Holding Registers - case 3: - if (!FunctionCode3Disabled) - this.ReadHoldingRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Read Input Registers - case 4: - if (!FunctionCode4Disabled) - this.ReadInputRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write single coil - case 5: - if (!FunctionCode5Disabled) - this.WriteSingleCoil(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write single register - case 6: - if (!FunctionCode6Disabled) - this.WriteSingleRegister(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write Multiple coils - case 15: - if (!FunctionCode15Disabled) - this.WriteMultipleCoils(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write Multiple registers - case 16: - if (!FunctionCode16Disabled) - this.WriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Error: Function Code not supported - case 23: - if (!FunctionCode23Disabled) - this.ReadWriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Error: Function Code not supported - default: sendData.errorCode = (byte) (receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - break; - } - sendData.timeStamp = DateTime.Now; - } - #endregion - - private void ReadCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if ((receiveData.quantity % 8) == 0) - sendData.byteCount = (byte)(receiveData.quantity / 8); - else - sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); - - sendData.sendCoilValues = new bool[receiveData.quantity]; - lock (lockCoils) - Array.Copy(coils.localArray, receiveData.startingAdress + 1, sendData.sendCoilValues, 0, receiveData.quantity); - } - if (true) - { - Byte[] data; - - if (sendData.exceptionCode > 0) - data = new byte[9 + 2*Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount+ 2*Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendCoilValues = null; - } - - if (sendData.sendCoilValues != null) - for (int i = 0; i < (sendData.byteCount); i++) - { - byteData = new byte[2]; - for (int j = 0; j < 8; j++) - { - - byte boolValue; - if (sendData.sendCoilValues[i * 8 + j] == true) - boolValue = 1; - else - boolValue = 0; - byteData[1] = (byte)((byteData[1]) | (boolValue << j)); - if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) - break; - } - data[9 + i] = byteData[1]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadDiscreteInputs(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if ((receiveData.quantity % 8) == 0) - sendData.byteCount = (byte)(receiveData.quantity / 8); - else - sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); - - sendData.sendCoilValues = new bool[receiveData.quantity]; - Array.Copy(discreteInputs.localArray, receiveData.startingAdress + 1, sendData.sendCoilValues, 0, receiveData.quantity); - } - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendCoilValues = null; - } - - if (sendData.sendCoilValues != null) - for (int i = 0; i < (sendData.byteCount); i++) - { - byteData = new byte[2]; - for (int j = 0; j < 8; j++) - { - - byte boolValue; - if (sendData.sendCoilValues[i * 8 + j] == true) - boolValue = 1; - else - boolValue = 0; - byteData[1] = (byte)((byteData[1]) | (boolValue << j)); - if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) - break; - } - data[9 + i] = byteData[1]; - } - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if(debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadHoldingRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.byteCount = (byte)(2 * receiveData.quantity); - sendData.sendRegisterValues = new Int16[receiveData.quantity]; - lock (lockHoldingRegisters) - Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAdress * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - - - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadInputRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.byteCount = (byte)(2 * receiveData.quantity); - sendData.sendRegisterValues = new Int16[receiveData.quantity]; - Buffer.BlockCopy(inputRegisters.localArray, receiveData.startingAdress * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - - - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void WriteSingleCoil(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.receiveCoilValues = receiveData.receiveCoilValues; - if ((receiveData.receiveCoilValues[0] != 0x0000) & (receiveData.receiveCoilValues[0] != 0xFF00)) //Invalid Value - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if (receiveData.receiveCoilValues[0] == 0xFF00) - { - lock (lockCoils) - coils[receiveData.startingAdress + 1] = true; - } - if (receiveData.receiveCoilValues[0] == 0x0000) - { - lock (lockCoils) - coils[receiveData.startingAdress + 1] = false; - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.receiveCoilValues[0]); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (CoilsChanged != null) - CoilsChanged(receiveData.startingAdress+1, 1); - } - } - - private void WriteSingleRegister(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.receiveRegisterValues = receiveData.receiveRegisterValues; - - if ((receiveData.receiveRegisterValues[0] < 0x0000) | (receiveData.receiveRegisterValues[0] > 0xFFFF)) //Invalid Value - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockHoldingRegisters) - holdingRegisters[receiveData.startingAdress + 1] = unchecked((short)receiveData.receiveRegisterValues[0]); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.receiveRegisterValues[0]); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAdress+1, 1); - } - } - - private void WriteMultipleCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.quantity = receiveData.quantity; - - if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAdress + 1 + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockCoils) - for (int i = 0; i < receiveData.quantity; i++) - { - int shift = i % 16; - /* if ((i == receiveData.quantity - 1) & (receiveData.quantity % 2 != 0)) - { - if (shift < 8) - shift = shift + 8; - else - shift = shift - 8; - }*/ - int mask = 0x1; - mask = mask << (shift); - if ((receiveData.receiveCoilValues[i / 16] & (ushort)mask) == 0) - - coils[receiveData.startingAdress + i + 1] = false; - else - - coils[receiveData.startingAdress + i + 1] = true; - - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.quantity); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (CoilsChanged != null) - CoilsChanged(receiveData.startingAdress+1, receiveData.quantity); - } - } - - private void WriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.quantity = receiveData.quantity; - - if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAdress + 1 + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockHoldingRegisters) - for (int i = 0; i < receiveData.quantity; i++) - { - holdingRegisters[receiveData.startingAdress + i + 1] = unchecked((short)receiveData.receiveRegisterValues[i]); - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.quantity); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAdress+1, receiveData.quantity); - } - } - - private void ReadWriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - - - if ((receiveData.quantityRead < 0x0001) | (receiveData.quantityRead > 0x007D) | (receiveData.quantityWrite < 0x0001) | (receiveData.quantityWrite > 0x0079) | (receiveData.byteCount != (receiveData.quantityWrite * 2))) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAddressRead + 1 + (int)receiveData.quantityRead) > 65535) | (((int)receiveData.startingAddressWrite + 1 + (int)receiveData.quantityWrite) > 65535) | (receiveData.quantityWrite < 0) | (receiveData.quantityRead < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.sendRegisterValues = new Int16[receiveData.quantityRead]; - lock (lockHoldingRegisters) - Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAddressRead * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantityRead * 2); - - lock (holdingRegisters) - for (int i = 0; i < receiveData.quantityWrite; i++) - { - holdingRegisters[receiveData.startingAddressWrite + i + 1] = unchecked((short)receiveData.receiveRegisterValues[i]); - } - sendData.byteCount = (byte)(2 * receiveData.quantityRead); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = Convert.ToUInt16(3 + 2 * receiveData.quantityRead); - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAddressWrite+1, receiveData.quantityWrite); - } - } - - private void sendException(int errorCode, int exceptionCode, ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = receiveData.unitIdentifier; - sendData.errorCode = (byte)errorCode; - sendData.exceptionCode = (byte)exceptionCode; - - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void CreateLogData(ModbusProtocol receiveData, ModbusProtocol sendData) - { - for (int i = 0; i < 98; i++) - { - modbusLogData[99 - i] = modbusLogData[99 - i - 2]; - - } - modbusLogData[0] = receiveData; - modbusLogData[1] = sendData; - - } - - - - public int NumberOfConnections - { - get - { - return numberOfConnections; - } - } - - public ModbusProtocol[] ModbusLogData - { - get - { - return modbusLogData; - } - } - - public int Port - { - get - { - return port; - } - set - { - port = value; - - - } - } - - public bool UDPFlag - { - get - { - return udpFlag; - } - set - { - udpFlag = value; - } - } - - public bool SerialFlag - { - get - { - return serialFlag; - } - set - { - serialFlag = value; - } - } - - public int Baudrate - { - get - { - return baudrate; - } - set - { - baudrate = value; - } - } - - public System.IO.Ports.Parity Parity - { - get - { - return parity; - } - set - { - parity = value; - } - } - - public System.IO.Ports.StopBits StopBits - { - get - { - return stopBits; - } - set - { - stopBits = value; - } - } - - public string SerialPort - { - get - { - return serialPort; - } - set - { - serialPort = value; - if (serialPort != null) - serialFlag = true; - else - serialFlag = false; - } - } - - public byte UnitIdentifier - { - get - { - return unitIdentifier; - } - set - { - unitIdentifier = value; - } - } - - - - - /// - /// Gets or Sets the Filename for the LogFile - /// - public string LogFileFilename - { - get - { - return StoreLogData.Instance.Filename; - } - set - { - StoreLogData.Instance.Filename = value; - if (StoreLogData.Instance.Filename != null) - debug = true; - else - debug = false; - } - } - - - - - public class HoldingRegisters - { - public Int16[] localArray = new Int16[65535]; - ModbusServer modbusServer; - - public HoldingRegisters(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public Int16 this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class InputRegisters - { - public Int16[] localArray = new Int16[65535]; - ModbusServer modbusServer; - - public InputRegisters(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public Int16 this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class Coils - { - public bool[] localArray = new bool[65535]; - ModbusServer modbusServer; - - public Coils(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public bool this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class DiscreteInputs - { - public bool[] localArray = new bool[65535]; - ModbusServer modbusServer; - - public DiscreteInputs(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public bool this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - - - } - } -} - \ No newline at end of file diff --git a/EasyModbus/bin/Release/EasyModbus.dll b/EasyModbus/bin/Release/EasyModbus.dll new file mode 100644 index 0000000..f1c2e3d Binary files /dev/null and b/EasyModbus/bin/Release/EasyModbus.dll differ diff --git a/EasyModbusAdvancedClient/AddConnectionForm.Designer.cs b/EasyModbusAdvancedClient/AddConnectionForm.Designer.cs deleted file mode 100644 index 1fac5c1..0000000 --- a/EasyModbusAdvancedClient/AddConnectionForm.Designer.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Created by SharpDevelop. - * User: srossmann - * Date: 25.11.2015 - * Time: 07:35 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -namespace EasyModbusAdvancedClient -{ - partial class AddConnectionForm - { - /// - /// Designer variable used to keep track of non-visual components. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Disposes resources used by the form. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) { - if (components != null) { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - /// - /// This method is required for Windows Forms designer support. - /// Do not change the method contents inside the source code editor. The Forms designer might - /// not be able to load this method if it was changed manually. - /// - private void InitializeComponent() - { - this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); - this.button1 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // propertyGrid1 - // - this.propertyGrid1.Location = new System.Drawing.Point(2, 12); - this.propertyGrid1.Name = "propertyGrid1"; - this.propertyGrid1.Size = new System.Drawing.Size(383, 318); - this.propertyGrid1.TabIndex = 0; - // - // button1 - // - this.button1.Location = new System.Drawing.Point(298, 349); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); - this.button1.TabIndex = 1; - this.button1.Text = "OK"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1Click); - // - // button2 - // - this.button2.Location = new System.Drawing.Point(12, 349); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(75, 23); - this.button2.TabIndex = 2; - this.button2.Text = "Cancel"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.Button2Click); - // - // AddConnectionForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(386, 384); - this.Controls.Add(this.button2); - this.Controls.Add(this.button1); - this.Controls.Add(this.propertyGrid1); - this.Name = "AddConnectionForm"; - this.Text = "Add Connection"; - this.ResumeLayout(false); - - } - private System.Windows.Forms.Button button2; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.PropertyGrid propertyGrid1; - } -} diff --git a/EasyModbusAdvancedClient/AddConnectionForm.cs b/EasyModbusAdvancedClient/AddConnectionForm.cs deleted file mode 100644 index a430b1b..0000000 --- a/EasyModbusAdvancedClient/AddConnectionForm.cs +++ /dev/null @@ -1,211 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Drawing; -using System.ComponentModel; -using System.Windows.Forms; - -namespace EasyModbusAdvancedClient -{ - /// - /// Description of AddConnectionForm. - /// - public partial class AddConnectionForm : Form - { - private EasyModbusManager easyModbusManager; - private ConnectionProperties connectionProperties = new ConnectionProperties(); - private bool editMode = false; - private int indexToEdit; - public AddConnectionForm(EasyModbusManager easyModbusManager) - { - // - // The InitializeComponent() call is required for Windows Forms designer support. - // - this.easyModbusManager = easyModbusManager; - InitializeComponent(); - connectionProperties.ConnectionName = "Connection #"+(easyModbusManager.connectionPropertiesList.Count+1).ToString(); - propertyGrid1.SelectedObject = connectionProperties; - - // - // TODO: Add constructor code after the InitializeComponent() call. - // - } - - public AddConnectionForm(EasyModbusManager easyModbusManager, int indexToEdit) - { - this.easyModbusManager = easyModbusManager; - InitializeComponent(); - connectionProperties.ConnectionName = easyModbusManager.connectionPropertiesList[indexToEdit].ConnectionName; - connectionProperties.CycleTime = easyModbusManager.connectionPropertiesList[indexToEdit].CycleTime; - connectionProperties.CyclicFlag = easyModbusManager.connectionPropertiesList[indexToEdit].CyclicFlag; - connectionProperties.ModbusTCPAddress = easyModbusManager.connectionPropertiesList[indexToEdit].ModbusTCPAddress; - connectionProperties.Port = easyModbusManager.connectionPropertiesList[indexToEdit].Port; - connectionProperties.ComPort = easyModbusManager.connectionPropertiesList[indexToEdit].ComPort; - connectionProperties.SlaveID = easyModbusManager.connectionPropertiesList[indexToEdit].SlaveID; - connectionProperties.ModbusTypeProperty = easyModbusManager.connectionPropertiesList[indexToEdit].ModbusTypeProperty; - connectionProperties.modbusClient = easyModbusManager.connectionPropertiesList[indexToEdit].modbusClient; - propertyGrid1.SelectedObject = connectionProperties; - editMode = true; - this.indexToEdit = indexToEdit; - } - - void Button2Click(object sender, EventArgs e) - { - this.Close(); - } - - void Button1Click(object sender, EventArgs e) - { - try - { - if (!editMode) - { - easyModbusManager.AddConnection(connectionProperties); - } - else - easyModbusManager.EditConnection(connectionProperties, indexToEdit); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Adding connection", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - public enum ModbusType - { - ModbusTCP = 0, - ModbusRTU = 1 - } - - public class ConnectionProperties - { - - ModbusType modbusType; - - [Browsable(true)] - [Category("Modbus Type")] - [Description("Modbus TCP or Modbus RTU")] - [DisplayName("Modbus Type")] - public ModbusType ModbusTypeProperty - { - get { return modbusType; } - set { modbusType = value; } - } - - string connectionName = "Connection #1"; - - [Browsable(true)] - [Category("Connection properties")] - [Description("Unique Connection Name")] - [DisplayName("Connection Name")] - public string ConnectionName - { - get { return connectionName; } - set { connectionName = value; } - } - - string modbusTCPAddress = "127.0.0.1"; - - [Browsable(true)] - [Category("Connection properties")] - [Description("IP-Address of Modbus-TCP Server")] - [DisplayName("IP Address of Modbus-TCP Server")] - public string ModbusTCPAddress - { - get { return modbusTCPAddress; } - set { modbusTCPAddress = value; } - } - - - int port = 502; - [Browsable(true)] - [Category("Connection properties")] - [Description("Port")] - [DisplayName("Port")] - public int Port - { - get { return port; } - set { port = value; } - } - - string comPort = "COM1"; - [Browsable(true)] - [Category("Connection properties")] - [Description("Serial COM-Port")] - [DisplayName("Serial COM-Port")] - public string ComPort - { - get { return comPort; } - set { comPort = value; } - } - - int slaveID = 1; - [Browsable(true)] - [Category("Connection properties")] - [Description("Slave ID")] - [DisplayName("Slave ID")] - public int SlaveID - { - get { return slaveID; } - set { slaveID = value; } - } - - - bool cyclicFlag = false; - [Browsable(true)] - [Category("Connection properties")] - [Description("Enable cyclic data exchange")] - [DisplayName("Enable cyclic data exchange")] - public bool CyclicFlag - { - get {return cyclicFlag;} - set {cyclicFlag = value;} - } - - int cycleTime = 100; - [Browsable(true)] - [Category("Connection properties")] - [Description("Cycle time for cyclic data exchange")] - [DisplayName("Cycle time")] - public int CycleTime - { - get {return cycleTime;} - set {cycleTime = value;} - } - - System.Collections.Generic.List functionPropertiesList = new System.Collections.Generic.List(); - [Browsable(false)] - public System.Collections.Generic.List FunctionPropertiesList - { - get { return functionPropertiesList; } - set { functionPropertiesList = value; } - } - - public EasyModbus.ModbusClient modbusClient; - public System.Threading.Timer timer; - } -} - diff --git a/EasyModbusAdvancedClient/AddConnectionForm.resx b/EasyModbusAdvancedClient/AddConnectionForm.resx deleted file mode 100644 index 1af7de1..0000000 --- a/EasyModbusAdvancedClient/AddConnectionForm.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/EasyModbusAdvancedClient/AddFunctionCodeForm.Designer.cs b/EasyModbusAdvancedClient/AddFunctionCodeForm.Designer.cs deleted file mode 100644 index ae7270f..0000000 --- a/EasyModbusAdvancedClient/AddFunctionCodeForm.Designer.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Created by SharpDevelop. - * User: srossmann - * Date: 26.11.2015 - * Time: 06:55 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -namespace EasyModbusAdvancedClient -{ - partial class AddFunctionCodeForm - { - /// - /// Designer variable used to keep track of non-visual components. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Disposes resources used by the form. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) { - if (components != null) { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - /// - /// This method is required for Windows Forms designer support. - /// Do not change the method contents inside the source code editor. The Forms designer might - /// not be able to load this method if it was changed manually. - /// - private void InitializeComponent() - { - this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); - this.button2 = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // propertyGrid1 - // - this.propertyGrid1.Location = new System.Drawing.Point(2, 12); - this.propertyGrid1.Name = "propertyGrid1"; - this.propertyGrid1.Size = new System.Drawing.Size(383, 318); - this.propertyGrid1.TabIndex = 0; - // - // button2 - // - this.button2.Location = new System.Drawing.Point(13, 349); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(75, 23); - this.button2.TabIndex = 4; - this.button2.Text = "Cancel"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.Button2Click); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(299, 349); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); - this.button1.TabIndex = 3; - this.button1.Text = "OK"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1Click); - // - // AddFunctionCodeForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(386, 384); - this.Controls.Add(this.button2); - this.Controls.Add(this.button1); - this.Controls.Add(this.propertyGrid1); - this.Name = "AddFunctionCodeForm"; - this.Text = "Add Function Code"; - this.ResumeLayout(false); - - } - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.PropertyGrid propertyGrid1; - } -} diff --git a/EasyModbusAdvancedClient/AddFunctionCodeForm.cs b/EasyModbusAdvancedClient/AddFunctionCodeForm.cs deleted file mode 100644 index 64d7283..0000000 --- a/EasyModbusAdvancedClient/AddFunctionCodeForm.cs +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Drawing; -using System.Windows.Forms; - -namespace EasyModbusAdvancedClient -{ - /// - /// Description of AddFunctionCodeForm. - /// - public partial class AddFunctionCodeForm : Form - { - EasyModbusManager easyModbusManager; - int selectedConnection; - private bool editMode = false; - private int indexToEdit; - public AddFunctionCodeForm(EasyModbusManager easyModbusManager, int selectedConnection) - { - this.easyModbusManager = easyModbusManager; - this.selectedConnection = selectedConnection; - InitializeComponent(); - propertyGrid1.SelectedObject = new FunctionProperties(); - } - - public AddFunctionCodeForm(EasyModbusManager easyModbusManager, int selectedConnection, int indexToEdit) - { - this.easyModbusManager = easyModbusManager; - this.selectedConnection = selectedConnection; - InitializeComponent(); - FunctionProperties functionProperty; - functionProperty = easyModbusManager.connectionPropertiesList[selectedConnection].FunctionPropertiesList[indexToEdit]; - propertyGrid1.SelectedObject = functionProperty; - editMode = true; - this.indexToEdit = indexToEdit; - } - - void Button2Click(object sender, EventArgs e) - { - this.Close(); - } - - void Button1Click(object sender, EventArgs e) - { - if (!editMode) - this.easyModbusManager.AddFunctionProperty((FunctionProperties)propertyGrid1.SelectedObject, selectedConnection); - else - this.easyModbusManager.EditFunctionProperty((FunctionProperties)propertyGrid1.SelectedObject, selectedConnection, indexToEdit); - this.Close(); - } - } -} diff --git a/EasyModbusAdvancedClient/AddFunctionCodeForm.resx b/EasyModbusAdvancedClient/AddFunctionCodeForm.resx deleted file mode 100644 index 1af7de1..0000000 --- a/EasyModbusAdvancedClient/AddFunctionCodeForm.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/EasyModbusAdvancedClient/EasyModbusAdvancedClient.csproj b/EasyModbusAdvancedClient/EasyModbusAdvancedClient.csproj deleted file mode 100644 index 77592b0..0000000 --- a/EasyModbusAdvancedClient/EasyModbusAdvancedClient.csproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - {3398AAF9-F5A5-4F3B-9A02-14A6B2359DC4} - Debug - AnyCPU - WinExe - EasyModbusAdvancedClient - EasyModbusAdvancedClient - v4.5 - - - Properties - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - true - bin\DebugCommercial1\ - DEBUG;TRACE - true - Full - x86 - MinimumRecommendedRules.ruleset - false - - - false - TRACE;DEBUG;SSL - - - false - - - - - 3.5 - - - - 3.5 - - - - - - 3.5 - - - - - Exceptions\Exceptions.cs - - - ModbusClient.cs - - - ModbusServer.cs - - - StoreLogData.cs - - - Form - - - AddConnectionForm.cs - - - Form - - - AddFunctionCodeForm.cs - - - - Form - - - MainForm.cs - - - - - True - True - Resources.resx - - - - - AddConnectionForm.cs - - - AddFunctionCodeForm.cs - - - MainForm.Designer.cs - Always - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/EasyModbusAdvancedClient/EasyModbusManager.cs b/EasyModbusAdvancedClient/EasyModbusManager.cs deleted file mode 100644 index 2a7270b..0000000 --- a/EasyModbusAdvancedClient/EasyModbusManager.cs +++ /dev/null @@ -1,553 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.ComponentModel; -using System.Windows.Forms; -using System.Xml.Linq; -using System.Linq; -using System.Xml; -using EasyModbus; - -namespace EasyModbusAdvancedClient -{ - /// - /// Description of EasyModbusManager. - /// - public class EasyModbusManager - { - - EasyModbus.ModbusClient modbusClient = new EasyModbus.ModbusClient(); - public List connectionPropertiesList = new List(); - - public EasyModbusManager() - { - } - - public void AddConnection(ConnectionProperties connectionProperties) - { - foreach (ConnectionProperties connectionProperty in connectionPropertiesList) - { - if (connectionProperties.ConnectionName == connectionProperty.ConnectionName) - { - throw new Exception("Duplicate connection Name detected"); - } - } - - // create modbus client accordingly - if (connectionProperties.ModbusTypeProperty == ModbusType.ModbusTCP) - { - connectionProperties.modbusClient = new EasyModbus.ModbusClient(); - connectionProperties.modbusClient.UnitIdentifier = (byte)connectionProperties.SlaveID; - } - else - { - connectionProperties.modbusClient = new EasyModbus.ModbusClient(connectionProperties.ComPort); - connectionProperties.modbusClient.UnitIdentifier = (byte)connectionProperties.SlaveID; - } - - connectionPropertiesList.Add(connectionProperties); - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - } - - public void RemoveConnection(int connectionNumber) - { - connectionPropertiesList.RemoveAt(connectionNumber); - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - } - - public void EditConnection(ConnectionProperties connectionProperty, int connectionNumber) - { - connectionPropertiesList[connectionNumber] = connectionProperty; - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - foreach (ConnectionProperties connectionPropertyListEntry in connectionPropertiesList) - { - if (connectionPropertyListEntry.ConnectionName == connectionProperty.ConnectionName) - throw new Exception("Duplicate connection Name detcted"); - return; - } - } - - public void AddFunctionProperty(FunctionProperties functionProperty, int connectionNumber) - { - // create link to connection - functionProperty.Connection = connectionPropertiesList[connectionNumber]; - // add to list - connectionPropertiesList[connectionNumber].FunctionPropertiesList.Add(functionProperty); - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - } - - public void RemoveFunctionProperty(int connectionNumber, int functionNumber) - { - connectionPropertiesList[connectionNumber].FunctionPropertiesList.RemoveAt(functionNumber); - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - } - - public void EditFunctionProperty(FunctionProperties functionProperty, int connectionNumber, int functionNumber) - { - connectionPropertiesList[connectionNumber].FunctionPropertiesList[functionNumber] = functionProperty; - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - } - - public delegate void ValuesChanged(object sender); - public event ValuesChanged valuesChanged; - public void GetValues(ConnectionProperties connectionProperties, int functionPropertyID) - { - - modbusClient = connectionProperties.modbusClient; - if (!modbusClient.Connected) - { - modbusClient.IPAddress = connectionProperties.ModbusTCPAddress; - modbusClient.Port = connectionProperties.Port; - modbusClient.Connect(); - } - - switch (connectionProperties.FunctionPropertiesList[functionPropertyID].FunctionCodeRead) - { - case FunctionCodeRd.ReadCoils: - connectionProperties.FunctionPropertiesList[functionPropertyID].values = modbusClient.ReadCoils(connectionProperties.FunctionPropertiesList[functionPropertyID].StartingAdress, connectionProperties.FunctionPropertiesList[functionPropertyID].Quantity); - break; - case FunctionCodeRd.ReadDiscreteInputs: - connectionProperties.FunctionPropertiesList[functionPropertyID].values = modbusClient.ReadDiscreteInputs(connectionProperties.FunctionPropertiesList[functionPropertyID].StartingAdress, connectionProperties.FunctionPropertiesList[functionPropertyID].Quantity); - break; - case FunctionCodeRd.ReadHoldingRegisters: - connectionProperties.FunctionPropertiesList[functionPropertyID].values = modbusClient.ReadHoldingRegisters(connectionProperties.FunctionPropertiesList[functionPropertyID].StartingAdress, connectionProperties.FunctionPropertiesList[functionPropertyID].Quantity); - break; - case FunctionCodeRd.ReadInputRegisters: - connectionProperties.FunctionPropertiesList[functionPropertyID].values = modbusClient.ReadInputRegisters(connectionProperties.FunctionPropertiesList[functionPropertyID].StartingAdress, connectionProperties.FunctionPropertiesList[functionPropertyID].Quantity); - break; - default: break; - } - if (valuesChanged != null) - valuesChanged(this); - } - - public void GetValues(ConnectionProperties connectionProperties) - { - - modbusClient = connectionProperties.modbusClient; - if (!modbusClient.Connected) - { - modbusClient.IPAddress = connectionProperties.ModbusTCPAddress; - modbusClient.Port = connectionProperties.Port; - modbusClient.Connect(); - } - foreach (FunctionProperties functionProperty in connectionProperties.FunctionPropertiesList) - switch (functionProperty.FunctionCodeRead) - { - case FunctionCodeRd.ReadCoils: - functionProperty.values = modbusClient.ReadCoils(functionProperty.StartingAdress, functionProperty.Quantity); - break; - case FunctionCodeRd.ReadDiscreteInputs: - functionProperty.values = modbusClient.ReadDiscreteInputs(functionProperty.StartingAdress, functionProperty.Quantity); - break; - case FunctionCodeRd.ReadHoldingRegisters: - functionProperty.values = modbusClient.ReadHoldingRegisters(functionProperty.StartingAdress, functionProperty.Quantity); - break; - case FunctionCodeRd.ReadInputRegisters: - functionProperty.values = modbusClient.ReadInputRegisters(functionProperty.StartingAdress, functionProperty.Quantity); - break; - default: break; - } - if (valuesChanged != null) - valuesChanged(this); - } - - public delegate void ConnectionPropertiesListChanged(object sender); - public event ConnectionPropertiesListChanged connectionPropertiesListChanged; - - - public static string getAddress(FunctionCodeRd functionCode, int startingAddress, int quantity, int elementCount) - { - string returnValue = null; - if ((startingAddress + elementCount) <= (startingAddress + quantity)) - switch (functionCode) - { - case FunctionCodeRd.ReadCoils: - returnValue = "0x" + (startingAddress + elementCount + 1).ToString(); - break; - case FunctionCodeRd.ReadDiscreteInputs: - returnValue = "1x" + (startingAddress + elementCount + 1).ToString(); - break; - case FunctionCodeRd.ReadHoldingRegisters: - returnValue = "4x" + (startingAddress + elementCount + 1).ToString(); - break; - case FunctionCodeRd.ReadInputRegisters: - returnValue = "3x" + (startingAddress + elementCount + 1).ToString(); - break; - default: break; - } - return returnValue; - } - - public static int[] StrToValues(FunctionProperties functionProperties, string str) - { - int[] values = { }; - switch (functionProperties.FunctionCodeWrite) - { - case FunctionCodeWr.WriteHoldingRegisters: - int value = 0; - if (Int32.TryParse(str, out value)) - { - // add - int[] x = { value }; - return x; - - } - - break; - } - return values; - } - - public FunctionProperties FindPropertyFromGrid( int gridRow) - { - foreach (ConnectionProperties connection in connectionPropertiesList) - { - foreach (FunctionProperties functionProperty in connection.FunctionPropertiesList) - { - if (functionProperty.DataGridRow == gridRow) - { - return functionProperty; - } - } - } - - return null; - } - - public void WriteToServer(FunctionProperties prop, int[] values) - { - /* - string text = ""; - text += "property " + prop.StartingAdress + "\n" + "type " + prop.FunctionCodeWrite.ToString() + "\n" + "new value: " + values.ToString() + "\n"; - text += "connection " + prop.Connection.ConnectionName; - MessageBox.Show(text, "updating register"); - */ - - int startingAddress = prop.StartingAdress; - switch(prop.FunctionCodeWrite) - { - case FunctionCodeWr.WriteHoldingRegisters: - prop.Connection.modbusClient.WriteMultipleRegisters(startingAddress, values); - break; - - } - - - } - - public void WriteXML(DataGridView dataGridView) - { - XmlDocument xmlDocument = new XmlDocument(); - XmlNode xmlRoot; - XmlNode xmlNodeConnection, xmlNodeConnectionProp; - XmlNode xmlNodeFunctionCodes, xmlNodeFunctionCodesProp; - XmlNode xmlNodeDataGrid, xmlNodeDataGridLines, xmlNodeDataGridLinesProp; - xmlRoot = xmlDocument.CreateElement("ModbusConfiguration"); - for (int i = 0; i < this.connectionPropertiesList.Count; i++) - { - xmlNodeConnection = xmlDocument.CreateElement("connection"); - xmlNodeConnectionProp = xmlDocument.CreateElement("connectionName"); - xmlNodeConnectionProp.InnerText = this.connectionPropertiesList[i].ConnectionName; - xmlNodeConnection.AppendChild(xmlNodeConnectionProp); - xmlNodeConnectionProp = xmlDocument.CreateElement("ipAddress"); - xmlNodeConnectionProp.InnerText = this.connectionPropertiesList[i].ModbusTCPAddress; - xmlNodeConnection.AppendChild(xmlNodeConnectionProp); - xmlNodeConnectionProp = xmlDocument.CreateElement("port"); - xmlNodeConnectionProp.InnerText = this.connectionPropertiesList[i].Port.ToString(); - xmlNodeConnection.AppendChild(xmlNodeConnectionProp); - xmlNodeConnectionProp = xmlDocument.CreateElement("cyclicFlag"); - xmlNodeConnectionProp.InnerText = this.connectionPropertiesList[i].CyclicFlag.ToString(); - xmlNodeConnection.AppendChild(xmlNodeConnectionProp); - xmlNodeConnectionProp = xmlDocument.CreateElement("cycleTime"); - xmlNodeConnectionProp.InnerText = this.connectionPropertiesList[i].CycleTime.ToString(); - xmlNodeConnection.AppendChild(xmlNodeConnectionProp); - for (int j = 0; j < this.connectionPropertiesList[i].FunctionPropertiesList.Count; j++) - { - xmlNodeFunctionCodes = xmlDocument.CreateElement("functionCodes"); - xmlNodeFunctionCodesProp = xmlDocument.CreateElement("functionCodeRead"); - xmlNodeFunctionCodesProp.InnerText = this.connectionPropertiesList[i].FunctionPropertiesList[j].FunctionCodeRead.ToString(); - xmlNodeFunctionCodes.AppendChild(xmlNodeFunctionCodesProp); - xmlNodeFunctionCodesProp = xmlDocument.CreateElement("functionCodeWrite"); - xmlNodeFunctionCodesProp.InnerText = this.connectionPropertiesList[i].FunctionPropertiesList[j].FunctionCodeWrite.ToString(); - xmlNodeFunctionCodes.AppendChild(xmlNodeFunctionCodesProp); - xmlNodeFunctionCodesProp = xmlDocument.CreateElement("quantity"); - xmlNodeFunctionCodesProp.InnerText = this.connectionPropertiesList[i].FunctionPropertiesList[j].Quantity.ToString(); - xmlNodeFunctionCodes.AppendChild(xmlNodeFunctionCodesProp); - xmlNodeFunctionCodesProp = xmlDocument.CreateElement("startingAddress"); - xmlNodeFunctionCodesProp.InnerText = this.connectionPropertiesList[i].FunctionPropertiesList[j].StartingAdress.ToString(); - xmlNodeFunctionCodes.AppendChild(xmlNodeFunctionCodesProp); - xmlNodeConnection.AppendChild(xmlNodeFunctionCodes); - } - xmlRoot.AppendChild(xmlNodeConnection); - xmlNodeDataGrid = xmlDocument.CreateElement("dataGridView"); - for (int j = 0; j < dataGridView.Rows.Count; j++) - { - if (dataGridView[0, j].Value != null & dataGridView[1, j].Value != null & dataGridView[3, j].Value != null) - { - xmlNodeDataGridLines = xmlDocument.CreateElement("dataGridViewLines"); - - xmlNodeDataGridLinesProp = xmlDocument.CreateElement("columnConnection"); - xmlNodeDataGridLinesProp.InnerText = dataGridView[0, j].Value.ToString(); - xmlNodeDataGridLines.AppendChild(xmlNodeDataGridLinesProp); - - xmlNodeDataGridLinesProp = xmlDocument.CreateElement("columnAddress"); - xmlNodeDataGridLinesProp.InnerText = dataGridView[1, j].Value.ToString(); - xmlNodeDataGridLines.AppendChild(xmlNodeDataGridLinesProp); - - xmlNodeDataGridLinesProp = xmlDocument.CreateElement("columnTag"); - if (dataGridView[2, j].Value != null) - xmlNodeDataGridLinesProp.InnerText = dataGridView[2, j].Value.ToString(); - else - xmlNodeDataGridLinesProp.InnerText = "n.a."; - xmlNodeDataGridLines.AppendChild(xmlNodeDataGridLinesProp); - - xmlNodeDataGridLinesProp = xmlDocument.CreateElement("columnDataType"); - xmlNodeDataGridLinesProp.InnerText = dataGridView[3, j].Value.ToString(); - xmlNodeDataGridLines.AppendChild(xmlNodeDataGridLinesProp); - - xmlNodeDataGrid.AppendChild(xmlNodeDataGridLines); - } - } - xmlRoot.AppendChild(xmlNodeDataGrid); - - xmlDocument.AppendChild(xmlRoot); - xmlDocument.Save("textWriter.xml"); - } - - - - } - - public delegate void DataGridViewChanged(object sender); - public event DataGridViewChanged dataGridViewChanged; - public void ReadXML(DataGridView dataGridView) - { - XmlNodeList xmlNodeList, xmlNodeList2; - XmlNode xmlNode3; - System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument(); - xmlDocument.Load("textWriter.xml"); - xmlNodeList = xmlDocument.GetElementsByTagName("connection"); - //connectionPropertiesList = new List(); - this.connectionPropertiesList.Clear(); - int slotId = 0; - - foreach (XmlNode xmlNode in xmlNodeList) - { - ConnectionProperties connectionProperty = new ConnectionProperties(); - AddConnection(connectionProperty); - - connectionProperty.ConnectionName = (xmlNode["connectionName"].InnerText); - connectionProperty.ModbusTCPAddress = (xmlNode["ipAddress"].InnerText); - connectionProperty.Port = Int32.Parse(xmlNode["port"].InnerText); - connectionProperty.CyclicFlag = bool.Parse(xmlNode["cyclicFlag"].InnerText); - connectionProperty.CycleTime = Int32.Parse(xmlNode["cycleTime"].InnerText); - xmlNode3 = xmlNode["functionCodes"]; - while (xmlNode3 != null) - { - xmlNodeList2 = xmlNode3.ChildNodes; - FunctionProperties functionProperty = new FunctionProperties(); - - foreach (XmlNode xmlNode2 in xmlNodeList2) - { - if (xmlNode2.Name == "functionCodeRead") - switch (xmlNode2.InnerText) - { - case "ReadCoils": - functionProperty.FunctionCodeRead = FunctionCodeRd.ReadCoils; - break; - case "ReadDiscreteInputs": - functionProperty.FunctionCodeRead = FunctionCodeRd.ReadDiscreteInputs; - break; - case "ReadHoldingRegisters": - functionProperty.FunctionCodeRead = FunctionCodeRd.ReadHoldingRegisters; - break; - case "ReadInputRegisters": - functionProperty.FunctionCodeRead = FunctionCodeRd.ReadInputRegisters; - break; - } - if (xmlNode2.Name == "functionCodeWrite") - { - functionProperty.FunctionCodeWrite = FunctionCodeWr.WriteNone; - switch (xmlNode2.InnerText) - { - case "WriteCoils": - functionProperty.FunctionCodeWrite = FunctionCodeWr.WriteNone; - break; - case "WriteDiscreteInputs": - functionProperty.FunctionCodeWrite = FunctionCodeWr.WriteNone; - break; - case "WriteHoldingRegisters": - functionProperty.FunctionCodeWrite = FunctionCodeWr.WriteHoldingRegisters; - break; - case "WriteInputRegisters": - functionProperty.FunctionCodeWrite = FunctionCodeWr.WriteNone; - break; - } - - } - if (xmlNode2.Name == "startingAddress") - functionProperty.StartingAdress = Int32.Parse(xmlNode2.InnerText); - if (xmlNode2.Name == "quantity") - functionProperty.Quantity = Int32.Parse(xmlNode2.InnerText); - } - //connectionProperty.FunctionPropertiesList.Add(functionProperty); - this.AddFunctionProperty(functionProperty, slotId); - - xmlNode3 = xmlNode3.NextSibling; - } - slotId++; - //this.connectionPropertiesList.Add(connectionProperty); - } - if (connectionPropertiesListChanged != null) - connectionPropertiesListChanged(this); - - xmlNodeList = xmlDocument.GetElementsByTagName("dataGridViewLines"); - dataGridView.Rows.Clear(); - dataGridView.AllowUserToAddRows = false; - foreach (XmlNode xmlNode in xmlNodeList) - { - dataGridView.Rows.Add(); - if (xmlNode["columnConnection"] != null) - dataGridView[0, dataGridView.Rows.Count - 1].Value = xmlNode["columnConnection"].InnerText; - dataGridView.ClearSelection(); - dataGridView.CurrentCell = null; - - if (xmlNode["columnAddress"] != null) - dataGridView[1, dataGridView.Rows.Count - 1].Value = xmlNode["columnAddress"].InnerText; - if (dataGridViewChanged != null) - dataGridViewChanged(this); - if (xmlNode["columnTag"] != null) - dataGridView[2, dataGridView.Rows.Count - 1].Value = xmlNode["columnTag"].InnerText; - if (xmlNode["columnDataType"] != null) - dataGridView[3, dataGridView.Rows.Count - 1].Value = xmlNode["columnDataType"].InnerText; - } - - // trigger update of values manually - //this.valuesChanged(this); - - dataGridView.AllowUserToAddRows = true; - } - } - - - public enum FunctionCodeRd : int - { - ReadCoils = 1, - ReadDiscreteInputs = 2, - ReadHoldingRegisters = 3, - ReadInputRegisters = 4, - }; - - public enum FunctionCodeWr : int - { - WriteNone = 0, - WriteCoils = 1, - WriteDiscreteInputs = 2, - WriteHoldingRegisters = 3, - WriteInputRegisters = 4, - }; - - - public class FunctionProperties - { - - FunctionCodeRd functionCodeRd = FunctionCodeRd.ReadCoils; - [Browsable(true)] - [Category("Function code properties")] - [Description("Function Code Read")] - [DisplayName("Function Code Read")] - public FunctionCodeRd FunctionCodeRead - { - get {return functionCodeRd; } - set { functionCodeRd = value;} - } - - FunctionCodeWr functionCodeWr = FunctionCodeWr.WriteNone; - [Browsable(true)] - [Category("Function code properties")] - [Description("Function Code Write")] - [DisplayName("Function Code Write")] - public FunctionCodeWr FunctionCodeWrite - { - get { return functionCodeWr; } - set { functionCodeWr = value; } - } - - int startingAdress = 0; - [Browsable(true)] - [Category("Function code properties")] - [Description("Starting Address")] - [DisplayName("Starting Address")] - public int StartingAdress - { - get {return startingAdress;} - set {startingAdress = value;} - } - - - int quantity = 1; - [Browsable(true)] - [Category("Function code properties")] - [Description("Quantity")] - [DisplayName("Quantity")] - public int Quantity - { - get {return quantity;} - set {quantity = value;} - } - - int DataGridRowIdx = -1; - [Browsable(false)] - [Category("Function code properties")] - [Description("Data Grid Row Idx")] - [DisplayName("Data Grid Row Idx")] - public int DataGridRow - { - get { return DataGridRowIdx; } - set { DataGridRowIdx = value; } - } - - ConnectionProperties connection= null; - [Browsable(false)] - [Category("Function code properties")] - [Description("connection")] - [DisplayName("connection")] - public ConnectionProperties Connection - { - get { return connection; } - set { connection = value; } - } - - public object values; -} -} diff --git a/EasyModbusAdvancedClient/MainForm.Designer.cs b/EasyModbusAdvancedClient/MainForm.Designer.cs deleted file mode 100644 index b33260c..0000000 --- a/EasyModbusAdvancedClient/MainForm.Designer.cs +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Created by SharpDevelop. - * User: srossmann - * Date: 25.11.2015 - * Time: 06:50 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -namespace EasyModbusAdvancedClient -{ - partial class MainForm - { - /// - /// Designer variable used to keep track of non-visual components. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Disposes resources used by the form. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) { - if (components != null) { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - /// - /// This method is required for Windows Forms designer support. - /// Do not change the method contents inside the source code editor. The Forms designer might - /// not be able to load this method if it was changed manually. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.button9 = new System.Windows.Forms.Button(); - this.button10 = new System.Windows.Forms.Button(); - this.button8 = new System.Windows.Forms.Button(); - this.button7 = new System.Windows.Forms.Button(); - this.button6 = new System.Windows.Forms.Button(); - this.button5 = new System.Windows.Forms.Button(); - this.button4 = new System.Windows.Forms.Button(); - this.button3 = new System.Windows.Forms.Button(); - this.treeView1 = new System.Windows.Forms.TreeView(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.addConnectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.deleteConnectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editConnectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.addFunctionCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.deleteFunctionCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editFunctionCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.startSingleJobToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.stopCurrentJobToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.startAllJobsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.stopAllJobsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.updateValuesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.updateAllValuesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.button2 = new System.Windows.Forms.Button(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.Column5 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column1 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Column4 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.button1 = new System.Windows.Forms.Button(); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.workspaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveWorkspaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.changeWorkspaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.connectionManagerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.addConnectionToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.deleteConnectionToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.editConnectionToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.addFunctionCodeToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.deleteFunctionCodeToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.editFunctionCodeToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.startAllJobsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.stopAllJobsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); - this.updateAllValuessingleReadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - this.contextMenuStrip1.SuspendLayout(); - this.tabControl1.SuspendLayout(); - this.tabPage1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - this.tabPage2.SuspendLayout(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // splitContainer1 - // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(0, 0); - this.splitContainer1.Name = "splitContainer1"; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.button9); - this.splitContainer1.Panel1.Controls.Add(this.button10); - this.splitContainer1.Panel1.Controls.Add(this.button8); - this.splitContainer1.Panel1.Controls.Add(this.button7); - this.splitContainer1.Panel1.Controls.Add(this.button6); - this.splitContainer1.Panel1.Controls.Add(this.button5); - this.splitContainer1.Panel1.Controls.Add(this.button4); - this.splitContainer1.Panel1.Controls.Add(this.button3); - this.splitContainer1.Panel1.Controls.Add(this.treeView1); - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.button2); - this.splitContainer1.Panel2.Controls.Add(this.tabControl1); - this.splitContainer1.Panel2.Controls.Add(this.button1); - this.splitContainer1.Size = new System.Drawing.Size(1284, 742); - this.splitContainer1.SplitterDistance = 409; - this.splitContainer1.TabIndex = 0; - this.splitContainer1.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.SplitContainer1SplitterMoved); - // - // button9 - // - this.button9.Image = ((System.Drawing.Image)(resources.GetObject("button9.Image"))); - this.button9.Location = new System.Drawing.Point(256, 28); - this.button9.Name = "button9"; - this.button9.Size = new System.Drawing.Size(35, 35); - this.button9.TabIndex = 8; - this.button9.UseVisualStyleBackColor = true; - this.button9.Click += new System.EventHandler(this.Button9Click); - // - // button10 - // - this.button10.Image = ((System.Drawing.Image)(resources.GetObject("button10.Image"))); - this.button10.Location = new System.Drawing.Point(220, 28); - this.button10.Name = "button10"; - this.button10.Size = new System.Drawing.Size(35, 35); - this.button10.TabIndex = 7; - this.button10.UseVisualStyleBackColor = true; - this.button10.Click += new System.EventHandler(this.Button10Click); - // - // button8 - // - this.button8.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab; - this.button8.Location = new System.Drawing.Point(184, 28); - this.button8.Name = "button8"; - this.button8.Size = new System.Drawing.Size(35, 35); - this.button8.TabIndex = 5; - this.button8.UseVisualStyleBackColor = true; - this.button8.Click += new System.EventHandler(this.Button8Click); - // - // button7 - // - this.button7.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_close; - this.button7.Location = new System.Drawing.Point(148, 28); - this.button7.Name = "button7"; - this.button7.Size = new System.Drawing.Size(35, 35); - this.button7.TabIndex = 4; - this.button7.UseVisualStyleBackColor = true; - this.button7.Click += new System.EventHandler(this.Button7Click); - // - // button6 - // - this.button6.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_new; - this.button6.Location = new System.Drawing.Point(112, 28); - this.button6.Name = "button6"; - this.button6.Size = new System.Drawing.Size(35, 35); - this.button6.TabIndex = 2; - this.button6.UseVisualStyleBackColor = true; - this.button6.Click += new System.EventHandler(this.Button6Click); - // - // button5 - // - this.button5.Image = ((System.Drawing.Image)(resources.GetObject("button5.Image"))); - this.button5.Location = new System.Drawing.Point(76, 28); - this.button5.Name = "button5"; - this.button5.Size = new System.Drawing.Size(35, 35); - this.button5.TabIndex = 3; - this.button5.UseVisualStyleBackColor = true; - this.button5.Click += new System.EventHandler(this.Button5Click); - // - // button4 - // - this.button4.Image = ((System.Drawing.Image)(resources.GetObject("button4.Image"))); - this.button4.Location = new System.Drawing.Point(40, 28); - this.button4.Name = "button4"; - this.button4.Size = new System.Drawing.Size(35, 35); - this.button4.TabIndex = 2; - this.button4.UseVisualStyleBackColor = true; - this.button4.Click += new System.EventHandler(this.Button4Click); - // - // button3 - // - this.button3.Image = ((System.Drawing.Image)(resources.GetObject("button3.Image"))); - this.button3.Location = new System.Drawing.Point(4, 28); - this.button3.Name = "button3"; - this.button3.Size = new System.Drawing.Size(35, 35); - this.button3.TabIndex = 1; - this.button3.UseVisualStyleBackColor = true; - this.button3.Click += new System.EventHandler(this.Button3Click); - // - // treeView1 - // - this.treeView1.ContextMenuStrip = this.contextMenuStrip1; - this.treeView1.ForeColor = System.Drawing.Color.Black; - this.treeView1.ItemHeight = 16; - this.treeView1.Location = new System.Drawing.Point(3, 69); - this.treeView1.Name = "treeView1"; - this.treeView1.Size = new System.Drawing.Size(403, 670); - this.treeView1.TabIndex = 0; - this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TreeView1AfterSelect); - // - // contextMenuStrip1 - // - this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.addConnectionToolStripMenuItem, - this.deleteConnectionToolStripMenuItem, - this.editConnectionToolStripMenuItem, - this.toolStripSeparator1, - this.addFunctionCodeToolStripMenuItem, - this.deleteFunctionCodeToolStripMenuItem, - this.editFunctionCodeToolStripMenuItem, - this.toolStripSeparator2, - this.startSingleJobToolStripMenuItem, - this.stopCurrentJobToolStripMenuItem, - this.startAllJobsToolStripMenuItem, - this.stopAllJobsToolStripMenuItem, - this.toolStripSeparator3, - this.updateValuesToolStripMenuItem, - this.updateAllValuesToolStripMenuItem}); - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(281, 286); - this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStrip1Opening); - // - // addConnectionToolStripMenuItem - // - this.addConnectionToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("addConnectionToolStripMenuItem.Image"))); - this.addConnectionToolStripMenuItem.Name = "addConnectionToolStripMenuItem"; - this.addConnectionToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.addConnectionToolStripMenuItem.Text = "Add connection"; - this.addConnectionToolStripMenuItem.Click += new System.EventHandler(this.AddConnectionToolStripMenuItemClick); - // - // deleteConnectionToolStripMenuItem - // - this.deleteConnectionToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("deleteConnectionToolStripMenuItem.Image"))); - this.deleteConnectionToolStripMenuItem.Name = "deleteConnectionToolStripMenuItem"; - this.deleteConnectionToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.deleteConnectionToolStripMenuItem.Text = "Delete connection"; - this.deleteConnectionToolStripMenuItem.Visible = false; - this.deleteConnectionToolStripMenuItem.Click += new System.EventHandler(this.DeleteConnectionToolStripMenuItemClick); - // - // editConnectionToolStripMenuItem - // - this.editConnectionToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("editConnectionToolStripMenuItem.Image"))); - this.editConnectionToolStripMenuItem.Name = "editConnectionToolStripMenuItem"; - this.editConnectionToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.editConnectionToolStripMenuItem.Text = "Edit connection"; - this.editConnectionToolStripMenuItem.Visible = false; - this.editConnectionToolStripMenuItem.Click += new System.EventHandler(this.EditConnectionToolStripMenuItemClick); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(277, 6); - this.toolStripSeparator1.Visible = false; - // - // addFunctionCodeToolStripMenuItem - // - this.addFunctionCodeToolStripMenuItem.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_new; - this.addFunctionCodeToolStripMenuItem.Name = "addFunctionCodeToolStripMenuItem"; - this.addFunctionCodeToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.addFunctionCodeToolStripMenuItem.Text = "Add function code"; - this.addFunctionCodeToolStripMenuItem.Visible = false; - this.addFunctionCodeToolStripMenuItem.Click += new System.EventHandler(this.AddFunctionCodeToolStripMenuItemClick); - // - // deleteFunctionCodeToolStripMenuItem - // - this.deleteFunctionCodeToolStripMenuItem.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_close; - this.deleteFunctionCodeToolStripMenuItem.Name = "deleteFunctionCodeToolStripMenuItem"; - this.deleteFunctionCodeToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.deleteFunctionCodeToolStripMenuItem.Text = "Delete function code"; - this.deleteFunctionCodeToolStripMenuItem.Visible = false; - this.deleteFunctionCodeToolStripMenuItem.Click += new System.EventHandler(this.DeleteFunctionCodeToolStripMenuItemClick); - // - // editFunctionCodeToolStripMenuItem - // - this.editFunctionCodeToolStripMenuItem.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab; - this.editFunctionCodeToolStripMenuItem.Name = "editFunctionCodeToolStripMenuItem"; - this.editFunctionCodeToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.editFunctionCodeToolStripMenuItem.Text = "Edit function Code"; - this.editFunctionCodeToolStripMenuItem.Visible = false; - this.editFunctionCodeToolStripMenuItem.Click += new System.EventHandler(this.EditFunctionCodeToolStripMenuItemClick); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(277, 6); - this.toolStripSeparator2.Visible = false; - // - // startSingleJobToolStripMenuItem - // - this.startSingleJobToolStripMenuItem.Name = "startSingleJobToolStripMenuItem"; - this.startSingleJobToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.startSingleJobToolStripMenuItem.Text = "Start current job (continuous read)"; - this.startSingleJobToolStripMenuItem.Visible = false; - this.startSingleJobToolStripMenuItem.Click += new System.EventHandler(this.StartSingleJobToolStripMenuItemClick); - // - // stopCurrentJobToolStripMenuItem - // - this.stopCurrentJobToolStripMenuItem.Name = "stopCurrentJobToolStripMenuItem"; - this.stopCurrentJobToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.stopCurrentJobToolStripMenuItem.Text = "Stop current job"; - this.stopCurrentJobToolStripMenuItem.Visible = false; - this.stopCurrentJobToolStripMenuItem.Click += new System.EventHandler(this.stopCurrentJobToolStripMenuItem_Click); - // - // startAllJobsToolStripMenuItem - // - this.startAllJobsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("startAllJobsToolStripMenuItem.Image"))); - this.startAllJobsToolStripMenuItem.Name = "startAllJobsToolStripMenuItem"; - this.startAllJobsToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.startAllJobsToolStripMenuItem.Text = "Start all jobs (continuous read)"; - this.startAllJobsToolStripMenuItem.Visible = false; - this.startAllJobsToolStripMenuItem.Click += new System.EventHandler(this.StartAllJobsToolStripMenuItemClick); - // - // stopAllJobsToolStripMenuItem - // - this.stopAllJobsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("stopAllJobsToolStripMenuItem.Image"))); - this.stopAllJobsToolStripMenuItem.Name = "stopAllJobsToolStripMenuItem"; - this.stopAllJobsToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.stopAllJobsToolStripMenuItem.Text = "Stop all jobs"; - this.stopAllJobsToolStripMenuItem.Visible = false; - this.stopAllJobsToolStripMenuItem.Click += new System.EventHandler(this.StopAllJobsToolStripMenuItemClick); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(277, 6); - this.toolStripSeparator3.Visible = false; - // - // updateValuesToolStripMenuItem - // - this.updateValuesToolStripMenuItem.Name = "updateValuesToolStripMenuItem"; - this.updateValuesToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.updateValuesToolStripMenuItem.Text = "Update values current job (single read) "; - this.updateValuesToolStripMenuItem.Visible = false; - this.updateValuesToolStripMenuItem.Click += new System.EventHandler(this.UpdateValuesToolStripMenuItemClick); - // - // updateAllValuesToolStripMenuItem - // - this.updateAllValuesToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("updateAllValuesToolStripMenuItem.Image"))); - this.updateAllValuesToolStripMenuItem.Name = "updateAllValuesToolStripMenuItem"; - this.updateAllValuesToolStripMenuItem.Size = new System.Drawing.Size(280, 22); - this.updateAllValuesToolStripMenuItem.Text = "Update all values (single read)"; - this.updateAllValuesToolStripMenuItem.Visible = false; - this.updateAllValuesToolStripMenuItem.Click += new System.EventHandler(this.UpdateAllValuesToolStripMenuItemClick); - // - // button2 - // - this.button2.Image = ((System.Drawing.Image)(resources.GetObject("button2.Image"))); - this.button2.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.button2.Location = new System.Drawing.Point(3, 262); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(63, 58); - this.button2.TabIndex = 2; - this.button2.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.Button2Click); - // - // tabControl1 - // - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Controls.Add(this.tabPage2); - this.tabControl1.Location = new System.Drawing.Point(72, 28); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(787, 702); - this.tabControl1.TabIndex = 2; - // - // tabPage1 - // - this.tabPage1.Controls.Add(this.dataGridView1); - this.tabPage1.Location = new System.Drawing.Point(4, 22); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(779, 676); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "Tag View"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // dataGridView1 - // - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.Column5, - this.Column1, - this.Column2, - this.Column4, - this.Column3}); - this.dataGridView1.Location = new System.Drawing.Point(17, 6); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.Size = new System.Drawing.Size(766, 662); - this.dataGridView1.TabIndex = 0; - this.dataGridView1.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView1CellClick); - this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit); - // - // Column5 - // - this.Column5.HeaderText = "Connection"; - this.Column5.Name = "Column5"; - this.Column5.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.Column5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - this.Column5.Width = 150; - // - // Column1 - // - this.Column1.HeaderText = "Address"; - this.Column1.Name = "Column1"; - this.Column1.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.Column1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - // - // Column2 - // - this.Column2.HeaderText = "Tag (optional)"; - this.Column2.Name = "Column2"; - this.Column2.Width = 200; - // - // Column4 - // - this.Column4.HeaderText = "Datatype"; - this.Column4.Items.AddRange(new object[] { - "BOOL (FALSE...TRUE)", - "INT16 (-32768...32767)", - "UINT16 (0...65535)", - "BOOL (FALSE...TRUE)", - "INT16 (-32768...32767)", - "WORD16 (0...65535)", - "ASCII"}); - this.Column4.Name = "Column4"; - this.Column4.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.Column4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - this.Column4.Width = 150; - // - // Column3 - // - this.Column3.HeaderText = "Value"; - this.Column3.Name = "Column3"; - // - // tabPage2 - // - this.tabPage2.Controls.Add(this.textBox1); - this.tabPage2.Location = new System.Drawing.Point(4, 22); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(779, 676); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "Raw Data View"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // textBox1 - // - this.textBox1.Location = new System.Drawing.Point(4, 4); - this.textBox1.Multiline = true; - this.textBox1.Name = "textBox1"; - this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(769, 666); - this.textBox1.TabIndex = 0; - // - // button1 - // - this.button1.Image = ((System.Drawing.Image)(resources.GetObject("button1.Image"))); - this.button1.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.button1.Location = new System.Drawing.Point(3, 167); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(63, 58); - this.button1.TabIndex = 1; - this.button1.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1Click); - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.workspaceToolStripMenuItem, - this.connectionManagerToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(1284, 24); - this.menuStrip1.TabIndex = 1; - this.menuStrip1.Text = "menuStrip1"; - // - // workspaceToolStripMenuItem - // - this.workspaceToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.saveWorkspaceToolStripMenuItem, - this.changeWorkspaceToolStripMenuItem, - this.loadToolStripMenuItem}); - this.workspaceToolStripMenuItem.Name = "workspaceToolStripMenuItem"; - this.workspaceToolStripMenuItem.Size = new System.Drawing.Size(77, 20); - this.workspaceToolStripMenuItem.Text = "Workspace"; - // - // saveWorkspaceToolStripMenuItem - // - this.saveWorkspaceToolStripMenuItem.Name = "saveWorkspaceToolStripMenuItem"; - this.saveWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(176, 22); - this.saveWorkspaceToolStripMenuItem.Text = "Save Workspace"; - this.saveWorkspaceToolStripMenuItem.Click += new System.EventHandler(this.saveWorkspaceToolStripMenuItem_Click); - // - // changeWorkspaceToolStripMenuItem - // - this.changeWorkspaceToolStripMenuItem.Name = "changeWorkspaceToolStripMenuItem"; - this.changeWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(176, 22); - this.changeWorkspaceToolStripMenuItem.Text = "Change Workspace"; - // - // loadToolStripMenuItem - // - this.loadToolStripMenuItem.Name = "loadToolStripMenuItem"; - this.loadToolStripMenuItem.Size = new System.Drawing.Size(176, 22); - this.loadToolStripMenuItem.Text = "Load"; - this.loadToolStripMenuItem.Click += new System.EventHandler(this.loadToolStripMenuItem_Click); - // - // connectionManagerToolStripMenuItem - // - this.connectionManagerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.addConnectionToolStripMenuItem1, - this.deleteConnectionToolStripMenuItem1, - this.editConnectionToolStripMenuItem1, - this.toolStripSeparator4, - this.addFunctionCodeToolStripMenuItem1, - this.deleteFunctionCodeToolStripMenuItem1, - this.editFunctionCodeToolStripMenuItem1, - this.toolStripSeparator5, - this.startAllJobsToolStripMenuItem1, - this.stopAllJobsToolStripMenuItem1, - this.toolStripSeparator6, - this.updateAllValuessingleReadToolStripMenuItem}); - this.connectionManagerToolStripMenuItem.Name = "connectionManagerToolStripMenuItem"; - this.connectionManagerToolStripMenuItem.Size = new System.Drawing.Size(131, 20); - this.connectionManagerToolStripMenuItem.Text = "Connection Manager"; - // - // addConnectionToolStripMenuItem1 - // - this.addConnectionToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.network_connect; - this.addConnectionToolStripMenuItem1.Name = "addConnectionToolStripMenuItem1"; - this.addConnectionToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.addConnectionToolStripMenuItem1.Text = "Add connection"; - this.addConnectionToolStripMenuItem1.Click += new System.EventHandler(this.AddConnectionToolStripMenuItemClick); - // - // deleteConnectionToolStripMenuItem1 - // - this.deleteConnectionToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.network_disconnect_2; - this.deleteConnectionToolStripMenuItem1.Name = "deleteConnectionToolStripMenuItem1"; - this.deleteConnectionToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.deleteConnectionToolStripMenuItem1.Text = "Delete connection"; - this.deleteConnectionToolStripMenuItem1.Visible = false; - this.deleteConnectionToolStripMenuItem1.Click += new System.EventHandler(this.DeleteConnectionToolStripMenuItemClick); - // - // editConnectionToolStripMenuItem1 - // - this.editConnectionToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.network_connect_2; - this.editConnectionToolStripMenuItem1.Name = "editConnectionToolStripMenuItem1"; - this.editConnectionToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.editConnectionToolStripMenuItem1.Text = "Edit connection"; - this.editConnectionToolStripMenuItem1.Visible = false; - this.editConnectionToolStripMenuItem1.Click += new System.EventHandler(this.EditConnectionToolStripMenuItemClick); - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(232, 6); - this.toolStripSeparator4.Visible = false; - // - // addFunctionCodeToolStripMenuItem1 - // - this.addFunctionCodeToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_new; - this.addFunctionCodeToolStripMenuItem1.Name = "addFunctionCodeToolStripMenuItem1"; - this.addFunctionCodeToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.addFunctionCodeToolStripMenuItem1.Text = "Add function code"; - this.addFunctionCodeToolStripMenuItem1.Visible = false; - this.addFunctionCodeToolStripMenuItem1.Click += new System.EventHandler(this.AddFunctionCodeToolStripMenuItemClick); - // - // deleteFunctionCodeToolStripMenuItem1 - // - this.deleteFunctionCodeToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab_close; - this.deleteFunctionCodeToolStripMenuItem1.Name = "deleteFunctionCodeToolStripMenuItem1"; - this.deleteFunctionCodeToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.deleteFunctionCodeToolStripMenuItem1.Text = "Delete function code"; - this.deleteFunctionCodeToolStripMenuItem1.Visible = false; - this.deleteFunctionCodeToolStripMenuItem1.Click += new System.EventHandler(this.DeleteFunctionCodeToolStripMenuItemClick); - // - // editFunctionCodeToolStripMenuItem1 - // - this.editFunctionCodeToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.tab; - this.editFunctionCodeToolStripMenuItem1.Name = "editFunctionCodeToolStripMenuItem1"; - this.editFunctionCodeToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.editFunctionCodeToolStripMenuItem1.Text = "Edit function code"; - this.editFunctionCodeToolStripMenuItem1.Visible = false; - this.editFunctionCodeToolStripMenuItem1.Click += new System.EventHandler(this.EditFunctionCodeToolStripMenuItemClick); - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(232, 6); - this.toolStripSeparator5.Visible = false; - // - // startAllJobsToolStripMenuItem1 - // - this.startAllJobsToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.view_refresh_2; - this.startAllJobsToolStripMenuItem1.Name = "startAllJobsToolStripMenuItem1"; - this.startAllJobsToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.startAllJobsToolStripMenuItem1.Text = "Start all jobs (continuous read)"; - this.startAllJobsToolStripMenuItem1.Visible = false; - this.startAllJobsToolStripMenuItem1.Click += new System.EventHandler(this.StartAllJobsToolStripMenuItemClick); - // - // stopAllJobsToolStripMenuItem1 - // - this.stopAllJobsToolStripMenuItem1.Image = global::EasyModbusAdvancedClient.Properties.Resources.process_stop_2; - this.stopAllJobsToolStripMenuItem1.Name = "stopAllJobsToolStripMenuItem1"; - this.stopAllJobsToolStripMenuItem1.Size = new System.Drawing.Size(235, 22); - this.stopAllJobsToolStripMenuItem1.Text = "Stop all jobs"; - this.stopAllJobsToolStripMenuItem1.Visible = false; - this.stopAllJobsToolStripMenuItem1.Click += new System.EventHandler(this.StopAllJobsToolStripMenuItemClick); - // - // toolStripSeparator6 - // - this.toolStripSeparator6.Name = "toolStripSeparator6"; - this.toolStripSeparator6.Size = new System.Drawing.Size(232, 6); - this.toolStripSeparator6.Visible = false; - // - // updateAllValuessingleReadToolStripMenuItem - // - this.updateAllValuessingleReadToolStripMenuItem.Name = "updateAllValuessingleReadToolStripMenuItem"; - this.updateAllValuessingleReadToolStripMenuItem.Size = new System.Drawing.Size(235, 22); - this.updateAllValuessingleReadToolStripMenuItem.Text = "Update all Values (single read)"; - this.updateAllValuessingleReadToolStripMenuItem.Visible = false; - this.updateAllValuessingleReadToolStripMenuItem.Click += new System.EventHandler(this.UpdateAllValuesToolStripMenuItemClick); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1284, 742); - this.Controls.Add(this.menuStrip1); - this.Controls.Add(this.splitContainer1); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MainMenuStrip = this.menuStrip1; - this.Name = "MainForm"; - this.Text = "EasyModbus Advanced Client"; - this.WindowState = System.Windows.Forms.FormWindowState.Maximized; - this.SizeChanged += new System.EventHandler(this.MainFormSizeChanged); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.contextMenuStrip1.ResumeLayout(false); - this.tabControl1.ResumeLayout(false); - this.tabPage1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - this.tabPage2.ResumeLayout(false); - this.tabPage2.PerformLayout(); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - - private System.Windows.Forms.ToolStripMenuItem deleteConnectionToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editConnectionToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem deleteFunctionCodeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editFunctionCodeToolStripMenuItem; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.ToolStripMenuItem updateAllValuesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem updateValuesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem startAllJobsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem startSingleJobToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem addFunctionCodeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem addConnectionToolStripMenuItem; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; - private System.Windows.Forms.TreeView treeView1; - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.Button button6; - private System.Windows.Forms.Button button5; - private System.Windows.Forms.Button button4; - private System.Windows.Forms.Button button10; - private System.Windows.Forms.Button button9; - private System.Windows.Forms.Button button8; - private System.Windows.Forms.Button button7; - private System.Windows.Forms.ToolStripMenuItem stopCurrentJobToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem stopAllJobsToolStripMenuItem; - private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem workspaceToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveWorkspaceToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem changeWorkspaceToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem connectionManagerToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem addConnectionToolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem deleteConnectionToolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem editConnectionToolStripMenuItem1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; - private System.Windows.Forms.ToolStripMenuItem addFunctionCodeToolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem deleteFunctionCodeToolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem editFunctionCodeToolStripMenuItem1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem startAllJobsToolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem stopAllJobsToolStripMenuItem1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; - private System.Windows.Forms.ToolStripMenuItem updateAllValuessingleReadToolStripMenuItem; - - - - void ContextMenuStrip1Opening(object sender, System.ComponentModel.CancelEventArgs e) - { - - } - - void AddConnectionToolStripMenuItemClick(object sender, System.EventArgs e) - { - AddConnectionForm addConnectionForm = new AddConnectionForm(easyModbusManager); - addConnectionForm.ShowDialog(); - } - - private System.Windows.Forms.DataGridViewComboBoxColumn Column5; - private System.Windows.Forms.DataGridViewComboBoxColumn Column1; - private System.Windows.Forms.DataGridViewTextBoxColumn Column2; - private System.Windows.Forms.DataGridViewComboBoxColumn Column4; - private System.Windows.Forms.DataGridViewTextBoxColumn Column3; - private System.Windows.Forms.ToolStripMenuItem loadToolStripMenuItem; - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.TextBox textBox1; - } -} - - diff --git a/EasyModbusAdvancedClient/MainForm.cs b/EasyModbusAdvancedClient/MainForm.cs deleted file mode 100644 index 98e5a65..0000000 --- a/EasyModbusAdvancedClient/MainForm.cs +++ /dev/null @@ -1,789 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows.Forms; - -namespace EasyModbusAdvancedClient -{ - /// - /// Description of MainForm. - /// - public partial class MainForm : Form - { - EasyModbusManager easyModbusManager = new EasyModbusManager(); - public MainForm() - { - - // - // The InitializeComponent() call is required for Windows Forms designer support. - // - InitializeComponent(); - easyModbusManager.connectionPropertiesListChanged += new EasyModbusManager.ConnectionPropertiesListChanged(UpdateListBox); - easyModbusManager.valuesChanged += new EasyModbusManager.ValuesChanged(UpdateDataGridView); - //*************************************************create tooltips - ToolTip toolTip1 = new ToolTip(); - toolTip1.AutoPopDelay=5000; - toolTip1.InitialDelay=100; - toolTip1.ReshowDelay=500; - toolTip1.ShowAlways=true; - toolTip1.SetToolTip(this.button3, "Add connection"); - - ToolTip toolTip2 = new ToolTip(); - toolTip2.AutoPopDelay=5000; - toolTip2.InitialDelay=100; - toolTip2.ReshowDelay=500; - toolTip2.ShowAlways=true; - toolTip2.SetToolTip(this.button4, "Remove connection"); - - ToolTip toolTip3 = new ToolTip(); - toolTip3.AutoPopDelay=5000; - toolTip3.InitialDelay=100; - toolTip3.ReshowDelay=500; - toolTip3.ShowAlways=true; - toolTip3.SetToolTip(this.button5, "Edit connection"); - - ToolTip toolTip4 = new ToolTip(); - toolTip4.AutoPopDelay=5000; - toolTip4.InitialDelay=100; - toolTip4.ReshowDelay=500; - toolTip4.ShowAlways=true; - toolTip4.SetToolTip(this.button6, "Add Function code"); - - ToolTip toolTip5 = new ToolTip(); - toolTip5.AutoPopDelay=5000; - toolTip5.InitialDelay=100; - toolTip5.ReshowDelay=500; - toolTip5.ShowAlways=true; - toolTip5.SetToolTip(this.button7, "Remove Function code"); - - ToolTip toolTip6 = new ToolTip(); - toolTip6.AutoPopDelay=5000; - toolTip6.InitialDelay=100; - toolTip6.ReshowDelay=500; - toolTip6.ShowAlways=true; - toolTip6.SetToolTip(this.button8, "Edit Function code"); - - - ToolTip toolTip7 = new ToolTip(); - toolTip7.AutoPopDelay=5000; - toolTip7.InitialDelay=100; - toolTip7.ReshowDelay=500; - toolTip7.ShowAlways=true; - toolTip7.SetToolTip(this.button9, "Stop all jobs"); - - ToolTip toolTip8 = new ToolTip(); - toolTip8.AutoPopDelay=5000; - toolTip8.InitialDelay=100; - toolTip8.ReshowDelay=500; - toolTip8.ShowAlways=true; - toolTip8.SetToolTip(this.button10, "Start all jobs (continuous reading)"); - } - - - private void UpdateListBox(object sender) - { - treeView1.Nodes.Clear(); - TreeNode rootNode = new TreeNode("Modbus connections"); - treeView1.Nodes.Add(rootNode); - foreach (ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - { - TreeNode treeNode = null; - if (connectionProperty.ModbusTypeProperty == ModbusType.ModbusTCP) - treeNode = new TreeNode("Modbus-TCP Connection: " + connectionProperty.ConnectionName +"; IP-Address: "+connectionProperty.ModbusTCPAddress + "; Port: "+connectionProperty.Port); - else - treeNode = new TreeNode("Modbus-RTU Connection: " + connectionProperty.ConnectionName +"; COM-Port: "+connectionProperty.ComPort); - foreach (FunctionProperties functionProperty in connectionProperty.FunctionPropertiesList) - { - treeNode.Nodes.Add("Function code: " + functionProperty.FunctionCodeRead + "; Starting Address: "+functionProperty.StartingAdress + "; Quantity: "+functionProperty.Quantity); - } - rootNode.Nodes.Add(treeNode); - - } - treeView1.ExpandAll(); - this.UpdateDataGridViewItems(); - - } - - private void UpdateDataGridView(object sender) - { - for (int i = 0; i < dataGridView1.RowCount-1; i++) - { - foreach (ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - { - if (dataGridView1[0,i].Value != null) - if (connectionProperty.ConnectionName.Equals(dataGridView1[0,i].Value.ToString())) - { - foreach (FunctionProperties functionProperty in connectionProperty.FunctionPropertiesList) - { - - if (dataGridView1[1,i].Value != null) - - for (int j = 0; j < functionProperty.Quantity; j++) - if (EasyModbusManager.getAddress(functionProperty.FunctionCodeRead, functionProperty.StartingAdress, functionProperty.Quantity, j).Equals(dataGridView1[1,i].Value.ToString())) - { - functionProperty.DataGridRow = i; - if (functionProperty.values.GetType().Equals(typeof(Boolean[]))) - dataGridView1[4,i].Value=((bool[]) functionProperty.values)[j].ToString(); - else - { - if (dataGridView1[3, i].Value != null) - if (dataGridView1[3, i].Value.Equals("UINT16 (0...65535)")) - if (((int[])functionProperty.values)[j] < 0) - dataGridView1[4, i].Value = (65536 + ((int[])functionProperty.values)[j]).ToString(); - else - dataGridView1[4, i].Value = ((int[])functionProperty.values)[j].ToString(); - else if (dataGridView1[3, i].Value.Equals("ASCII")) - { - - string str = ""; - for (int tt = 0; tt < ((int[])functionProperty.values).Length; tt++) - { - int value = ((int[])functionProperty.values)[tt]; - str += "" + (char)((value & 0xff00) >> 8) + (char)((value & 0x00ff)); - } - dataGridView1[4, i].Value = "" + str; - } - else - dataGridView1[4, i].Value = ((int[])functionProperty.values)[j].ToString(); - else - dataGridView1[4, i].Value = ((int[])functionProperty.values)[j].ToString(); - } - } - } - - } - } - } - } - - - - void TreeView1AfterSelect(object sender, TreeViewEventArgs e) - { - if (treeView1.SelectedNode.Level == 1) - { - //conext menu strip - stopCurrentJobToolStripMenuItem.Visible = true; - stopAllJobsToolStripMenuItem.Visible = true; - startAllJobsToolStripMenuItem.Visible = true; - startSingleJobToolStripMenuItem.Visible = true; - startAllJobsToolStripMenuItem.Visible = true; - startSingleJobToolStripMenuItem.Visible = true; - addFunctionCodeToolStripMenuItem.Visible = true; - deleteConnectionToolStripMenuItem.Visible = true; - editConnectionToolStripMenuItem.Visible = true; - addConnectionToolStripMenuItem.Visible = true; - deleteFunctionCodeToolStripMenuItem.Visible = false; - editFunctionCodeToolStripMenuItem.Visible = false; - updateAllValuesToolStripMenuItem.Visible = true; - updateValuesToolStripMenuItem.Visible = true; - toolStripSeparator1.Visible = true; - toolStripSeparator2.Visible = true; - toolStripSeparator3.Visible = true; - //tool strip - addConnectionToolStripMenuItem1.Visible = true; - editConnectionToolStripMenuItem1.Visible = true; - deleteConnectionToolStripMenuItem1.Visible = true; - addFunctionCodeToolStripMenuItem1.Visible = true; - editFunctionCodeToolStripMenuItem1.Visible = false; - deleteFunctionCodeToolStripMenuItem1.Visible = false; - startAllJobsToolStripMenuItem1.Visible = true; - stopAllJobsToolStripMenuItem1.Visible = true; - updateAllValuessingleReadToolStripMenuItem.Visible = true; - toolStripSeparator4.Visible = true; - toolStripSeparator5.Visible = true; - toolStripSeparator6.Visible = true; - - } - else if (treeView1.SelectedNode.Level == 2) - { - stopCurrentJobToolStripMenuItem.Visible = true; - stopAllJobsToolStripMenuItem.Visible = true; - startAllJobsToolStripMenuItem.Visible = true; - startSingleJobToolStripMenuItem.Visible = true; - addConnectionToolStripMenuItem.Visible = true; - editConnectionToolStripMenuItem.Visible = false; - deleteConnectionToolStripMenuItem.Visible = false; - editFunctionCodeToolStripMenuItem.Visible = true; - deleteFunctionCodeToolStripMenuItem.Visible = true; - startAllJobsToolStripMenuItem.Visible = true; - startSingleJobToolStripMenuItem.Visible = true; - updateAllValuesToolStripMenuItem.Visible = true; - updateValuesToolStripMenuItem.Visible = true; - toolStripSeparator1.Visible = true; - toolStripSeparator2.Visible = true; - toolStripSeparator3.Visible = true; - //tool strip - addConnectionToolStripMenuItem1.Visible = true; - editConnectionToolStripMenuItem1.Visible = false; - deleteConnectionToolStripMenuItem1.Visible = false; - addFunctionCodeToolStripMenuItem1.Visible = true; - editFunctionCodeToolStripMenuItem1.Visible = true; - deleteFunctionCodeToolStripMenuItem1.Visible = true; - startAllJobsToolStripMenuItem1.Visible = true; - stopAllJobsToolStripMenuItem1.Visible = true; - updateAllValuessingleReadToolStripMenuItem.Visible = true; - toolStripSeparator4.Visible = true; - toolStripSeparator5.Visible = true; - toolStripSeparator6.Visible = true; - } - else - { - //context menu strip - stopCurrentJobToolStripMenuItem.Visible = false; - stopAllJobsToolStripMenuItem.Visible = false; - startAllJobsToolStripMenuItem.Visible = true; - startSingleJobToolStripMenuItem.Visible = false; - addConnectionToolStripMenuItem.Visible = true; - editConnectionToolStripMenuItem.Visible = false; - deleteConnectionToolStripMenuItem.Visible = false; - addFunctionCodeToolStripMenuItem.Visible = false; - deleteConnectionToolStripMenuItem.Visible = false; - editConnectionToolStripMenuItem.Visible = false; - editFunctionCodeToolStripMenuItem.Visible = false; - deleteFunctionCodeToolStripMenuItem.Visible = false; - startAllJobsToolStripMenuItem.Visible = false; - startSingleJobToolStripMenuItem.Visible = false; - updateAllValuesToolStripMenuItem.Visible = true; - updateValuesToolStripMenuItem.Visible = false; - toolStripSeparator1.Visible = false; - toolStripSeparator2.Visible = false; - toolStripSeparator3.Visible = false; - //tool strip - addConnectionToolStripMenuItem1.Visible = true; - editConnectionToolStripMenuItem1.Visible = false; - deleteConnectionToolStripMenuItem1.Visible = false; - addFunctionCodeToolStripMenuItem1.Visible = false; - editFunctionCodeToolStripMenuItem1.Visible = false; - deleteFunctionCodeToolStripMenuItem1.Visible = false; - startAllJobsToolStripMenuItem1.Visible = true; - stopAllJobsToolStripMenuItem1.Visible = false; - updateAllValuessingleReadToolStripMenuItem.Visible = true; - toolStripSeparator4.Visible = false; - toolStripSeparator5.Visible = false; - toolStripSeparator6.Visible = false; - - } - } - - - - void AddFunctionCodeToolStripMenuItemClick(object sender, EventArgs e) - { - if (treeView1.SelectedNode != null) - { - AddFunctionCodeForm addFunctionCodeForm = new AddFunctionCodeForm(easyModbusManager, treeView1.SelectedNode.Index); - addFunctionCodeForm.Show(); - } - } - - void UpdateValuesToolStripMenuItemClick(object sender, EventArgs e) - { - try - { - easyModbusManager.GetValues(easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index], treeView1.SelectedNode.Index); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Reading values", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - void SplitContainer1SplitterMoved(object sender, SplitterEventArgs e) - { - treeView1.Width = splitContainer1.Panel1.Width - 5; - tabControl1.Width = splitContainer1.Panel2.Width - 80; - - } - - void Button1Click(object sender, EventArgs e) - { - if (treeView1.SelectedNode == null) return; - dataGridView1.AllowUserToAddRows = false; - if (treeView1.SelectedNode.Level == 1) - { - dataGridView1.Rows.Add(); - dataGridView1[0,dataGridView1.Rows.Count-1].Value=easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Index].ConnectionName; - } - if (treeView1.SelectedNode.Level == 2) - { - dataGridView1.Rows.Add(); - dataGridView1[0,dataGridView1.Rows.Count-1].Value=easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].ConnectionName; - } - dataGridView1.AllowUserToAddRows = true; - } - - void Button2Click(object sender, EventArgs e) - { - if (treeView1.SelectedNode == null) return; - if (treeView1.SelectedNode.Level == 2) - { - - FunctionProperties functionProperty = easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].FunctionPropertiesList[treeView1.SelectedNode.Index]; - ConnectionProperties connectionProperty = easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index]; - - dataGridView1.AllowUserToAddRows = false; - for (int i = 0; i < functionProperty.Quantity; i++) - { - dataGridView1.Rows.Add(); - dataGridView1[0,dataGridView1.Rows.Count-1].Value = connectionProperty.ConnectionName; - dataGridView1.ClearSelection(); - dataGridView1.CurrentCell = null; - DataGridView1CellClick(null, null); - - // DataGridViewComboBoxCell cbCell = (DataGridViewComboBoxCell)dataGridView1.Rows[row].Cells[1]; - switch (functionProperty.FunctionCodeRead) - { - case FunctionCodeRd.ReadCoils: dataGridView1[1,dataGridView1.Rows.Count-1].Value = "0x"+(functionProperty.StartingAdress+i+1).ToString(); - break; - case FunctionCodeRd.ReadDiscreteInputs: dataGridView1[1,dataGridView1.Rows.Count-1].Value = "1x"+(functionProperty.StartingAdress+i+1).ToString(); - break; - case FunctionCodeRd.ReadHoldingRegisters: dataGridView1[1,dataGridView1.Rows.Count-1].Value = "4x"+(functionProperty.StartingAdress+i+1).ToString(); - break; - case FunctionCodeRd.ReadInputRegisters: dataGridView1[1,dataGridView1.Rows.Count-1].Value = "3x"+(functionProperty.StartingAdress+i+1).ToString(); - break; - default: break; - - } - - - - } - dataGridView1.AllowUserToAddRows = true; - } - - - } - - - private void UpdateDataGridViewItems() - { - - - //*********************************************************************Set combo box for Connection - string[] connectionNames = new string[dataGridView1.RowCount]; - //Save data from column "Connection name" - for (int i = 0; i < dataGridView1.RowCount; i++) - { - if (dataGridView1[0, i].Value != null) - connectionNames[i] = dataGridView1[0, i].Value.ToString(); - } - DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn(); - dataGridView1.Columns.RemoveAt(0); - cmb.HeaderText = "Connection"; - if (easyModbusManager.connectionPropertiesList.Count > 0) - cmb.MaxDropDownItems = easyModbusManager.connectionPropertiesList.Count; - else - cmb.MaxDropDownItems = 1; - foreach (ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - { - cmb.Items.Add(connectionProperty.ConnectionName); - } - dataGridView1.Columns.Insert(0,cmb); - //Restore data to column "connection name" - for (int i = 0; i < dataGridView1.RowCount; i++) - { - dataGridView1[0, i].Value = connectionNames[i] ; - } - - - - - - // DataGridViewComboBoxCell cbCell = (DataGridViewComboBoxCell)dataGridView1.Rows[0].Cells[3]; - // cbCell.Items.Add("www"); - } - - void DataGridView1CellClick(object sender, DataGridViewCellEventArgs e) - { - //********************************************************************Set combo box for address - int row = 0; - if (dataGridView1.CurrentCell == null) - row = dataGridView1.RowCount-1; - else - row = dataGridView1.CurrentCell.RowIndex; - DataGridViewComboBoxCell cbCell = (DataGridViewComboBoxCell)dataGridView1.Rows[row].Cells[1]; - string selectedCell = null; - if (cbCell.Value != null) - selectedCell = cbCell.Value.ToString(); - cbCell.Value = null; - cbCell.Items.Clear(); - for (int j = 0; j < easyModbusManager.connectionPropertiesList.Count; j++) - { - if (dataGridView1[0,row].Value != null) - if (easyModbusManager.connectionPropertiesList[j].ConnectionName == dataGridView1[0,row].Value.ToString()) - { - - for (int k = 0; k < easyModbusManager.connectionPropertiesList[j].FunctionPropertiesList.Count; k++) - { - int currentAddress = 0; - for (int l = 0; l < easyModbusManager.connectionPropertiesList[j].FunctionPropertiesList[k].Quantity; l++) - { - currentAddress = easyModbusManager.connectionPropertiesList[j].FunctionPropertiesList[k].StartingAdress + l + 1; - switch (easyModbusManager.connectionPropertiesList[j].FunctionPropertiesList[k].FunctionCodeRead) - { - - case FunctionCodeRd.ReadCoils: - cbCell.Items.Add("0x" + currentAddress.ToString()); - break; - case FunctionCodeRd.ReadDiscreteInputs: - cbCell.Items.Add("1x" + currentAddress.ToString()); - break; - case FunctionCodeRd.ReadHoldingRegisters: - cbCell.Items.Add("4x" + currentAddress.ToString()); - break; - case FunctionCodeRd.ReadInputRegisters: - cbCell.Items.Add("3x" + currentAddress.ToString()); - break; - default: break; - - } - } - } - } - } - if (selectedCell != null) - { - for (int i = 0; i < cbCell.Items.Count; i++) - if (cbCell.Items[i].ToString() == selectedCell) - cbCell.Value = selectedCell; - } - //********************************************************************Set combo box for datatype - if (dataGridView1[1,row].Value != null) - { - cbCell = (DataGridViewComboBoxCell)dataGridView1.Rows[row].Cells[3]; - selectedCell = null; - if (cbCell.Value != null) - selectedCell = cbCell.Value.ToString(); - cbCell.Value = null; - cbCell.Items.Clear(); - if (dataGridView1[1, row].Value.ToString().StartsWith("0x") | dataGridView1[1, row].Value.ToString().StartsWith("1x")) - { - cbCell.Items.Add("BOOL (FALSE...TRUE)"); - cbCell.Value = "BOOL (FALSE...TRUE)"; - } - if (dataGridView1[1,row].Value.ToString().StartsWith("3x")|dataGridView1[1,row].Value.ToString().StartsWith("4x")) - { - cbCell.Items.Add("INT16 (-32768...32767)"); - cbCell.Items.Add("UINT16 (0...65535)"); - cbCell.Items.Add("ASCII"); - } - if (selectedCell != null) - { - for (int i = 0; i < cbCell.Items.Count; i++) - if (cbCell.Items[i].ToString() == selectedCell) - cbCell.Value = selectedCell; - } - - } - - } - void DeleteConnectionToolStripMenuItemClick(object sender, EventArgs e) - { - if (treeView1.SelectedNode != null) - if (treeView1.SelectedNode.Level == 1) - { - easyModbusManager.RemoveConnection(treeView1.SelectedNode.Index); - } - } - void EditConnectionToolStripMenuItemClick(object sender, EventArgs e) - { - if (treeView1.SelectedNode != null) - { - int index = treeView1.SelectedNode.Index; - if (treeView1.SelectedNode.Level == 1) - { - AddConnectionForm addConnectionForm = new AddConnectionForm(easyModbusManager, index); - addConnectionForm.ShowDialog(); - } - } - } - void EditFunctionCodeToolStripMenuItemClick(object sender, EventArgs e) - { - if (treeView1.SelectedNode == null) return; - int indexFunction = treeView1.SelectedNode.Index; - int indexConnection = treeView1.SelectedNode.Parent.Index; - if (treeView1.SelectedNode.Level == 2) - { - AddFunctionCodeForm addFunctionCodeForm = new AddFunctionCodeForm(easyModbusManager, indexConnection, indexFunction); - addFunctionCodeForm.ShowDialog(); - } - - } - void UpdateAllValuesToolStripMenuItemClick(object sender, EventArgs e) - { - try - { - foreach(ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - for (int i = 0; i < connectionProperty.FunctionPropertiesList.Count; i++) - easyModbusManager.GetValues(connectionProperty, i); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Reading values", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - void DeleteFunctionCodeToolStripMenuItemClick(object sender, EventArgs e) - { - if (treeView1.SelectedNode != null) - if (treeView1.SelectedNode.Level == 2) - { - easyModbusManager.RemoveFunctionProperty(treeView1.SelectedNode.Parent.Index, treeView1.SelectedNode.Index); - } - } - void MainFormSizeChanged(object sender, EventArgs e) - { - treeView1.Height = this.Height - 112; - tabControl1.Height = this.Height - 70; - dataGridView1.Height = this.tabControl1.Height - 30; - dataGridView1.Width = this.splitContainer1.Panel2.Width - 85; - } - void Button3Click(object sender, EventArgs e) - { - this.AddConnectionToolStripMenuItemClick(null, null); - } - void Button4Click(object sender, EventArgs e) - { - this.DeleteConnectionToolStripMenuItemClick(null, null); - } - void Button5Click(object sender, EventArgs e) - { - this.EditConnectionToolStripMenuItemClick(null, null); - } - void Button6Click(object sender, EventArgs e) - { - this.AddFunctionCodeToolStripMenuItemClick(null, null); - } - void Button7Click(object sender, EventArgs e) - { - this.DeleteFunctionCodeToolStripMenuItemClick(null, null); - } - void Button8Click(object sender, EventArgs e) - { - this.EditFunctionCodeToolStripMenuItemClick(null, null); - } - void Button9Click(object sender, EventArgs e) - { - this.StopAllJobsToolStripMenuItemClick(null, null); - } - - void StartSingleJobToolStripMenuItemClick(object sender, EventArgs e) - { - GetValuesThreadObject getValuesThreadObject = new GetValuesThreadObject(); - getValuesThreadObject.connectionProperty = easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index]; - getValuesThreadObject.functionPropertyIndex = treeView1.SelectedNode.Index; - if (getValuesThreadObject.connectionProperty.timer == null) - getValuesThreadObject.connectionProperty.timer = new System.Threading.Timer(GetValuesThread, getValuesThreadObject , easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].CycleTime, easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].CycleTime); - else - getValuesThreadObject.connectionProperty.timer.Change(easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].CycleTime, easyModbusManager.connectionPropertiesList[treeView1.SelectedNode.Parent.Index].CycleTime); - getValuesThreadObject.connectionProperty.modbusClient.ReceiveDataChanged -= new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateTextBoxReceive); - getValuesThreadObject.connectionProperty.modbusClient.SendDataChanged -= new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateTextBoxSend); - - } - - private bool locked; - object locker = new object(); - private void GetValuesThread(object obj) - { - if (locked) - System.Threading.Thread.Sleep(100); - if (!locked) - locked = true; - lock (locker) { - - GetValuesThreadObject getValuesThreadObject = (GetValuesThreadObject)obj; - try { - if (getValuesThreadObject.functionPropertyIndex != 0) - easyModbusManager.GetValues(getValuesThreadObject.connectionProperty, getValuesThreadObject.functionPropertyIndex); - else - easyModbusManager.GetValues(getValuesThreadObject.connectionProperty); - } catch (Exception exc) { - getValuesThreadObject.connectionProperty.timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - getValuesThreadObject.connectionProperty.modbusClient.Disconnect(); - MessageBox.Show(exc.Message, "Exception Reading values", MessageBoxButtons.OK, MessageBoxIcon.Error); - - } finally { - UpdateNodesConnectedStatus(); - locked = false; - } - locked = false; - } - } - - void StartAllJobsToolStripMenuItemClick(object sender, EventArgs e) - { - foreach(ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - { - connectionProperty.modbusClient.ReceiveDataChanged += new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateTextBoxReceive); - connectionProperty.modbusClient.SendDataChanged += new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateTextBoxSend); - GetValuesThreadObject getValuesThreadObject = new GetValuesThreadObject(); - getValuesThreadObject.connectionProperty = connectionProperty; - if (connectionProperty.timer == null) - connectionProperty.timer = new System.Threading.Timer(GetValuesThread, getValuesThreadObject , connectionProperty.CycleTime, connectionProperty.CycleTime); - else - connectionProperty.timer.Change(connectionProperty.CycleTime, connectionProperty.CycleTime); - } - UpdateNodesConnectedStatus(); - } - void Button10Click(object sender, EventArgs e) - { - this.StartAllJobsToolStripMenuItemClick(null, null); - } - - void UpdateNodesConnectedStatus() - { - if (treeView1.Nodes.Count > 0) - foreach (TreeNode tn1 in treeView1.Nodes[0].Nodes) - { - foreach (TreeNode tn2 in tn1.Nodes) - { - if (easyModbusManager.connectionPropertiesList[tn1.Index].modbusClient.Connected) - tn2.BackColor = Color.Green; - else - tn2.BackColor = Color.White; - } - } - - } - void StopAllJobsToolStripMenuItemClick(object sender, EventArgs e) - { - foreach(ConnectionProperties connectionProperty in easyModbusManager.connectionPropertiesList) - { - connectionProperty.modbusClient.ReceiveDataChanged -= new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateTextBoxReceive); - connectionProperty.modbusClient.SendDataChanged -= new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateTextBoxSend); - connectionProperty.timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - connectionProperty.modbusClient.Disconnect(); - } - UpdateNodesConnectedStatus(); - } - - - public class GetValuesThreadObject - { - public ConnectionProperties connectionProperty; - public int functionPropertyIndex; - } - - private void stopCurrentJobToolStripMenuItem_Click(object sender, EventArgs e) - { - int indexJobToStop = 0; - if (treeView1.SelectedNode.Level == 1) - { - indexJobToStop = treeView1.SelectedNode.Index; - easyModbusManager.connectionPropertiesList[indexJobToStop].timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.Disconnect(); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.ReceiveDataChanged += new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateTextBoxReceive); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.SendDataChanged += new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateTextBoxSend); - } - if (treeView1.SelectedNode.Level == 2) - { - indexJobToStop = treeView1.SelectedNode.Parent.Index; - easyModbusManager.connectionPropertiesList[indexJobToStop].timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.Disconnect(); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.ReceiveDataChanged += new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateTextBoxReceive); - easyModbusManager.connectionPropertiesList[indexJobToStop].modbusClient.SendDataChanged += new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateTextBoxSend); - - } - UpdateNodesConnectedStatus(); - } - - private void saveWorkspaceToolStripMenuItem_Click(object sender, EventArgs e) - { - easyModbusManager.WriteXML(dataGridView1); - } - - private void loadToolStripMenuItem_Click(object sender, EventArgs e) - { - easyModbusManager.dataGridViewChanged += new EasyModbusManager.DataGridViewChanged(DataGridViewLinesChanged); - easyModbusManager.ReadXML(dataGridView1); - } - - private void DataGridViewLinesChanged(object sender) - { - dataGridView1.ClearSelection(); - dataGridView1.CurrentCell = null; - - DataGridView1CellClick(null, null); - } - - delegate void UpdateReceiveDataCallback(EasyModbus.ModbusClient sender); - void UpdateTextBoxReceive(object sender) - { - EasyModbus.ModbusClient modbusClient = (EasyModbus.ModbusClient)sender; - if (textBox1.InvokeRequired) - { - UpdateReceiveDataCallback d = new UpdateReceiveDataCallback(UpdateTextBoxReceive); - this.Invoke(d, new object[] { modbusClient }); - } - else - { - textBox1.AppendText("From: "+modbusClient.IPAddress.ToString()+ " Rx: "); - string hex = BitConverter.ToString(modbusClient.receiveData); - hex = hex.Replace("-", " "); - textBox1.AppendText(hex); - textBox1.AppendText(System.Environment.NewLine); - } - } - - - delegate void UpdateSendDataCallback(EasyModbus.ModbusClient sender); - void UpdateTextBoxSend(object sender) - { - EasyModbus.ModbusClient modbusClient = (EasyModbus.ModbusClient)sender; - if (textBox1.InvokeRequired) - { - UpdateSendDataCallback d = new UpdateSendDataCallback(UpdateTextBoxSend); - this.Invoke(d, new object[] { modbusClient }); - } - else - { - textBox1.AppendText("To: "+modbusClient.IPAddress.ToString() + "Tx: "); - string hex = BitConverter.ToString(modbusClient.sendData); - hex = hex.Replace("-", " "); - textBox1.AppendText(hex); - textBox1.AppendText(System.Environment.NewLine); - } - } - - private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) - { - // check if we are in column value - if (e.ColumnIndex == 4) - { - int idx = e.RowIndex; - FunctionProperties functionProperties= easyModbusManager.FindPropertyFromGrid(idx); - if (functionProperties != null) - { - string str = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); - int[] values = EasyModbusManager.StrToValues(functionProperties, str); - easyModbusManager.WriteToServer(functionProperties, values); - } - } - - } - } - -} diff --git a/EasyModbusAdvancedClient/MainForm.resx b/EasyModbusAdvancedClient/MainForm.resx deleted file mode 100644 index 755aea9..0000000 --- a/EasyModbusAdvancedClient/MainForm.resx +++ /dev/null @@ -1,984 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - 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 - /wBvHwFTyP73igAAAABJRU5ErkJggg== - - - - - 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 - AAAAAElFTkSuQmCC - - - - - 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 - Ab2/sBj+ZzWJAAAAAElFTkSuQmCC - - - - - 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 - - - - 17, 17 - - - - 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 - Ab2/sBj+ZzWJAAAAAElFTkSuQmCC - - - - - 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 - AAAAAElFTkSuQmCC - - - - - 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 - /wBvHwFTyP73igAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAD - dAAAA3QBAitBRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAATdEVYdFNvdXJj - ZQBPeHlnZW4gSWNvbnPsGK7oAAAIzElEQVRYR72XC1BU1xnHz+7dx929+37CLvKWpzyCREziCNokgkRc - RFRAEXwxIFLwhYgy4INan6CgaKwBRVFQNMYmRE111MRO2yTVJm2aqU6SiZk0rU5am8bG6r/fvYDhsSbt - ZKY787u797v3fP//+c6559xlAH4QDEzmLf7f4jXoDVbLFGwpm2xdbT2UuDnxg1n7Z92pPV37oOli04PK - k5V/z96ffTNhc0K3cZUxi+5VecvhDa/BgbASpmPL2EaunPsyfU86anpq0PJ2Cw7+/iC6bnah408daL7W - jNpLtVhyagmmtkyFYoniLitnO8iIwVvO8R3j/dZcWZMo/h52cSBcFStULOf+ktOWgz3v7EHDtQZseXfL - dyLes+NXOzCxcSK4Mvkd+TJWMjCnol6+Pu9ULqaeyrgjng8S7Iecy9XlXEvU+ghsuLgB9b+sx/qr6/8n - NlzdgNJXSjFirR/UK7kXxSHk6xSb4nfHoek3TeAbFSTlxYA4qbTFynMpm8ej7mIdqi9U/yBqL9YifXcq - hCrVzYSGWOl845WNMDVqSJANN6AvUu9/qiYRVWersPS1pd/J6rOrseLVFVjWs2z49Z5vWX2O7juzHNXn - qqVr1eerYdupA1VlsAFjsXZRWEkQyrrLUHKyZBilp0qRtz8PY9eORXBxMBSZCsgyZHDkOxBREYGJP5mI - go4ClJym+73xci9LzyyFq8k42IC9hAmmmfzt2SRQ2FE4jPlH5iNuRRzYFCpcH/IpcnAZXO+5h8hi0ORr - MGHnBBR2U7uBnCCOE12FKDpRhMAmC1jnAAOOhdrmxPJ45LbmIqc1ZxCZuzJhmGXoE5VBO0kJ3QQV9Cnq - r/XJ6n/qxqnAU0yeIwObT0aKGALXBWJ613TkdFOOE0QX0UkczUF+Rz5CmuxIudBngGUzzpalvZvRkAFP - i2cQmc2ZEGYIkjifoYApTfMvR66uyXeOMaHfvCvfFGafpWs0PcvfUxVQRSrJRBWD3xY/eE5SnhNEJ9FB - tHuQdSgLEXt8MHpvnwH/CvOU0Fw3UhtSB5G+Mx0BRQGSuCZDCUe27qPAhSZ3v/BQ/IssUbbJwt+4ajnY - FjLxU4aY1hikdlO+TuIw0ZaKtANpiGlxf2sgoMjcHlMSieRNyYOIW9k75twLcjizdN8ELLY5hooOxD3D - cMw4gwdrJXFCaBUwqmsUkk9Svk6inTiQjJSWFMQ2uhHdGd1rwDXHeC22PAZJdUmDMOWaJAP6yWq45xnX - DRUciM803T5dthqy16lalzQIvRKKMZfHIOks5TpNHEvCmANjEL49HI5VDoRtsCHwpcBeA/ZM3a2oskjE - rop9RFxVHDgPjWcmg2kyD98iU9RQ0X6SVoRFuPKMkF2TwfqJFSNvjETY9TBEvBWBiJ4IjDg8AsYGeuxo - XrAyBtkCGYKqzV+k9D+GlnTNV6GlIQirCHtEcGkw2Ay6eTaDOZX/hiaqfKhwP8/WRT4Xmxv0teEpNQzj - eBiT+YfGCfwDmpQPzJM0Dy2TNbB6tLDTZHbmC/At0X/qrjI+I7aVEphS+X8YZuphpF5Y5lhgLbTCuJAc - zyPHxQzGNP4+W8S4gaLfh71A8BofinQwvKC+pUijmUvjLS0oucQCYgmxksEwXQ1boS5+aOPHYctWM+1Y - Ja99RqnSTVRzhjReZvTwXl9cpIPOo7qunawAyyDBnD5xGiu2iqijChSrYZmn3TW08eMweXiNZTbvr6yX - O7lVMgtXJNMrczmtehqnMmXzCnPOt2akgzBD1W5MVYPNJEFxJRPFxQmznthKBraqaViE+65Kc0h/w8dh - LzDJLRM046z1mqc1jcp41Q4uXL5NFsA2MSerYSa2nAm2Iq3aUKySTEiNtPlcmm2SFqyABBcT4kq2rldc - uUMODe3d/psM8C3Tfeau0TkHCg7EscAsp4UoP3iludyyRzvX0KT2CDuVE9UN3BhumyyaTAQJ65Q+hjy1 - mS/npTZ9BybTP6+8q1+gAjkUdylJXLG9V1zfpIZjrwCfzXoEVVr/HbjWXBhQbTVH02YSnc1YwHKz1rVI - P8kv03A+dq2zZ8TPjId8X9RvtbcIq0zN/CJhlyqbTDxPlRjrrBFGqecqHi1oj9wrsuSNrjzacKpJfBOt - fttl0luLfheN/x4NfPbpQYkRf9AXIZssSNroRmS546uoYsfd0eUuBFWY7yUecP05ot3+YehB69XAl8wn - 3fsN+8j4RjKxlCpRIDSqPI4yYYKqSK4bZoCec15IV92xr9FCRr1XNXAg5zDvFsV18D9gREibBZHtdsR0 - +CDhmJuW2CAkdwfiyW4/PHncDwmdrvtxR31vRx9x3gg7ZHszqNXcTSZaqBIbaDgqRjZY58ryZc9RlQdP - wkcn09kCn9k6mLbxVHoljM28VHo/6rkkftiOuKM+SOxy44mXXYh51QejXnci+qwTo3qciDvji9HdbtHI - l6OOOD8kE5eoEl00HLsj99nXCYuUS+gtmx+kOfBECkxjLSMrrLDs0kilp8a0ZpsRTj2P7ROPO+ODqPO0 - nl+2IeQtC0KuWhD6phXhF+2SIdGcaIIq8QENx4X4Ntcxy2K+mR7vgGF6QwNSMJO9FrXageC9ZmncQ9us - oGRiUsS/4ovIX9glUf93THD/zgD3ewb4XTMi8NdmyZRoQqyEOBzjjgW851dpeIPNZdO8ankLitA+sDVk - pfnh2DY/hB+ySb0Xk4rlFns74rdGOP+og/UjLSwfa2C/IcD1PlWLTIiVeLonAAFbTPecZcKnbDb9TaGN - x6uOt2A/bBbzaBepbuoqVUg9MRKjT7uk3geRiO8f9DB/ooHwVxW0d5QwfK6WTARcN+NH54IRUWMTV9UL - hL+33P14DQ6Eng4l7Q0/FuarPhtT74Z1sxaO4wKsl7WI/9gHcZ/7QPa2DMrjHNTbODyxxRfymbJbtKpm - e8s3FK9Bb9BHRm+9iTQ/6mjD+jl9v6vLUX7BZclv0+/3iTeIjUQy7Zzi3x6veYbiNfj/A+w/LGRr8L2X - B8UAAAAASUVORK5CYII= - - - - - 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 - - - - True - - - True - - - True - - - True - - - True - - - - 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 - - - - 163, 17 - - - - AAABAAEAQEAAAAEAIAAoQAAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAADgAAAAhwAAAAAAAAAAAAAAAAAAAMEAAACaAAAAKQAAAAAAAAApAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAKQAAAJoAAADBAAAAAAAAAIcAAACaAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmgAAAIcAAADgAAAAKQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ACkAAADgAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAOAAAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD//wAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP//AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A//8AAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A//8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//wAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAACkAAADgAAAAhwAAAJoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaAAAAhwAAAAAAAADBAAAAmgAAACkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkAAACaAAAAwQAAAAAAAAAAAAAAAAAA - AIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA4AAAAP8AAADgAAAAhwAA - AAAAAAAA - - - \ No newline at end of file diff --git a/EasyModbusAdvancedClient/Program.cs b/EasyModbusAdvancedClient/Program.cs deleted file mode 100644 index b7b3982..0000000 --- a/EasyModbusAdvancedClient/Program.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Windows.Forms; - -namespace EasyModbusAdvancedClient -{ - /// - /// Class with program entry point. - /// - internal sealed class Program - { - /// - /// Program entry point. - /// - [STAThread] - private static void Main(string[] args) - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm()); - } - - } -} diff --git a/EasyModbusAdvancedClient/Properties/AssemblyInfo.cs b/EasyModbusAdvancedClient/Properties/AssemblyInfo.cs deleted file mode 100644 index 4fae2f9..0000000 --- a/EasyModbusAdvancedClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -#region Using directives - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("EasyModbusAdvancedClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Stefan Rossmann Engineering Solutions")] -[assembly: AssemblyProduct("EasyModbusAdvancedClient")] -[assembly: AssemblyCopyright("Copyright 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible(false)] - -// The assembly version has following format : -// -// Major.Minor.Build.Revision -// -// You can specify all the values or you can use the default the Revision and -// Build Numbers by using the '*' as shown below: -[assembly: AssemblyVersion("5.1.0")] diff --git a/EasyModbusAdvancedClient/Properties/Resources.Designer.cs b/EasyModbusAdvancedClient/Properties/Resources.Designer.cs deleted file mode 100644 index 7c0f175..0000000 --- a/EasyModbusAdvancedClient/Properties/Resources.Designer.cs +++ /dev/null @@ -1,143 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace EasyModbusAdvancedClient.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EasyModbusAdvancedClient.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap network_connect { - get { - object obj = ResourceManager.GetObject("network-connect", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap network_connect_2 { - get { - object obj = ResourceManager.GetObject("network-connect-2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap network_disconnect_2 { - get { - object obj = ResourceManager.GetObject("network-disconnect-2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap process_stop_2 { - get { - object obj = ResourceManager.GetObject("process-stop-2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap tab { - get { - object obj = ResourceManager.GetObject("tab", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap tab_close { - get { - object obj = ResourceManager.GetObject("tab-close", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap tab_new { - get { - object obj = ResourceManager.GetObject("tab-new", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap view_refresh_2 { - get { - object obj = ResourceManager.GetObject("view-refresh-2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/EasyModbusAdvancedClient/Properties/Resources.resx b/EasyModbusAdvancedClient/Properties/Resources.resx deleted file mode 100644 index 179b94d..0000000 --- a/EasyModbusAdvancedClient/Properties/Resources.resx +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\tab-new.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\network-connect-2.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\view-refresh-2.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\tab.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\network-disconnect-2.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\network-connect.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\tab-close.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\process-stop-2.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/EasyModbusAdvancedClient/Resources/network-connect-2.ico b/EasyModbusAdvancedClient/Resources/network-connect-2.ico deleted file mode 100644 index 1c6d3f6..0000000 Binary files a/EasyModbusAdvancedClient/Resources/network-connect-2.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/network-connect.ico b/EasyModbusAdvancedClient/Resources/network-connect.ico deleted file mode 100644 index 42d882b..0000000 Binary files a/EasyModbusAdvancedClient/Resources/network-connect.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/network-disconnect-2.ico b/EasyModbusAdvancedClient/Resources/network-disconnect-2.ico deleted file mode 100644 index 20e8324..0000000 Binary files a/EasyModbusAdvancedClient/Resources/network-disconnect-2.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/process-stop-2.ico b/EasyModbusAdvancedClient/Resources/process-stop-2.ico deleted file mode 100644 index 71a0f72..0000000 Binary files a/EasyModbusAdvancedClient/Resources/process-stop-2.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/tab-close.ico b/EasyModbusAdvancedClient/Resources/tab-close.ico deleted file mode 100644 index 8df003f..0000000 Binary files a/EasyModbusAdvancedClient/Resources/tab-close.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/tab-new.ico b/EasyModbusAdvancedClient/Resources/tab-new.ico deleted file mode 100644 index 6f6c98e..0000000 Binary files a/EasyModbusAdvancedClient/Resources/tab-new.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/tab.ico b/EasyModbusAdvancedClient/Resources/tab.ico deleted file mode 100644 index 50b6170..0000000 Binary files a/EasyModbusAdvancedClient/Resources/tab.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/Resources/view-refresh-2.ico b/EasyModbusAdvancedClient/Resources/view-refresh-2.ico deleted file mode 100644 index 2925a53..0000000 Binary files a/EasyModbusAdvancedClient/Resources/view-refresh-2.ico and /dev/null differ diff --git a/EasyModbusAdvancedClient/app.config b/EasyModbusAdvancedClient/app.config deleted file mode 100644 index 51278a4..0000000 --- a/EasyModbusAdvancedClient/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/EasyModbusClientExample/EasyModbusClientExample.csproj b/EasyModbusClientExample/EasyModbusClientExample.csproj deleted file mode 100644 index c228c5b..0000000 --- a/EasyModbusClientExample/EasyModbusClientExample.csproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - {9412077F-7DFF-45D0-AFF9-7D5303118EA7} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Debug - AnyCPU - WinExe - EasyModbusClientExample - EasyModbusClientExample - v4.5 - Properties - - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - true - bin\DebugCommercial2\ - TRACE;DEBUG;COMMERCIAL - true - Full - x86 - MinimumRecommendedRules.ruleset - false - - - false - TRACE;DEBUG;SSL - - - false - - - - 4.0 - - - - 3.5 - - - - 3.5 - - - - - - 3.5 - - - - - Exceptions\Exceptions.cs - - - ModbusClient.cs - - - ModbusServer.cs - - - StoreLogData.cs - - - Form - - - MainForm.cs - - - - - True - True - Resources.resx - - - - - - - - MainForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/EasyModbusClientExample/MainForm.Designer.cs b/EasyModbusClientExample/MainForm.Designer.cs deleted file mode 100644 index 26e934b..0000000 --- a/EasyModbusClientExample/MainForm.Designer.cs +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Created by SharpDevelop. - * User: srossmann - * Date: 13.02.2015 - * Time: 11:09 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -namespace EasyModbusClientExample -{ - partial class MainForm - { - /// - /// Designer variable used to keep track of non-visual components. - /// - private System.ComponentModel.IContainer components = null; - private System.Windows.Forms.TextBox txtIpAddressInput; - private System.Windows.Forms.Label txtIpAddress; - private System.Windows.Forms.Label txtPort; - private System.Windows.Forms.TextBox txtPortInput; - private System.Windows.Forms.Button btnReadCoils; - private System.Windows.Forms.Button btnReadDiscreteInputs; - private System.Windows.Forms.Button btnReadHoldingRegisters; - private System.Windows.Forms.Button btnReadInputRegisters; - private System.Windows.Forms.TextBox txtStartingAddressInput; - private System.Windows.Forms.Label txtStartingAddress; - private System.Windows.Forms.Label txtNumberOfValues; - private System.Windows.Forms.TextBox txtNumberOfValuesInput; - - /// - /// Disposes resources used by the form. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) { - if (components != null) { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - /// - /// This method is required for Windows Forms designer support. - /// Do not change the method contents inside the source code editor. The Forms designer might - /// not be able to load this method if it was changed manually. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.txtIpAddressInput = new System.Windows.Forms.TextBox(); - this.txtIpAddress = new System.Windows.Forms.Label(); - this.txtPort = new System.Windows.Forms.Label(); - this.txtPortInput = new System.Windows.Forms.TextBox(); - this.btnReadCoils = new System.Windows.Forms.Button(); - this.btnReadDiscreteInputs = new System.Windows.Forms.Button(); - this.btnReadHoldingRegisters = new System.Windows.Forms.Button(); - this.btnReadInputRegisters = new System.Windows.Forms.Button(); - this.txtStartingAddressInput = new System.Windows.Forms.TextBox(); - this.txtStartingAddress = new System.Windows.Forms.Label(); - this.txtNumberOfValues = new System.Windows.Forms.Label(); - this.txtNumberOfValuesInput = new System.Windows.Forms.TextBox(); - this.lsbAnswerFromServer = new System.Windows.Forms.ListBox(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.cbbSelctionModbus = new System.Windows.Forms.ComboBox(); - this.txtCOMPort = new System.Windows.Forms.Label(); - this.cbbSelectComPort = new System.Windows.Forms.ComboBox(); - this.txtSlaveAddress = new System.Windows.Forms.Label(); - this.txtSlaveAddressInput = new System.Windows.Forms.TextBox(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.btnWriteMultipleRegisters = new System.Windows.Forms.Button(); - this.btnWriteMultipleCoils = new System.Windows.Forms.Button(); - this.btnWriteSingleRegister = new System.Windows.Forms.Button(); - this.btnWriteSingleCoil = new System.Windows.Forms.Button(); - this.txtCoilValue = new System.Windows.Forms.TextBox(); - this.txtRegisterValue = new System.Windows.Forms.TextBox(); - this.lblReadOperations = new System.Windows.Forms.Label(); - this.button3 = new System.Windows.Forms.Button(); - this.button4 = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); - this.txtStartingAddressOutput = new System.Windows.Forms.TextBox(); - this.lsbWriteToServer = new System.Windows.Forms.ListBox(); - this.lblParity = new System.Windows.Forms.Label(); - this.lblStopbits = new System.Windows.Forms.Label(); - this.cbbParity = new System.Windows.Forms.ComboBox(); - this.cbbStopbits = new System.Windows.Forms.ComboBox(); - this.txtBaudrate = new System.Windows.Forms.TextBox(); - this.lblBaudrate = new System.Windows.Forms.Label(); - this.txtConnectedStatus = new System.Windows.Forms.TextBox(); - this.button2 = new System.Windows.Forms.Button(); - this.btnClear = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.btnPrepareCoils = new System.Windows.Forms.Button(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // txtIpAddressInput - // - this.txtIpAddressInput.Location = new System.Drawing.Point(34, 55); - this.txtIpAddressInput.Name = "txtIpAddressInput"; - this.txtIpAddressInput.Size = new System.Drawing.Size(118, 20); - this.txtIpAddressInput.TabIndex = 0; - this.txtIpAddressInput.Text = "127.0.0.1"; - // - // txtIpAddress - // - this.txtIpAddress.Location = new System.Drawing.Point(34, 35); - this.txtIpAddress.Name = "txtIpAddress"; - this.txtIpAddress.Size = new System.Drawing.Size(100, 14); - this.txtIpAddress.TabIndex = 1; - this.txtIpAddress.Text = "Server IP-Address"; - // - // txtPort - // - this.txtPort.Location = new System.Drawing.Point(158, 35); - this.txtPort.Name = "txtPort"; - this.txtPort.Size = new System.Drawing.Size(73, 17); - this.txtPort.TabIndex = 3; - this.txtPort.Text = "Server Port"; - // - // txtPortInput - // - this.txtPortInput.Location = new System.Drawing.Point(158, 55); - this.txtPortInput.Name = "txtPortInput"; - this.txtPortInput.Size = new System.Drawing.Size(56, 20); - this.txtPortInput.TabIndex = 2; - this.txtPortInput.Text = "502"; - // - // btnReadCoils - // - this.btnReadCoils.Location = new System.Drawing.Point(12, 176); - this.btnReadCoils.Name = "btnReadCoils"; - this.btnReadCoils.Size = new System.Drawing.Size(161, 23); - this.btnReadCoils.TabIndex = 5; - this.btnReadCoils.Text = "Read Coils - FC1"; - this.btnReadCoils.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnReadCoils.UseVisualStyleBackColor = true; - this.btnReadCoils.Click += new System.EventHandler(this.BtnReadCoilsClick); - // - // btnReadDiscreteInputs - // - this.btnReadDiscreteInputs.Location = new System.Drawing.Point(12, 205); - this.btnReadDiscreteInputs.Name = "btnReadDiscreteInputs"; - this.btnReadDiscreteInputs.Size = new System.Drawing.Size(161, 23); - this.btnReadDiscreteInputs.TabIndex = 6; - this.btnReadDiscreteInputs.Text = "Read Discrete Inputs - FC2"; - this.btnReadDiscreteInputs.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnReadDiscreteInputs.UseVisualStyleBackColor = true; - this.btnReadDiscreteInputs.Click += new System.EventHandler(this.btnReadDiscreteInputs_Click); - // - // btnReadHoldingRegisters - // - this.btnReadHoldingRegisters.Location = new System.Drawing.Point(12, 234); - this.btnReadHoldingRegisters.Name = "btnReadHoldingRegisters"; - this.btnReadHoldingRegisters.Size = new System.Drawing.Size(161, 23); - this.btnReadHoldingRegisters.TabIndex = 7; - this.btnReadHoldingRegisters.Text = "Read Holding Registers - FC3"; - this.btnReadHoldingRegisters.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnReadHoldingRegisters.UseVisualStyleBackColor = true; - this.btnReadHoldingRegisters.Click += new System.EventHandler(this.btnReadHoldingRegisters_Click); - // - // btnReadInputRegisters - // - this.btnReadInputRegisters.Location = new System.Drawing.Point(12, 263); - this.btnReadInputRegisters.Name = "btnReadInputRegisters"; - this.btnReadInputRegisters.Size = new System.Drawing.Size(161, 23); - this.btnReadInputRegisters.TabIndex = 8; - this.btnReadInputRegisters.Text = "Read Input Registers - FC4"; - this.btnReadInputRegisters.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnReadInputRegisters.UseVisualStyleBackColor = true; - this.btnReadInputRegisters.Click += new System.EventHandler(this.btnReadInputRegisters_Click); - // - // txtStartingAddressInput - // - this.txtStartingAddressInput.Location = new System.Drawing.Point(198, 198); - this.txtStartingAddressInput.Name = "txtStartingAddressInput"; - this.txtStartingAddressInput.Size = new System.Drawing.Size(39, 20); - this.txtStartingAddressInput.TabIndex = 9; - this.txtStartingAddressInput.Text = "1"; - // - // txtStartingAddress - // - this.txtStartingAddress.Location = new System.Drawing.Point(198, 178); - this.txtStartingAddress.Name = "txtStartingAddress"; - this.txtStartingAddress.Size = new System.Drawing.Size(89, 17); - this.txtStartingAddress.TabIndex = 10; - this.txtStartingAddress.Text = "Starting Address"; - // - // txtNumberOfValues - // - this.txtNumberOfValues.Location = new System.Drawing.Point(198, 233); - this.txtNumberOfValues.Name = "txtNumberOfValues"; - this.txtNumberOfValues.Size = new System.Drawing.Size(100, 17); - this.txtNumberOfValues.TabIndex = 12; - this.txtNumberOfValues.Text = "Number of Values"; - // - // txtNumberOfValuesInput - // - this.txtNumberOfValuesInput.Location = new System.Drawing.Point(198, 253); - this.txtNumberOfValuesInput.Name = "txtNumberOfValuesInput"; - this.txtNumberOfValuesInput.Size = new System.Drawing.Size(39, 20); - this.txtNumberOfValuesInput.TabIndex = 11; - this.txtNumberOfValuesInput.Text = "1"; - // - // lsbAnswerFromServer - // - this.lsbAnswerFromServer.FormattingEnabled = true; - this.lsbAnswerFromServer.Location = new System.Drawing.Point(310, 147); - this.lsbAnswerFromServer.Name = "lsbAnswerFromServer"; - this.lsbAnswerFromServer.Size = new System.Drawing.Size(188, 160); - this.lsbAnswerFromServer.TabIndex = 13; - this.lsbAnswerFromServer.DoubleClick += new System.EventHandler(this.lsbAnswerFromServer_DoubleClick); - // - // linkLabel1 - // - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(307, 6); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(165, 13); - this.linkLabel1.TabIndex = 16; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "http://www.EasyModbusTCP.net"; - // - // cbbSelctionModbus - // - this.cbbSelctionModbus.FormattingEnabled = true; - this.cbbSelctionModbus.Items.AddRange(new object[] { - "ModbusTCP (Ethernet)", - "ModbusRTU (Serial)"}); - this.cbbSelctionModbus.Location = new System.Drawing.Point(34, 6); - this.cbbSelctionModbus.Name = "cbbSelctionModbus"; - this.cbbSelctionModbus.Size = new System.Drawing.Size(180, 21); - this.cbbSelctionModbus.TabIndex = 17; - this.cbbSelctionModbus.Text = "ModbusTCP (Ethernet)"; - this.cbbSelctionModbus.SelectedIndexChanged += new System.EventHandler(this.cbbSelctionModbus_SelectedIndexChanged); - // - // txtCOMPort - // - this.txtCOMPort.Location = new System.Drawing.Point(34, 35); - this.txtCOMPort.Name = "txtCOMPort"; - this.txtCOMPort.Size = new System.Drawing.Size(100, 14); - this.txtCOMPort.TabIndex = 18; - this.txtCOMPort.Text = "COM-Port"; - this.txtCOMPort.Visible = false; - // - // cbbSelectComPort - // - this.cbbSelectComPort.FormattingEnabled = true; - this.cbbSelectComPort.Items.AddRange(new object[] { - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8"}); - this.cbbSelectComPort.Location = new System.Drawing.Point(34, 55); - this.cbbSelectComPort.Name = "cbbSelectComPort"; - this.cbbSelectComPort.Size = new System.Drawing.Size(121, 21); - this.cbbSelectComPort.TabIndex = 19; - this.cbbSelectComPort.Visible = false; - this.cbbSelectComPort.SelectedIndexChanged += new System.EventHandler(this.cbbSelectComPort_SelectedIndexChanged); - // - // txtSlaveAddress - // - this.txtSlaveAddress.Location = new System.Drawing.Point(158, 35); - this.txtSlaveAddress.Name = "txtSlaveAddress"; - this.txtSlaveAddress.Size = new System.Drawing.Size(56, 19); - this.txtSlaveAddress.TabIndex = 20; - this.txtSlaveAddress.Text = "Slave ID"; - this.txtSlaveAddress.Visible = false; - // - // txtSlaveAddressInput - // - this.txtSlaveAddressInput.Location = new System.Drawing.Point(158, 55); - this.txtSlaveAddressInput.Name = "txtSlaveAddressInput"; - this.txtSlaveAddressInput.Size = new System.Drawing.Size(56, 20); - this.txtSlaveAddressInput.TabIndex = 21; - this.txtSlaveAddressInput.Text = "1"; - this.txtSlaveAddressInput.Visible = false; - this.txtSlaveAddressInput.TextChanged += new System.EventHandler(this.TxtSlaveAddressInputTextChanged); - // - // textBox1 - // - this.textBox1.Location = new System.Drawing.Point(12, 506); - this.textBox1.Multiline = true; - this.textBox1.Name = "textBox1"; - this.textBox1.ReadOnly = true; - this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox1.Size = new System.Drawing.Size(641, 157); - this.textBox1.TabIndex = 22; - this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); - // - // btnWriteMultipleRegisters - // - this.btnWriteMultipleRegisters.Location = new System.Drawing.Point(12, 453); - this.btnWriteMultipleRegisters.Name = "btnWriteMultipleRegisters"; - this.btnWriteMultipleRegisters.Size = new System.Drawing.Size(161, 23); - this.btnWriteMultipleRegisters.TabIndex = 30; - this.btnWriteMultipleRegisters.Text = "Write Multiple Registers - FC16"; - this.btnWriteMultipleRegisters.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnWriteMultipleRegisters.UseVisualStyleBackColor = true; - this.btnWriteMultipleRegisters.Click += new System.EventHandler(this.btnWriteMultipleRegisters_Click); - // - // btnWriteMultipleCoils - // - this.btnWriteMultipleCoils.Location = new System.Drawing.Point(12, 424); - this.btnWriteMultipleCoils.Name = "btnWriteMultipleCoils"; - this.btnWriteMultipleCoils.Size = new System.Drawing.Size(161, 23); - this.btnWriteMultipleCoils.TabIndex = 29; - this.btnWriteMultipleCoils.Text = "Write Multiple Coils - FC15"; - this.btnWriteMultipleCoils.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnWriteMultipleCoils.UseVisualStyleBackColor = true; - this.btnWriteMultipleCoils.Click += new System.EventHandler(this.btnWriteMultipleCoils_Click); - // - // btnWriteSingleRegister - // - this.btnWriteSingleRegister.Location = new System.Drawing.Point(12, 395); - this.btnWriteSingleRegister.Name = "btnWriteSingleRegister"; - this.btnWriteSingleRegister.Size = new System.Drawing.Size(161, 23); - this.btnWriteSingleRegister.TabIndex = 28; - this.btnWriteSingleRegister.Text = "Write Single Register - FC6"; - this.btnWriteSingleRegister.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnWriteSingleRegister.UseVisualStyleBackColor = true; - this.btnWriteSingleRegister.Click += new System.EventHandler(this.btnWriteSingleRegister_Click); - // - // btnWriteSingleCoil - // - this.btnWriteSingleCoil.Location = new System.Drawing.Point(12, 366); - this.btnWriteSingleCoil.Name = "btnWriteSingleCoil"; - this.btnWriteSingleCoil.Size = new System.Drawing.Size(161, 23); - this.btnWriteSingleCoil.TabIndex = 27; - this.btnWriteSingleCoil.Text = "Write Single Coil - FC5"; - this.btnWriteSingleCoil.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnWriteSingleCoil.UseVisualStyleBackColor = true; - this.btnWriteSingleCoil.Click += new System.EventHandler(this.btnWriteSingleCoil_Click); - // - // txtCoilValue - // - this.txtCoilValue.BackColor = System.Drawing.SystemColors.Info; - this.txtCoilValue.Location = new System.Drawing.Point(563, 413); - this.txtCoilValue.Name = "txtCoilValue"; - this.txtCoilValue.ReadOnly = true; - this.txtCoilValue.Size = new System.Drawing.Size(81, 20); - this.txtCoilValue.TabIndex = 31; - this.txtCoilValue.Text = "FALSE"; - this.txtCoilValue.DoubleClick += new System.EventHandler(this.txtCoilValue_DoubleClick); - // - // txtRegisterValue - // - this.txtRegisterValue.BackColor = System.Drawing.SystemColors.Info; - this.txtRegisterValue.Location = new System.Drawing.Point(563, 461); - this.txtRegisterValue.Name = "txtRegisterValue"; - this.txtRegisterValue.Size = new System.Drawing.Size(81, 20); - this.txtRegisterValue.TabIndex = 32; - this.txtRegisterValue.Text = "0"; - this.txtRegisterValue.TextChanged += new System.EventHandler(this.txtRegisterValue_TextChanged); - // - // lblReadOperations - // - this.lblReadOperations.AutoSize = true; - this.lblReadOperations.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblReadOperations.Location = new System.Drawing.Point(19, 127); - this.lblReadOperations.Name = "lblReadOperations"; - this.lblReadOperations.Size = new System.Drawing.Size(206, 20); - this.lblReadOperations.TabIndex = 37; - this.lblReadOperations.Text = "Read values from Server"; - // - // button3 - // - this.button3.BackColor = System.Drawing.Color.Lime; - this.button3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button3.Location = new System.Drawing.Point(310, 94); - this.button3.Name = "button3"; - this.button3.Size = new System.Drawing.Size(89, 47); - this.button3.TabIndex = 38; - this.button3.Text = "connect"; - this.button3.UseVisualStyleBackColor = false; - this.button3.Click += new System.EventHandler(this.button3_Click); - // - // button4 - // - this.button4.BackColor = System.Drawing.Color.Red; - this.button4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button4.Location = new System.Drawing.Point(409, 94); - this.button4.Name = "button4"; - this.button4.Size = new System.Drawing.Size(89, 47); - this.button4.TabIndex = 39; - this.button4.Text = "disconnect"; - this.button4.UseVisualStyleBackColor = false; - this.button4.Click += new System.EventHandler(this.button4_Click); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(19, 310); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(185, 20); - this.label1.TabIndex = 40; - this.label1.Text = "Write values to Server"; - // - // label4 - // - this.label4.Location = new System.Drawing.Point(198, 395); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(89, 17); - this.label4.TabIndex = 42; - this.label4.Text = "Starting Address"; - // - // txtStartingAddressOutput - // - this.txtStartingAddressOutput.Location = new System.Drawing.Point(198, 415); - this.txtStartingAddressOutput.Name = "txtStartingAddressOutput"; - this.txtStartingAddressOutput.Size = new System.Drawing.Size(39, 20); - this.txtStartingAddressOutput.TabIndex = 41; - this.txtStartingAddressOutput.Text = "1"; - // - // lsbWriteToServer - // - this.lsbWriteToServer.FormattingEnabled = true; - this.lsbWriteToServer.Location = new System.Drawing.Point(310, 340); - this.lsbWriteToServer.Name = "lsbWriteToServer"; - this.lsbWriteToServer.Size = new System.Drawing.Size(188, 160); - this.lsbWriteToServer.TabIndex = 43; - // - // lblParity - // - this.lblParity.Location = new System.Drawing.Point(96, 82); - this.lblParity.Name = "lblParity"; - this.lblParity.Size = new System.Drawing.Size(56, 19); - this.lblParity.TabIndex = 46; - this.lblParity.Text = "Parity"; - this.lblParity.Visible = false; - // - // lblStopbits - // - this.lblStopbits.Location = new System.Drawing.Point(158, 82); - this.lblStopbits.Name = "lblStopbits"; - this.lblStopbits.Size = new System.Drawing.Size(56, 19); - this.lblStopbits.TabIndex = 48; - this.lblStopbits.Text = "Stopbits"; - this.lblStopbits.Visible = false; - // - // cbbParity - // - this.cbbParity.FormattingEnabled = true; - this.cbbParity.Items.AddRange(new object[] { - "Even", - "Odd", - "None"}); - this.cbbParity.Location = new System.Drawing.Point(97, 101); - this.cbbParity.Name = "cbbParity"; - this.cbbParity.Size = new System.Drawing.Size(55, 21); - this.cbbParity.TabIndex = 50; - this.cbbParity.Visible = false; - // - // cbbStopbits - // - this.cbbStopbits.FormattingEnabled = true; - this.cbbStopbits.Items.AddRange(new object[] { - "1", - "1.5", - "2"}); - this.cbbStopbits.Location = new System.Drawing.Point(158, 101); - this.cbbStopbits.Name = "cbbStopbits"; - this.cbbStopbits.Size = new System.Drawing.Size(55, 21); - this.cbbStopbits.TabIndex = 51; - this.cbbStopbits.Visible = false; - // - // txtBaudrate - // - this.txtBaudrate.Location = new System.Drawing.Point(35, 102); - this.txtBaudrate.Name = "txtBaudrate"; - this.txtBaudrate.Size = new System.Drawing.Size(56, 20); - this.txtBaudrate.TabIndex = 53; - this.txtBaudrate.Text = "9600"; - this.txtBaudrate.Visible = false; - this.txtBaudrate.TextChanged += new System.EventHandler(this.txtBaudrate_TextChanged); - // - // lblBaudrate - // - this.lblBaudrate.Location = new System.Drawing.Point(35, 82); - this.lblBaudrate.Name = "lblBaudrate"; - this.lblBaudrate.Size = new System.Drawing.Size(56, 19); - this.lblBaudrate.TabIndex = 52; - this.lblBaudrate.Text = "Baudrate"; - this.lblBaudrate.Visible = false; - // - // txtConnectedStatus - // - this.txtConnectedStatus.BackColor = System.Drawing.Color.Red; - this.txtConnectedStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F); - this.txtConnectedStatus.Location = new System.Drawing.Point(3, 669); - this.txtConnectedStatus.Name = "txtConnectedStatus"; - this.txtConnectedStatus.Size = new System.Drawing.Size(665, 32); - this.txtConnectedStatus.TabIndex = 54; - this.txtConnectedStatus.Text = "Not connected to Server"; - // - // button2 - // - this.button2.Cursor = System.Windows.Forms.Cursors.Default; - this.button2.Image = global::EasyModbusClientExample.Properties.Resources.circle_minus; - this.button2.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.button2.Location = new System.Drawing.Point(518, 340); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(64, 52); - this.button2.TabIndex = 34; - this.button2.Text = "clear entry"; - this.button2.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button2_Click); - // - // btnClear - // - this.btnClear.Cursor = System.Windows.Forms.Cursors.Default; - this.btnClear.Image = global::EasyModbusClientExample.Properties.Resources.circle_delete1; - this.btnClear.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.btnClear.Location = new System.Drawing.Point(585, 340); - this.btnClear.Name = "btnClear"; - this.btnClear.Size = new System.Drawing.Size(64, 52); - this.btnClear.TabIndex = 33; - this.btnClear.Text = "clear all"; - this.btnClear.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.btnClear.UseVisualStyleBackColor = true; - this.btnClear.Click += new System.EventHandler(this.btnClear_Click); - // - // button1 - // - this.button1.Image = global::EasyModbusClientExample.Properties.Resources.arrow_left; - this.button1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.button1.Location = new System.Drawing.Point(507, 457); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(146, 43); - this.button1.TabIndex = 26; - this.button1.Text = "Prepare Registers"; - this.button1.TextAlign = System.Drawing.ContentAlignment.BottomRight; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // - // btnPrepareCoils - // - this.btnPrepareCoils.Image = global::EasyModbusClientExample.Properties.Resources.arrow_left; - this.btnPrepareCoils.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnPrepareCoils.Location = new System.Drawing.Point(507, 408); - this.btnPrepareCoils.Name = "btnPrepareCoils"; - this.btnPrepareCoils.Size = new System.Drawing.Size(146, 43); - this.btnPrepareCoils.TabIndex = 25; - this.btnPrepareCoils.Text = "Prepare Coils"; - this.btnPrepareCoils.TextAlign = System.Drawing.ContentAlignment.BottomRight; - this.btnPrepareCoils.UseVisualStyleBackColor = true; - this.btnPrepareCoils.Click += new System.EventHandler(this.btnPrepareCoils_Click); - // - // pictureBox1 - // - this.pictureBox1.Image = global::EasyModbusClientExample.Properties.Resources.small; - this.pictureBox1.Location = new System.Drawing.Point(476, 0); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(192, 101); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; - this.pictureBox1.TabIndex = 15; - this.pictureBox1.TabStop = false; - this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(669, 702); - this.Controls.Add(this.txtConnectedStatus); - this.Controls.Add(this.txtBaudrate); - this.Controls.Add(this.lblBaudrate); - this.Controls.Add(this.cbbStopbits); - this.Controls.Add(this.cbbParity); - this.Controls.Add(this.lblStopbits); - this.Controls.Add(this.lblParity); - this.Controls.Add(this.lsbWriteToServer); - this.Controls.Add(this.label4); - this.Controls.Add(this.txtStartingAddressOutput); - this.Controls.Add(this.label1); - this.Controls.Add(this.button4); - this.Controls.Add(this.button3); - this.Controls.Add(this.lblReadOperations); - this.Controls.Add(this.button2); - this.Controls.Add(this.btnClear); - this.Controls.Add(this.txtRegisterValue); - this.Controls.Add(this.txtCoilValue); - this.Controls.Add(this.btnWriteMultipleRegisters); - this.Controls.Add(this.btnWriteMultipleCoils); - this.Controls.Add(this.btnWriteSingleRegister); - this.Controls.Add(this.btnWriteSingleCoil); - this.Controls.Add(this.button1); - this.Controls.Add(this.btnPrepareCoils); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.txtSlaveAddressInput); - this.Controls.Add(this.txtSlaveAddress); - this.Controls.Add(this.cbbSelectComPort); - this.Controls.Add(this.txtCOMPort); - this.Controls.Add(this.cbbSelctionModbus); - this.Controls.Add(this.linkLabel1); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.lsbAnswerFromServer); - this.Controls.Add(this.txtNumberOfValues); - this.Controls.Add(this.txtNumberOfValuesInput); - this.Controls.Add(this.txtStartingAddress); - this.Controls.Add(this.txtStartingAddressInput); - this.Controls.Add(this.btnReadInputRegisters); - this.Controls.Add(this.btnReadHoldingRegisters); - this.Controls.Add(this.btnReadDiscreteInputs); - this.Controls.Add(this.btnReadCoils); - this.Controls.Add(this.txtPort); - this.Controls.Add(this.txtPortInput); - this.Controls.Add(this.txtIpAddress); - this.Controls.Add(this.txtIpAddressInput); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "MainForm"; - this.Text = "EasyModbus Client"; - this.Load += new System.EventHandler(this.MainForm_Load); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - private System.Windows.Forms.ListBox lsbAnswerFromServer; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.ComboBox cbbSelctionModbus; - private System.Windows.Forms.Label txtCOMPort; - private System.Windows.Forms.ComboBox cbbSelectComPort; - private System.Windows.Forms.Label txtSlaveAddress; - private System.Windows.Forms.TextBox txtSlaveAddressInput; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.Button btnPrepareCoils; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button btnWriteMultipleRegisters; - private System.Windows.Forms.Button btnWriteMultipleCoils; - private System.Windows.Forms.Button btnWriteSingleRegister; - private System.Windows.Forms.Button btnWriteSingleCoil; - private System.Windows.Forms.TextBox txtCoilValue; - private System.Windows.Forms.TextBox txtRegisterValue; - private System.Windows.Forms.Button btnClear; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.Label lblReadOperations; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.Button button4; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.TextBox txtStartingAddressOutput; - private System.Windows.Forms.ListBox lsbWriteToServer; - private System.Windows.Forms.Label lblParity; - private System.Windows.Forms.Label lblStopbits; - private System.Windows.Forms.ComboBox cbbParity; - private System.Windows.Forms.ComboBox cbbStopbits; - private System.Windows.Forms.TextBox txtBaudrate; - private System.Windows.Forms.Label lblBaudrate; - private System.Windows.Forms.TextBox txtConnectedStatus; - } -} diff --git a/EasyModbusClientExample/MainForm.cs b/EasyModbusClientExample/MainForm.cs deleted file mode 100644 index d374705..0000000 --- a/EasyModbusClientExample/MainForm.cs +++ /dev/null @@ -1,512 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Threading; -using System.Windows.Forms; - -namespace EasyModbusClientExample -{ - /// - /// Description of MainForm. - /// - public partial class MainForm : Form - { - private EasyModbus.ModbusClient modbusClient; - public MainForm() - { - // - // The InitializeComponent() call is required for Windows Forms designer support. - // - InitializeComponent(); - - modbusClient = new EasyModbus.ModbusClient(); - modbusClient.ReceiveDataChanged += new EasyModbus.ModbusClient.ReceiveDataChangedHandler(UpdateReceiveData); - modbusClient.SendDataChanged += new EasyModbus.ModbusClient.SendDataChangedHandler(UpdateSendData); - modbusClient.ConnectedChanged += new EasyModbus.ModbusClient.ConnectedChangedHandler(UpdateConnectedChanged); - // modbusClient.LogFileFilename = "logFiletxt.txt"; - - //modbusClient.Baudrate = 9600; - //modbusClient.UnitIdentifier = 2; - - } - - string receiveData = null; - - void UpdateReceiveData(object sender) - { - receiveData = "Rx: " + BitConverter.ToString(modbusClient.receiveData).Replace("-", " ") + System.Environment.NewLine; - Thread thread = new Thread(updateReceiveTextBox); - thread.Start(); - } - delegate void UpdateReceiveDataCallback(); - void updateReceiveTextBox() - { - if (textBox1.InvokeRequired) - { - UpdateReceiveDataCallback d = new UpdateReceiveDataCallback(updateReceiveTextBox); - this.Invoke(d, new object[] { }); - } - else - { - textBox1.AppendText(receiveData); - } - } - - string sendData = null; - void UpdateSendData(object sender) - { - sendData = "Tx: " + BitConverter.ToString(modbusClient.sendData).Replace("-", " ") + System.Environment.NewLine; - Thread thread = new Thread(updateSendTextBox); - thread.Start(); - - } - - void updateSendTextBox() - { - if (textBox1.InvokeRequired) - { - UpdateReceiveDataCallback d = new UpdateReceiveDataCallback(updateSendTextBox); - this.Invoke(d, new object[] { }); - } - else - { - textBox1.AppendText(sendData); - } - } - - void BtnConnectClick(object sender, EventArgs e) - { - modbusClient.IPAddress = txtIpAddressInput.Text; - modbusClient.Port = int.Parse(txtPortInput.Text); - modbusClient.Connect(); - } - void BtnReadCoilsClick(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - bool[] serverResponse = modbusClient.ReadCoils(int.Parse(txtStartingAddressInput.Text)-1, int.Parse(txtNumberOfValuesInput.Text)); - lsbAnswerFromServer.Items.Clear(); - for (int i = 0; i < serverResponse.Length; i++) - { - lsbAnswerFromServer.Items.Add(serverResponse[i]); - } - } - catch (Exception exc) - { - MessageBox.Show(exc.Message,"Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnReadDiscreteInputs_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - bool[] serverResponse = modbusClient.ReadDiscreteInputs(int.Parse(txtStartingAddressInput.Text)-1, int.Parse(txtNumberOfValuesInput.Text)); - lsbAnswerFromServer.Items.Clear(); - for (int i = 0; i < serverResponse.Length; i++) - { - lsbAnswerFromServer.Items.Add(serverResponse[i]); - } - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnReadHoldingRegisters_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - - int[] serverResponse = modbusClient.ReadHoldingRegisters(int.Parse(txtStartingAddressInput.Text)-1, int.Parse(txtNumberOfValuesInput.Text)); - - lsbAnswerFromServer.Items.Clear(); - for (int i = 0; i < serverResponse.Length; i++) - { - lsbAnswerFromServer.Items.Add(serverResponse[i]); - - } - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnReadInputRegisters_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - int[] serverResponse = modbusClient.ReadInputRegisters(int.Parse(txtStartingAddressInput.Text)-1, int.Parse(txtNumberOfValuesInput.Text)); - - lsbAnswerFromServer.Items.Clear(); - for (int i = 0; i < serverResponse.Length; i++) - { - lsbAnswerFromServer.Items.Add(serverResponse[i]); - } - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void pictureBox1_Click(object sender, EventArgs e) - { - System.Diagnostics.Process.Start("http://www.EasyModbusTCP.net");  - } - - private void cbbSelctionModbus_SelectedIndexChanged(object sender, EventArgs e) - { - if (modbusClient.Connected) - modbusClient.Disconnect(); - - if (cbbSelctionModbus.SelectedIndex == 0) - { - - txtIpAddress.Visible = true; - txtIpAddressInput.Visible = true; - txtPort.Visible = true; - txtPortInput.Visible = true; - txtCOMPort.Visible = false; - cbbSelectComPort.Visible = false; - txtSlaveAddress.Visible = false; - txtSlaveAddressInput.Visible = false; - lblBaudrate.Visible = false; - lblParity.Visible = false; - lblStopbits.Visible = false; - txtBaudrate.Visible = false; - cbbParity.Visible = false; - cbbStopbits.Visible = false; - } - if (cbbSelctionModbus.SelectedIndex == 1) - { - cbbSelectComPort.SelectedIndex = 0; - cbbParity.SelectedIndex = 0; - cbbStopbits.SelectedIndex = 0; - if (cbbSelectComPort.SelectedText == "") - cbbSelectComPort.SelectedItem.ToString(); - txtIpAddress.Visible = false; - txtIpAddressInput.Visible = false; - txtPort.Visible = false; - txtPortInput.Visible = false; - txtCOMPort.Visible = true; - cbbSelectComPort.Visible = true; - txtSlaveAddress.Visible = true; - txtSlaveAddressInput.Visible = true; - lblBaudrate.Visible = true; - lblParity.Visible = true; - lblStopbits.Visible = true; - txtBaudrate.Visible = true; - cbbParity.Visible = true; - cbbStopbits.Visible = true; - - - } - } - - private void cbbSelectComPort_SelectedIndexChanged(object sender, EventArgs e) - { - if (modbusClient.Connected) - modbusClient.Disconnect(); - modbusClient.SerialPort = cbbSelectComPort.SelectedItem.ToString(); - - modbusClient.UnitIdentifier = byte.Parse(txtSlaveAddressInput.Text); - - } - - void TxtSlaveAddressInputTextChanged(object sender, EventArgs e) - { - try - { - modbusClient.UnitIdentifier = byte.Parse(txtSlaveAddressInput.Text); - } - catch (FormatException) - { } - } - - bool listBoxPrepareCoils = false; - private void btnPrepareCoils_Click(object sender, EventArgs e) - { - if (!listBoxPrepareCoils) - { - lsbAnswerFromServer.Items.Clear(); - } - listBoxPrepareCoils = true; - listBoxPrepareRegisters = false; - lsbWriteToServer.Items.Add(txtCoilValue.Text); - - } - bool listBoxPrepareRegisters = false; - private void button1_Click(object sender, EventArgs e) - { - if (!listBoxPrepareRegisters) - { - lsbAnswerFromServer.Items.Clear(); - } - listBoxPrepareRegisters = true; - listBoxPrepareCoils = false; - lsbWriteToServer.Items.Add(int.Parse(txtRegisterValue.Text)); - } - - private void btnWriteSingleCoil_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - bool coilsToSend = false; - - coilsToSend = bool.Parse(lsbWriteToServer.Items[0].ToString()); - - - modbusClient.WriteSingleCoil(int.Parse(txtStartingAddressOutput.Text) - 1, coilsToSend); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnWriteSingleRegister_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - int registerToSend = 0; - - registerToSend = int.Parse(lsbWriteToServer.Items[0].ToString()); - - - modbusClient.WriteSingleRegister(int.Parse(txtStartingAddressOutput.Text) - 1, registerToSend); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnWriteMultipleCoils_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - bool[] coilsToSend = new bool[lsbWriteToServer.Items.Count]; - - for (int i = 0; i < lsbWriteToServer.Items.Count; i++) - { - - coilsToSend[i] = bool.Parse(lsbWriteToServer.Items[i].ToString()); - } - - - modbusClient.WriteMultipleCoils(int.Parse(txtStartingAddressOutput.Text) - 1, coilsToSend); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void btnWriteMultipleRegisters_Click(object sender, EventArgs e) - { - try - { - if (!modbusClient.Connected) - { - button3_Click(null, null); - } - - int[] registersToSend = new int[lsbWriteToServer.Items.Count]; - - for (int i = 0; i < lsbWriteToServer.Items.Count; i++) - { - - registersToSend[i] = int.Parse(lsbWriteToServer.Items[i].ToString()); - } - - - modbusClient.WriteMultipleRegisters(int.Parse(txtStartingAddressOutput.Text) - 1, registersToSend); - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void lsbAnswerFromServer_DoubleClick(object sender, EventArgs e) - { - int rowindex = lsbAnswerFromServer.SelectedIndex; - - - - - - } - - private void txtCoilValue_DoubleClick(object sender, EventArgs e) - { - if (txtCoilValue.Text.Equals("FALSE")) - txtCoilValue.Text = "TRUE"; - else - txtCoilValue.Text = "FALSE"; - } - - private void btnClear_Click(object sender, EventArgs e) - { - lsbWriteToServer.Items.Clear(); - } - - private void button2_Click(object sender, EventArgs e) - { - int rowindex = lsbWriteToServer.SelectedIndex; - if(rowindex >= 0) - lsbWriteToServer.Items.RemoveAt(rowindex); - } - - private void MainForm_Load(object sender, EventArgs e) - { - - } - - private void textBox1_TextChanged(object sender, EventArgs e) - { - - } - - private void txtRegisterValue_TextChanged(object sender, EventArgs e) - { - - } - - private void button3_Click(object sender, EventArgs e) - { - try - { - if (modbusClient.Connected) - modbusClient.Disconnect(); - if (cbbSelctionModbus.SelectedIndex == 0) - { - - - modbusClient.IPAddress = txtIpAddressInput.Text; - modbusClient.Port = int.Parse(txtPortInput.Text); - modbusClient.SerialPort = null; - //modbusClient.receiveDataChanged += new EasyModbus.ModbusClient.ReceiveDataChanged(UpdateReceiveData); - //modbusClient.sendDataChanged += new EasyModbus.ModbusClient.SendDataChanged(UpdateSendData); - //modbusClient.connectedChanged += new EasyModbus.ModbusClient.ConnectedChanged(UpdateConnectedChanged); - - modbusClient.Connect(); - } - if (cbbSelctionModbus.SelectedIndex == 1) - { - modbusClient.SerialPort = cbbSelectComPort.SelectedItem.ToString(); - - modbusClient.UnitIdentifier = byte.Parse(txtSlaveAddressInput.Text); - modbusClient.Baudrate = int.Parse(txtBaudrate.Text); - if (cbbParity.SelectedIndex == 0) - modbusClient.Parity = System.IO.Ports.Parity.Even; - if (cbbParity.SelectedIndex == 1) - modbusClient.Parity = System.IO.Ports.Parity.Odd; - if (cbbParity.SelectedIndex == 2) - modbusClient.Parity = System.IO.Ports.Parity.None; - - if (cbbStopbits.SelectedIndex == 0) - modbusClient.StopBits = System.IO.Ports.StopBits.One; - if (cbbStopbits.SelectedIndex == 1) - modbusClient.StopBits = System.IO.Ports.StopBits.OnePointFive; - if (cbbStopbits.SelectedIndex == 2) - modbusClient.StopBits = System.IO.Ports.StopBits.Two; - - modbusClient.Connect(); - } - } - catch (Exception exc) - { - MessageBox.Show(exc.Message, "Unable to connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void UpdateConnectedChanged(object sender) - { - if (modbusClient.Connected) - { - txtConnectedStatus.Text = "Connected to Server"; - txtConnectedStatus.BackColor = Color.Green; - } - else - { - txtConnectedStatus.Text = "Not Connected to Server"; - txtConnectedStatus.BackColor = Color.Red; - } - } - - private void button4_Click(object sender, EventArgs e) - { - modbusClient.Disconnect(); - } - - private void txtBaudrate_TextChanged(object sender, EventArgs e) - { - if (modbusClient.Connected) - modbusClient.Disconnect(); - modbusClient.Baudrate = int.Parse(txtBaudrate.Text); - - - } - - } -} diff --git a/EasyModbusClientExample/MainForm.resx b/EasyModbusClientExample/MainForm.resx deleted file mode 100644 index 1d9a2be..0000000 --- a/EasyModbusClientExample/MainForm.resx +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAEAVDgAAAEAIABITAAAFgAAACgAAABUAAAAcAAAAAEAIAAAAAAAgEkAAMMOAADDDgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfYRaGAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAJ9fHwieYBWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACpVBwJnmAaHZ1h - GCqgXxQzn18WOJ9fFTueYBQylFUVDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJxiF0GcXxZoAAAAAAAA - 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 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlmAAWfYhVTn2AWs55gFsGeYBbBnWEWuJ9fF0AAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFs05FhbOvRYWzuIWFs6zFxfPKwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ9fF0ueYBa3nmAWwZ5gFsGeYBW7n2EWc6BeFSMAAAAAAAAAAAAA - AAATE8QNFhbPcBYWzukXF8+QGBjNNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfXw8Qn2IXWJ9g - FqueYBbBnmAWwZ5gFsGeYBWZnmAaHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACiXBcWn2EVgJ9gFsCeYBbBnmAWwZ5gFsGfYBaen18XY6FiFDGZZhkKAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKpVAAObXBUknmAVUp5gFoqfYRa9nmAWwZ5gFsGeYBbBnmAWtJ1hFVSqVQADAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJtdGCmfXxeFnmAWv55g - FsGeYBbBnmAWwZ5gFsGeYBbAn2AWqp9hFpOdYRaGn18VgJ1fF4OeYBeOnmAWop5gF7yeYBbBnmAWwZ5g - FsGeYBbBnmAWwZ5gFrOdXxdjnGITDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo2UUGZ1hF2GeYBahnmAWwZ5gFsGeYBbBnmAWwZ5g - FsGeYBbBnmAWwZ5gFsGeYBbBnmAWwZ5gFsGeYBbBnmAWwZ9gF7ueYBaJoGIVRpFtJAcAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAm2MWF55gFkWdXxVrnmAWiZ9gFp6eYBasnmAWs55gF7GdYRaonmAVl59h - Fn6fXxVdoWIYNJ9fHwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////v//////8AD//////P///gH/ - 8AD//////P//wAB/8AD4AB//+P//AAB/8ADwAB/x8f/8H/w/8ADwAB/A4//4//4/8ADwAB/AR//z//4/ - 8ADwAB/MD/////4/8ADwAB/ED/////4/8ADxER/AH/////4/8ADx3/+AB/////4/8ADx//8IAf////4/ - 8ADx+/8cQPB///4/8ADx8x48cCAf//4f8ADx8AA4/AAP//8H8ADx4AB4/weP//+D8AD/4fBx/4+P///B - 8AD/w/xx/5/H///h8AD/h54xwB/H///w8AD/jw4wAA/P///w8AD/ng8AAY+P///h8AD/ng8Af4AP///h - 8AD/GAMT/8Af///D8AD/lAER/8B////D8AD/kQkR/4j///+H8AD/gAAR/wj///+H8AD/hAYB/xj///8P - 8AD/w/wB/jj///8P8AD/4fBgfDj///8f8AD/8ADwAHj///8f8AD/+AP4AHj///4f8AD//h/4hHif//4f - 8AD//j/4DH4H//4f8AD//j/8AEAH//4f8AD//n/wAAAD//4/8AD//H+AAIAD//w/8AD//HwCDwwH//w/ - 8AD/+GAPDwwH//g/8AD/4AB/h4Af//B/8AD/4AP/g4AH/+D/8AD/4h//wMAH/8H/8AD/4j//4HMj/wP/ - 8AD/4D//8B8H/Af/8AD/8H///AcH8A//8AD//////gB/AB//8AD//////4AAAH//8AD//////+AAAf// - 8AD///////wAD///8AD/////////////8AD/////////////8AD/////////////8AD///////////// - 8AD/////////////8AD/////////////8AD/////////////8AD/////////////8AA= - - - \ No newline at end of file diff --git a/EasyModbusClientExample/Program.cs b/EasyModbusClientExample/Program.cs deleted file mode 100644 index da22046..0000000 --- a/EasyModbusClientExample/Program.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Windows.Forms; - -namespace EasyModbusClientExample -{ - /// - /// Class with program entry point. - /// - internal sealed class Program - { - /// - /// Program entry point. - /// - [STAThread] - private static void Main(string[] args) - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm()); - } - - } -} diff --git a/EasyModbusClientExample/Properties/AssemblyInfo.cs b/EasyModbusClientExample/Properties/AssemblyInfo.cs deleted file mode 100644 index 553e4e1..0000000 --- a/EasyModbusClientExample/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -#region Using directives - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("EasyModbusClientExample")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Stefan Rossmann Engineering Solutions")] -[assembly: AssemblyProduct("EasyModbusClientExample")] -[assembly: AssemblyCopyright("Copyright 2018-2020")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible(false)] - -// The assembly version has following format : -// -// Major.Minor.Build.Revision -// -// You can specify all the values or you can use the default the Revision and -// Build Numbers by using the '*' as shown below: -[assembly: AssemblyVersion("5.6.0")] diff --git a/EasyModbusClientExample/Properties/Resources.Designer.cs b/EasyModbusClientExample/Properties/Resources.Designer.cs deleted file mode 100644 index 71a65cc..0000000 --- a/EasyModbusClientExample/Properties/Resources.Designer.cs +++ /dev/null @@ -1,143 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace EasyModbusClientExample.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EasyModbusClientExample.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap arrow_1 { - get { - object obj = ResourceManager.GetObject("arrow_1", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap arrow_2 { - get { - object obj = ResourceManager.GetObject("arrow_2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap arrow_left { - get { - object obj = ResourceManager.GetObject("arrow_left", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap circle_delete { - get { - object obj = ResourceManager.GetObject("circle_delete", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap circle_delete1 { - get { - object obj = ResourceManager.GetObject("circle_delete1", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap circle_minus { - get { - object obj = ResourceManager.GetObject("circle_minus", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap PLCLoggerCompact { - get { - object obj = ResourceManager.GetObject("PLCLoggerCompact", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap small { - get { - object obj = ResourceManager.GetObject("small", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/EasyModbusClientExample/Properties/Resources.resx b/EasyModbusClientExample/Properties/Resources.resx deleted file mode 100644 index 6efff2b..0000000 --- a/EasyModbusClientExample/Properties/Resources.resx +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\arrow_2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\PLCLoggerCompact.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\circle_delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\circle_delete1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\arrow_1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\arrow_left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\circle_minus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\resources\small.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/EasyModbusClientExample/Resources/PLCLoggerCompact.jpg b/EasyModbusClientExample/Resources/PLCLoggerCompact.jpg deleted file mode 100644 index 48d8d88..0000000 Binary files a/EasyModbusClientExample/Resources/PLCLoggerCompact.jpg and /dev/null differ diff --git a/EasyModbusClientExample/Resources/arrow_1.png b/EasyModbusClientExample/Resources/arrow_1.png deleted file mode 100644 index 63aeb17..0000000 Binary files a/EasyModbusClientExample/Resources/arrow_1.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/arrow_2.png b/EasyModbusClientExample/Resources/arrow_2.png deleted file mode 100644 index 5dd7b60..0000000 Binary files a/EasyModbusClientExample/Resources/arrow_2.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/arrow_left.png b/EasyModbusClientExample/Resources/arrow_left.png deleted file mode 100644 index 700d605..0000000 Binary files a/EasyModbusClientExample/Resources/arrow_left.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/circle_delete.png b/EasyModbusClientExample/Resources/circle_delete.png deleted file mode 100644 index 06b0e9b..0000000 Binary files a/EasyModbusClientExample/Resources/circle_delete.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/circle_delete1.png b/EasyModbusClientExample/Resources/circle_delete1.png deleted file mode 100644 index fa28fa5..0000000 Binary files a/EasyModbusClientExample/Resources/circle_delete1.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/circle_minus.png b/EasyModbusClientExample/Resources/circle_minus.png deleted file mode 100644 index 5ba877f..0000000 Binary files a/EasyModbusClientExample/Resources/circle_minus.png and /dev/null differ diff --git a/EasyModbusClientExample/Resources/small.png b/EasyModbusClientExample/Resources/small.png deleted file mode 100644 index 48cf80f..0000000 Binary files a/EasyModbusClientExample/Resources/small.png and /dev/null differ diff --git a/EasyModbusClientExample/app.config b/EasyModbusClientExample/app.config deleted file mode 100644 index eb92298..0000000 --- a/EasyModbusClientExample/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/EasyModbusServerSimulator/EasyModbusServerSimulator.OpenCover.Settings b/EasyModbusServerSimulator/EasyModbusServerSimulator.OpenCover.Settings deleted file mode 100644 index 6f1dade..0000000 --- a/EasyModbusServerSimulator/EasyModbusServerSimulator.OpenCover.Settings +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj b/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj deleted file mode 100644 index 7bd300a..0000000 --- a/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj +++ /dev/null @@ -1,171 +0,0 @@ - - - - {871BD4C1-69F0-45B9-8807-1620E6A896A9} - Debug - AnyCPU - WinExe - EasyModbusServerSimulator - EasyModbusServerSimulator - v4.5 - - - Properties - - - - - 3.5 - false - False - False - False - OnBuildSuccess - False - False - False - obj\$(Configuration)\ - 4 - False - C:\Users\srossmann.CARPENTIER\AppData\Roaming\ICSharpCode\SharpDevelop5\Settings.SourceAnalysis - veröffentlichen\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - x86 - 4194304 - False - Auto - 4096 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - obj\ - Project - - - bin\Release\ - False - None - True - False - TRACE - - - false - - - bin\DebugCommercial3\ - false - - - TRACE;DEBUG;SSL - false - - - oie_ITkzMZD7tnyn.ico - - - - - - - - - - - Exceptions\Exceptions.cs - - - ModbusClient.cs - - - ModbusServer.cs - - - StoreLogData.cs - - - Form - - - Info.cs - - - Form - - - MainForm.cs - - - - - Resources.resx - True - True - - - Form - - - PropertyForm.cs - - - - - - Info.cs - - - MainForm.cs - - - ResXFileCodeGenerator - Never - Resources.Designer.cs - - - PropertyForm.cs - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - - - - - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj.sdsettings b/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj.sdsettings deleted file mode 100644 index 38f7991..0000000 --- a/EasyModbusServerSimulator/EasyModbusServerSimulator.csproj.sdsettings +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/Info.Designer.cs b/EasyModbusServerSimulator/Info.Designer.cs deleted file mode 100644 index cadb14b..0000000 --- a/EasyModbusServerSimulator/Info.Designer.cs +++ /dev/null @@ -1,119 +0,0 @@ -namespace EasyModbusServerSimulator -{ - partial class Info - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Info)); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.lblVersion = new System.Windows.Forms.Label(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.label1 = new System.Windows.Forms.Label(); - this.linkLabel2 = new System.Windows.Forms.LinkLabel(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // pictureBox1 - // - this.pictureBox1.Image = global::EasyModbusServerSimulator.Properties.Resources.small; - this.pictureBox1.Location = new System.Drawing.Point(3, 3); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(183, 92); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; - this.pictureBox1.TabIndex = 6; - this.pictureBox1.TabStop = false; - // - // lblVersion - // - this.lblVersion.AutoSize = true; - this.lblVersion.Location = new System.Drawing.Point(194, 39); - this.lblVersion.Name = "lblVersion"; - this.lblVersion.Size = new System.Drawing.Size(60, 13); - this.lblVersion.TabIndex = 14; - this.lblVersion.Text = "Version 5.6"; - // - // linkLabel1 - // - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(193, 12); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(165, 13); - this.linkLabel1.TabIndex = 13; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "http://www.EasyModbusTCP.net"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(194, 66); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(185, 13); - this.label1.TabIndex = 15; - this.label1.Text = "(c) Rossmann-Engineering 2018-2020"; - this.label1.Click += new System.EventHandler(this.label1_Click); - // - // linkLabel2 - // - this.linkLabel2.AutoSize = true; - this.linkLabel2.Location = new System.Drawing.Point(194, 82); - this.linkLabel2.Name = "linkLabel2"; - this.linkLabel2.Size = new System.Drawing.Size(189, 13); - this.linkLabel2.TabIndex = 16; - this.linkLabel2.TabStop = true; - this.linkLabel2.Text = "http://www.Rossmann-Engineering.de"; - // - // Info - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(388, 103); - this.Controls.Add(this.linkLabel2); - this.Controls.Add(this.label1); - this.Controls.Add(this.lblVersion); - this.Controls.Add(this.linkLabel1); - this.Controls.Add(this.pictureBox1); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "Info"; - this.ShowIcon = false; - this.Text = "Info"; - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.Label lblVersion; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.LinkLabel linkLabel2; - } -} \ No newline at end of file diff --git a/EasyModbusServerSimulator/Info.cs b/EasyModbusServerSimulator/Info.cs deleted file mode 100644 index 9adee1d..0000000 --- a/EasyModbusServerSimulator/Info.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using System.Reflection; - -namespace EasyModbusServerSimulator -{ - public partial class Info : Form - { - public Info() - { - InitializeComponent(); - Assembly.GetExecutingAssembly().GetName().Version.ToString(); - lblVersion.Text = "Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); - } - - private void label1_Click(object sender, EventArgs e) - { - - } - } -} diff --git a/EasyModbusServerSimulator/Info.resx b/EasyModbusServerSimulator/Info.resx deleted file mode 100644 index 7326cbb..0000000 --- a/EasyModbusServerSimulator/Info.resx +++ /dev/null @@ -1,400 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAEAQEAAAAEAIAAoQAAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAADgAAAAhwAAAAAAAAAAAAAAAAAAAMEAAACaAAAAKQAAAAAAAAApAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAKQAAAJoAAADBAAAAAAAAAIcAAACaAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmgAAAIcAAADgAAAAKQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ACkAAADgAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAOAAAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD//wAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP//AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A//8AAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A//8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//wAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAACkAAADgAAAAhwAAAJoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaAAAAhwAAAAAAAADBAAAAmgAAACkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkAAACaAAAAwQAAAAAAAAAAAAAAAAAA - AIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA4AAAAP8AAADgAAAAhwAA - AAAAAAAA - - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/MainForm.Designer.cs b/EasyModbusServerSimulator/MainForm.Designer.cs deleted file mode 100644 index d13ea2f..0000000 --- a/EasyModbusServerSimulator/MainForm.Designer.cs +++ /dev/null @@ -1,788 +0,0 @@ -namespace EasyModbusServerSimulator -{ - partial class MainForm - { - /// - /// Erforderliche Designervariable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Verwendete Ressourcen bereinigen. - /// - /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Vom Windows Form-Designer generierter Code - - /// - /// Erforderliche Methode für die Designerunterstützung. - /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Value = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.vScrollBar2 = new System.Windows.Forms.VScrollBar(); - this.dataGridView2 = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.tabPage3 = new System.Windows.Forms.TabPage(); - this.vScrollBar3 = new System.Windows.Forms.VScrollBar(); - this.dataGridView3 = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.tabPage4 = new System.Windows.Forms.TabPage(); - this.vScrollBar4 = new System.Windows.Forms.VScrollBar(); - this.dataGridView4 = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.label4 = new System.Windows.Forms.Label(); - this.listBox1 = new System.Windows.Forms.ListBox(); - this.label5 = new System.Windows.Forms.Label(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.lblVersion = new System.Windows.Forms.Label(); - this.checkBox2 = new System.Windows.Forms.CheckBox(); - this.checkBox3 = new System.Windows.Forms.CheckBox(); - this.checkBox4 = new System.Windows.Forms.CheckBox(); - this.checkBox5 = new System.Windows.Forms.CheckBox(); - this.checkBox6 = new System.Windows.Forms.CheckBox(); - this.checkBox7 = new System.Windows.Forms.CheckBox(); - this.checkBox8 = new System.Windows.Forms.CheckBox(); - this.checkBox9 = new System.Windows.Forms.CheckBox(); - this.btnProperties = new System.Windows.Forms.Button(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.form1BindingSource = new System.Windows.Forms.BindingSource(this.components); - this.easyModbusTCPServerBindingSource = new System.Windows.Forms.BindingSource(this.components); - this.checkBox10 = new System.Windows.Forms.CheckBox(); - this.panel1 = new System.Windows.Forms.Panel(); - this.performanceCounter1 = new System.Diagnostics.PerformanceCounter(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.setupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.infoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.tabControl1.SuspendLayout(); - this.tabPage1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - this.tabPage2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit(); - this.tabPage3.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView3)).BeginInit(); - this.tabPage4.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView4)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.form1BindingSource)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.easyModbusTCPServerBindingSource)).BeginInit(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).BeginInit(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // tabControl1 - // - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Controls.Add(this.tabPage2); - this.tabControl1.Controls.Add(this.tabPage3); - this.tabControl1.Controls.Add(this.tabPage4); - this.tabControl1.Location = new System.Drawing.Point(588, 63); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(307, 502); - this.tabControl1.TabIndex = 0; - this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); - this.tabControl1.MouseEnter += new System.EventHandler(this.tabControl1_MouseEnter); - this.tabControl1.MouseLeave += new System.EventHandler(this.tabControl1_MouseLeave); - // - // tabPage1 - // - this.tabPage1.Controls.Add(this.vScrollBar1); - this.tabPage1.Controls.Add(this.dataGridView1); - this.tabPage1.Location = new System.Drawing.Point(4, 22); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(299, 476); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "Discrete Inputs"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // vScrollBar1 - // - this.vScrollBar1.Cursor = System.Windows.Forms.Cursors.Default; - this.vScrollBar1.LargeChange = 20; - this.vScrollBar1.Location = new System.Drawing.Point(264, 2); - this.vScrollBar1.Maximum = 65534; - this.vScrollBar1.Minimum = 1; - this.vScrollBar1.Name = "vScrollBar1"; - this.vScrollBar1.Padding = new System.Windows.Forms.Padding(1); - this.vScrollBar1.Size = new System.Drawing.Size(21, 473); - this.vScrollBar1.TabIndex = 1; - this.vScrollBar1.Value = 1; - this.vScrollBar1.ValueChanged += new System.EventHandler(this.vScrollBar1_ValueChanged); - // - // dataGridView1 - // - this.dataGridView1.AllowUserToAddRows = false; - this.dataGridView1.AllowUserToDeleteRows = false; - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.Column1, - this.Value}); - dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle2; - this.dataGridView1.Location = new System.Drawing.Point(53, 2); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.ReadOnly = true; - this.dataGridView1.RowHeadersVisible = false; - this.dataGridView1.ShowEditingIcon = false; - this.dataGridView1.Size = new System.Drawing.Size(204, 473); - this.dataGridView1.TabIndex = 0; - this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick); - // - // Column1 - // - this.Column1.HeaderText = "Address"; - this.Column1.Name = "Column1"; - this.Column1.ReadOnly = true; - // - // Value - // - dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Value.DefaultCellStyle = dataGridViewCellStyle1; - this.Value.HeaderText = "Value"; - this.Value.Name = "Value"; - this.Value.ReadOnly = true; - // - // tabPage2 - // - this.tabPage2.Controls.Add(this.vScrollBar2); - this.tabPage2.Controls.Add(this.dataGridView2); - this.tabPage2.Location = new System.Drawing.Point(4, 22); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(299, 476); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "Coils"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // vScrollBar2 - // - this.vScrollBar2.Cursor = System.Windows.Forms.Cursors.Default; - this.vScrollBar2.LargeChange = 20; - this.vScrollBar2.Location = new System.Drawing.Point(264, 2); - this.vScrollBar2.Maximum = 65534; - this.vScrollBar2.Minimum = 1; - this.vScrollBar2.Name = "vScrollBar2"; - this.vScrollBar2.Padding = new System.Windows.Forms.Padding(1); - this.vScrollBar2.Size = new System.Drawing.Size(21, 473); - this.vScrollBar2.TabIndex = 2; - this.vScrollBar2.Value = 1; - this.vScrollBar2.ValueChanged += new System.EventHandler(this.vScrollBar2_ValueChanged); - // - // dataGridView2 - // - this.dataGridView2.AllowUserToAddRows = false; - this.dataGridView2.AllowUserToDeleteRows = false; - this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView2.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn1, - this.dataGridViewTextBoxColumn2}); - dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridView2.DefaultCellStyle = dataGridViewCellStyle4; - this.dataGridView2.Location = new System.Drawing.Point(53, 2); - this.dataGridView2.Name = "dataGridView2"; - this.dataGridView2.ReadOnly = true; - this.dataGridView2.RowHeadersVisible = false; - this.dataGridView2.ShowEditingIcon = false; - this.dataGridView2.Size = new System.Drawing.Size(204, 473); - this.dataGridView2.TabIndex = 1; - this.dataGridView2.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView2_CellDoubleClick); - this.dataGridView2.MouseEnter += new System.EventHandler(this.dataGridView2_MouseEnter); - this.dataGridView2.MouseLeave += new System.EventHandler(this.dataGridView2_MouseLeave); - // - // dataGridViewTextBoxColumn1 - // - this.dataGridViewTextBoxColumn1.HeaderText = "Address"; - this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; - this.dataGridViewTextBoxColumn1.ReadOnly = true; - // - // dataGridViewTextBoxColumn2 - // - dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.dataGridViewTextBoxColumn2.DefaultCellStyle = dataGridViewCellStyle3; - this.dataGridViewTextBoxColumn2.HeaderText = "Value"; - this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; - this.dataGridViewTextBoxColumn2.ReadOnly = true; - // - // tabPage3 - // - this.tabPage3.Controls.Add(this.vScrollBar3); - this.tabPage3.Controls.Add(this.dataGridView3); - this.tabPage3.Location = new System.Drawing.Point(4, 22); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Padding = new System.Windows.Forms.Padding(3); - this.tabPage3.Size = new System.Drawing.Size(299, 476); - this.tabPage3.TabIndex = 2; - this.tabPage3.Text = "Input Registers"; - this.tabPage3.UseVisualStyleBackColor = true; - // - // vScrollBar3 - // - this.vScrollBar3.Cursor = System.Windows.Forms.Cursors.Default; - this.vScrollBar3.LargeChange = 20; - this.vScrollBar3.Location = new System.Drawing.Point(264, 2); - this.vScrollBar3.Maximum = 65534; - this.vScrollBar3.Minimum = 1; - this.vScrollBar3.Name = "vScrollBar3"; - this.vScrollBar3.Padding = new System.Windows.Forms.Padding(1); - this.vScrollBar3.Size = new System.Drawing.Size(21, 473); - this.vScrollBar3.TabIndex = 2; - this.vScrollBar3.Value = 1; - this.vScrollBar3.ValueChanged += new System.EventHandler(this.vScrollBar3_ValueChanged); - // - // dataGridView3 - // - this.dataGridView3.AllowUserToAddRows = false; - this.dataGridView3.AllowUserToDeleteRows = false; - this.dataGridView3.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView3.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn3, - this.dataGridViewTextBoxColumn4}); - dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridView3.DefaultCellStyle = dataGridViewCellStyle5; - this.dataGridView3.Location = new System.Drawing.Point(53, 2); - this.dataGridView3.Name = "dataGridView3"; - this.dataGridView3.RowHeadersVisible = false; - this.dataGridView3.ShowEditingIcon = false; - this.dataGridView3.Size = new System.Drawing.Size(204, 473); - this.dataGridView3.TabIndex = 1; - this.dataGridView3.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView3_CellValueChanged); - // - // dataGridViewTextBoxColumn3 - // - this.dataGridViewTextBoxColumn3.HeaderText = "Address"; - this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; - this.dataGridViewTextBoxColumn3.ReadOnly = true; - // - // dataGridViewTextBoxColumn4 - // - this.dataGridViewTextBoxColumn4.HeaderText = "Value"; - this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; - // - // tabPage4 - // - this.tabPage4.Controls.Add(this.vScrollBar4); - this.tabPage4.Controls.Add(this.dataGridView4); - this.tabPage4.Location = new System.Drawing.Point(4, 22); - this.tabPage4.Name = "tabPage4"; - this.tabPage4.Padding = new System.Windows.Forms.Padding(3); - this.tabPage4.Size = new System.Drawing.Size(299, 476); - this.tabPage4.TabIndex = 3; - this.tabPage4.Text = "Holding Registers"; - this.tabPage4.UseVisualStyleBackColor = true; - // - // vScrollBar4 - // - this.vScrollBar4.Cursor = System.Windows.Forms.Cursors.Default; - this.vScrollBar4.LargeChange = 20; - this.vScrollBar4.Location = new System.Drawing.Point(264, 2); - this.vScrollBar4.Maximum = 65534; - this.vScrollBar4.Minimum = 1; - this.vScrollBar4.Name = "vScrollBar4"; - this.vScrollBar4.Padding = new System.Windows.Forms.Padding(1); - this.vScrollBar4.Size = new System.Drawing.Size(21, 473); - this.vScrollBar4.TabIndex = 2; - this.vScrollBar4.Value = 1; - this.vScrollBar4.ValueChanged += new System.EventHandler(this.vScrollBar4_ValueChanged); - // - // dataGridView4 - // - this.dataGridView4.AllowUserToAddRows = false; - this.dataGridView4.AllowUserToDeleteRows = false; - this.dataGridView4.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView4.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn5, - this.dataGridViewTextBoxColumn6}); - dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridView4.DefaultCellStyle = dataGridViewCellStyle6; - this.dataGridView4.Location = new System.Drawing.Point(53, 2); - this.dataGridView4.Name = "dataGridView4"; - this.dataGridView4.RowHeadersVisible = false; - this.dataGridView4.ShowEditingIcon = false; - this.dataGridView4.Size = new System.Drawing.Size(204, 473); - this.dataGridView4.TabIndex = 1; - this.dataGridView4.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView4_CellValueChanged); - this.dataGridView4.MouseEnter += new System.EventHandler(this.dataGridView4_MouseEnter); - this.dataGridView4.MouseLeave += new System.EventHandler(this.dataGridView4_MouseLeave); - // - // dataGridViewTextBoxColumn5 - // - this.dataGridViewTextBoxColumn5.HeaderText = "Address"; - this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; - this.dataGridViewTextBoxColumn5.ReadOnly = true; - // - // dataGridViewTextBoxColumn6 - // - this.dataGridViewTextBoxColumn6.HeaderText = "Value"; - this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; - // - // numericUpDown1 - // - this.numericUpDown1.Location = new System.Drawing.Point(762, 37); - this.numericUpDown1.Maximum = new decimal(new int[] { - 65515, - 0, - 0, - 0}); - this.numericUpDown1.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.numericUpDown1.Name = "numericUpDown1"; - this.numericUpDown1.Size = new System.Drawing.Size(83, 20); - this.numericUpDown1.TabIndex = 1; - this.numericUpDown1.Value = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(669, 41); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(87, 13); - this.label1.TabIndex = 2; - this.label1.Text = "Move to Address"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(12, 115); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(143, 13); - this.label2.TabIndex = 3; - this.label2.Text = "Number of connected clients"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(152, 115); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(13, 13); - this.label3.TabIndex = 4; - this.label3.Text = "0"; - // - // linkLabel1 - // - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(218, 82); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(165, 13); - this.linkLabel1.TabIndex = 6; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "http://www.EasyModbusTCP.net"; - this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); - this.label4.Location = new System.Drawing.Point(235, 29); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(361, 20); - this.label4.TabIndex = 7; - this.label4.Text = "...Modbus-TCP Server Listening (Port 502)..."; - // - // listBox1 - // - this.listBox1.FormattingEnabled = true; - this.listBox1.HorizontalScrollbar = true; - this.listBox1.Location = new System.Drawing.Point(2, 3); - this.listBox1.Name = "listBox1"; - this.listBox1.Size = new System.Drawing.Size(571, 160); - this.listBox1.TabIndex = 8; - this.listBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseMove); - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label5.Location = new System.Drawing.Point(15, 133); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(121, 13); - this.label5.TabIndex = 9; - this.label5.Text = "Protocol Information"; - // - // textBox1 - // - this.textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox1.Location = new System.Drawing.Point(15, 335); - this.textBox1.Multiline = true; - this.textBox1.Name = "textBox1"; - this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(314, 187); - this.textBox1.TabIndex = 10; - this.textBox1.Text = resources.GetString("textBox1.Text"); - // - // checkBox1 - // - this.checkBox1.AutoSize = true; - this.checkBox1.Checked = true; - this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox1.Location = new System.Drawing.Point(428, 129); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(158, 17); - this.checkBox1.TabIndex = 11; - this.checkBox1.Text = "Show Protocol Informations "; - this.checkBox1.UseVisualStyleBackColor = true; - this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); - // - // lblVersion - // - this.lblVersion.AutoSize = true; - this.lblVersion.Location = new System.Drawing.Point(219, 99); - this.lblVersion.Name = "lblVersion"; - this.lblVersion.Size = new System.Drawing.Size(60, 13); - this.lblVersion.TabIndex = 12; - this.lblVersion.Text = "Version 5.6"; - // - // checkBox2 - // - this.checkBox2.AutoSize = true; - this.checkBox2.Checked = true; - this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox2.Location = new System.Drawing.Point(29, 371); - this.checkBox2.Name = "checkBox2"; - this.checkBox2.Size = new System.Drawing.Size(15, 14); - this.checkBox2.TabIndex = 13; - this.checkBox2.UseVisualStyleBackColor = true; - this.checkBox2.CheckedChanged += new System.EventHandler(this.checkBox2_CheckedChanged); - // - // checkBox3 - // - this.checkBox3.AutoSize = true; - this.checkBox3.Checked = true; - this.checkBox3.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox3.Location = new System.Drawing.Point(29, 387); - this.checkBox3.Name = "checkBox3"; - this.checkBox3.Size = new System.Drawing.Size(15, 14); - this.checkBox3.TabIndex = 14; - this.checkBox3.UseVisualStyleBackColor = true; - this.checkBox3.CheckedChanged += new System.EventHandler(this.checkBox3_CheckedChanged); - // - // checkBox4 - // - this.checkBox4.AutoSize = true; - this.checkBox4.Checked = true; - this.checkBox4.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox4.Location = new System.Drawing.Point(29, 403); - this.checkBox4.Name = "checkBox4"; - this.checkBox4.Size = new System.Drawing.Size(15, 14); - this.checkBox4.TabIndex = 15; - this.checkBox4.UseVisualStyleBackColor = true; - this.checkBox4.CheckedChanged += new System.EventHandler(this.checkBox4_CheckedChanged); - // - // checkBox5 - // - this.checkBox5.AutoSize = true; - this.checkBox5.Checked = true; - this.checkBox5.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox5.Location = new System.Drawing.Point(29, 419); - this.checkBox5.Name = "checkBox5"; - this.checkBox5.Size = new System.Drawing.Size(15, 14); - this.checkBox5.TabIndex = 16; - this.checkBox5.UseVisualStyleBackColor = true; - this.checkBox5.CheckedChanged += new System.EventHandler(this.checkBox5_CheckedChanged); - // - // checkBox6 - // - this.checkBox6.AutoSize = true; - this.checkBox6.Checked = true; - this.checkBox6.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox6.Location = new System.Drawing.Point(29, 435); - this.checkBox6.Name = "checkBox6"; - this.checkBox6.Size = new System.Drawing.Size(15, 14); - this.checkBox6.TabIndex = 17; - this.checkBox6.UseVisualStyleBackColor = true; - this.checkBox6.CheckedChanged += new System.EventHandler(this.checkBox6_CheckedChanged); - // - // checkBox7 - // - this.checkBox7.AutoSize = true; - this.checkBox7.Checked = true; - this.checkBox7.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox7.Location = new System.Drawing.Point(29, 451); - this.checkBox7.Name = "checkBox7"; - this.checkBox7.Size = new System.Drawing.Size(15, 14); - this.checkBox7.TabIndex = 18; - this.checkBox7.UseVisualStyleBackColor = true; - this.checkBox7.CheckedChanged += new System.EventHandler(this.checkBox7_CheckedChanged); - // - // checkBox8 - // - this.checkBox8.AutoSize = true; - this.checkBox8.Checked = true; - this.checkBox8.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox8.Location = new System.Drawing.Point(29, 483); - this.checkBox8.Name = "checkBox8"; - this.checkBox8.Size = new System.Drawing.Size(15, 14); - this.checkBox8.TabIndex = 20; - this.checkBox8.UseVisualStyleBackColor = true; - this.checkBox8.CheckedChanged += new System.EventHandler(this.checkBox8_CheckedChanged); - // - // checkBox9 - // - this.checkBox9.AutoSize = true; - this.checkBox9.Checked = true; - this.checkBox9.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox9.Location = new System.Drawing.Point(29, 467); - this.checkBox9.Name = "checkBox9"; - this.checkBox9.Size = new System.Drawing.Size(15, 14); - this.checkBox9.TabIndex = 19; - this.checkBox9.UseVisualStyleBackColor = true; - this.checkBox9.CheckedChanged += new System.EventHandler(this.checkBox9_CheckedChanged); - // - // btnProperties - // - this.btnProperties.BackgroundImage = global::EasyModbusServerSimulator.Properties.Resources.configure_2; - this.btnProperties.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.btnProperties.Location = new System.Drawing.Point(532, 63); - this.btnProperties.Name = "btnProperties"; - this.btnProperties.Size = new System.Drawing.Size(54, 52); - this.btnProperties.TabIndex = 21; - this.btnProperties.UseVisualStyleBackColor = true; - this.btnProperties.Click += new System.EventHandler(this.btnProperties_Click); - // - // pictureBox1 - // - this.pictureBox1.Image = global::EasyModbusServerSimulator.Properties.Resources.small; - this.pictureBox1.Location = new System.Drawing.Point(12, 27); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(201, 85); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; - this.pictureBox1.TabIndex = 5; - this.pictureBox1.TabStop = false; - this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); - // - // easyModbusTCPServerBindingSource - // - this.easyModbusTCPServerBindingSource.CurrentChanged += new System.EventHandler(this.EasyModbusTCPServerBindingSourceCurrentChanged); - // - // checkBox10 - // - this.checkBox10.AutoSize = true; - this.checkBox10.Checked = true; - this.checkBox10.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox10.Location = new System.Drawing.Point(29, 499); - this.checkBox10.Name = "checkBox10"; - this.checkBox10.Size = new System.Drawing.Size(15, 14); - this.checkBox10.TabIndex = 22; - this.checkBox10.UseVisualStyleBackColor = true; - this.checkBox10.CheckedChanged += new System.EventHandler(this.checkBox10_CheckedChanged); - // - // panel1 - // - this.panel1.Controls.Add(this.listBox1); - this.panel1.Location = new System.Drawing.Point(13, 149); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(573, 180); - this.panel1.TabIndex = 23; - this.panel1.MouseEnter += new System.EventHandler(this.panel1_MouseEnter); - this.panel1.MouseLeave += new System.EventHandler(this.panel1_MouseLeave_1); - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.setupToolStripMenuItem, - this.infoToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(897, 24); - this.menuStrip1.TabIndex = 24; - this.menuStrip1.Text = "menuStrip1"; - // - // setupToolStripMenuItem - // - this.setupToolStripMenuItem.Name = "setupToolStripMenuItem"; - this.setupToolStripMenuItem.Size = new System.Drawing.Size(49, 20); - this.setupToolStripMenuItem.Text = "Setup"; - this.setupToolStripMenuItem.Click += new System.EventHandler(this.setupToolStripMenuItem_Click); - // - // infoToolStripMenuItem - // - this.infoToolStripMenuItem.Name = "infoToolStripMenuItem"; - this.infoToolStripMenuItem.Size = new System.Drawing.Size(40, 20); - this.infoToolStripMenuItem.Text = "Info"; - this.infoToolStripMenuItem.Click += new System.EventHandler(this.infoToolStripMenuItem_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(897, 570); - this.Controls.Add(this.panel1); - this.Controls.Add(this.checkBox10); - this.Controls.Add(this.btnProperties); - this.Controls.Add(this.checkBox8); - this.Controls.Add(this.checkBox9); - this.Controls.Add(this.checkBox7); - this.Controls.Add(this.checkBox6); - this.Controls.Add(this.checkBox5); - this.Controls.Add(this.checkBox4); - this.Controls.Add(this.checkBox3); - this.Controls.Add(this.checkBox2); - this.Controls.Add(this.lblVersion); - this.Controls.Add(this.checkBox1); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.label5); - this.Controls.Add(this.label4); - this.Controls.Add(this.linkLabel1); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.label3); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.Controls.Add(this.numericUpDown1); - this.Controls.Add(this.tabControl1); - this.Controls.Add(this.menuStrip1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MainMenuStrip = this.menuStrip1; - this.Name = "MainForm"; - this.Text = "EasyModbusTCP Server Simulator"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed); - this.Load += new System.EventHandler(this.Form1_Load); - this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseMove); - this.tabControl1.ResumeLayout(false); - this.tabPage1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - this.tabPage2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit(); - this.tabPage3.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView3)).EndInit(); - this.tabPage4.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView4)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.form1BindingSource)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.easyModbusTCPServerBindingSource)).EndInit(); - this.panel1.ResumeLayout(false); - //((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).EndInit(); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.TabPage tabPage3; - private System.Windows.Forms.TabPage tabPage4; - private System.Windows.Forms.BindingSource form1BindingSource; - private System.Windows.Forms.BindingSource easyModbusTCPServerBindingSource; - private System.Windows.Forms.NumericUpDown numericUpDown1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.DataGridView dataGridView2; - private System.Windows.Forms.DataGridView dataGridView3; - private System.Windows.Forms.DataGridView dataGridView4; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.DataGridViewTextBoxColumn Column1; - private System.Windows.Forms.DataGridViewTextBoxColumn Value; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.VScrollBar vScrollBar1; - private System.Windows.Forms.VScrollBar vScrollBar2; - private System.Windows.Forms.VScrollBar vScrollBar3; - private System.Windows.Forms.VScrollBar vScrollBar4; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.ListBox listBox1; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.Label lblVersion; - private System.Windows.Forms.CheckBox checkBox2; - private System.Windows.Forms.CheckBox checkBox3; - private System.Windows.Forms.CheckBox checkBox4; - private System.Windows.Forms.CheckBox checkBox5; - private System.Windows.Forms.CheckBox checkBox6; - private System.Windows.Forms.CheckBox checkBox7; - private System.Windows.Forms.CheckBox checkBox8; - private System.Windows.Forms.CheckBox checkBox9; - private System.Windows.Forms.Button btnProperties; - private System.Windows.Forms.CheckBox checkBox10; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.ToolTip toolTip1; - private System.Diagnostics.PerformanceCounter performanceCounter1; - private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem setupToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem infoToolStripMenuItem; - } -} - diff --git a/EasyModbusServerSimulator/MainForm.cs b/EasyModbusServerSimulator/MainForm.cs deleted file mode 100644 index 78f6dc5..0000000 --- a/EasyModbusServerSimulator/MainForm.cs +++ /dev/null @@ -1,668 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using EasyModbus; -using System.Reflection; - -namespace EasyModbusServerSimulator -{ - public partial class MainForm : Form - { - Settings settings = new Settings(); - EasyModbus.ModbusServer easyModbusTCPServer; - private UInt16 startingAddressDiscreteInputs = 1; - private UInt16 startingAddressCoils = 1; - private UInt16 startingAddressHoldingRegisters = 1; - private UInt16 startingAddressInputRegisters = 1; - private bool showProtocolInformations = true; - private bool preventInvokeDiscreteInputs = false; - private bool preventInvokeCoils = false; - private bool preventInvokeInputRegisters = false; - private bool preventInvokeHoldingRegisters = false; - - public MainForm() - { - InitializeComponent(); - Assembly.GetExecutingAssembly().GetName().Version.ToString(); - lblVersion.Text = "Version: " + Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() +"."+ Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString(); - easyModbusTCPServer = new EasyModbus.ModbusServer(); - - easyModbusTCPServer.Listen(); - - - easyModbusTCPServer.CoilsChanged += new ModbusServer.CoilsChangedHandler(CoilsChanged); - easyModbusTCPServer.HoldingRegistersChanged += new ModbusServer.HoldingRegistersChangedHandler(HoldingRegistersChanged); - easyModbusTCPServer.NumberOfConnectedClientsChanged += new ModbusServer.NumberOfConnectedClientsChangedHandler(NumberOfConnectionsChanged); - easyModbusTCPServer.LogDataChanged += new ModbusServer.LogDataChangedHandler(LogDataChanged); - } - - private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) - { - if (tabControl1.SelectedIndex == 0) - { - numericUpDown1.Value = startingAddressDiscreteInputs; - dataGridView1.Rows.Clear(); - for (int i = startingAddressDiscreteInputs; i < 20 + startingAddressDiscreteInputs; i++) - { - dataGridView1.Rows.Add(i, easyModbusTCPServer.discreteInputs[i]); - - if (easyModbusTCPServer.discreteInputs[i]) - dataGridView1[1, i - startingAddressDiscreteInputs].Style.BackColor = Color.Green; - else - dataGridView1[1, i - startingAddressDiscreteInputs].Style.BackColor = Color.Red; - } - } - if (tabControl1.SelectedIndex == 1) - { - - numericUpDown1.Value = startingAddressCoils; - dataGridView2.Rows.Clear(); - for (int i = startingAddressCoils; i < 20 + startingAddressCoils; i++) - { - dataGridView2.Rows.Add(i, easyModbusTCPServer.coils[i]); - if (easyModbusTCPServer.coils[i]) - dataGridView2[1, i - startingAddressCoils].Style.BackColor = Color.Green; - else - dataGridView2[1, i - startingAddressCoils].Style.BackColor = Color.Red; - } - } - if (tabControl1.SelectedIndex == 2) - { - numericUpDown1.Value = startingAddressInputRegisters; - dataGridView3.Rows.Clear(); - for (int i = startingAddressInputRegisters; i < 20 + startingAddressInputRegisters; i++) - dataGridView3.Rows.Add(i, easyModbusTCPServer.inputRegisters[i]); - } - if (tabControl1.SelectedIndex == 3) - { - numericUpDown1.Value = startingAddressHoldingRegisters; - dataGridView4.Rows.Clear(); - for (int i = startingAddressHoldingRegisters; i < 20 + startingAddressHoldingRegisters; i++) - dataGridView4.Rows.Add(i, easyModbusTCPServer.holdingRegisters[i]); - } - - } - - private void Form1_Load(object sender, EventArgs e) - { - tabControl1_SelectedIndexChanged(null, null); - } - - private void numericUpDown1_ValueChanged(object sender, EventArgs e) - { - if (tabControl1.SelectedIndex == 0) - startingAddressDiscreteInputs = (UInt16)numericUpDown1.Value; - if (tabControl1.SelectedIndex == 1) - startingAddressCoils = (UInt16)numericUpDown1.Value; - if (tabControl1.SelectedIndex == 2) - startingAddressInputRegisters = (UInt16)numericUpDown1.Value; - if (tabControl1.SelectedIndex == 3) - startingAddressHoldingRegisters = (UInt16)numericUpDown1.Value; - tabControl1_SelectedIndexChanged(null, null); - - } - - private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - int rowindex = dataGridView1.SelectedCells[0].RowIndex; - if (easyModbusTCPServer.discreteInputs[rowindex+startingAddressDiscreteInputs] == false) - easyModbusTCPServer.discreteInputs[rowindex+startingAddressDiscreteInputs] = true; - else - easyModbusTCPServer.discreteInputs[rowindex + startingAddressDiscreteInputs] = false; - tabControl1_SelectedIndexChanged(null, null); - - } - - delegate void coilsChangedCallback(int coil, int numberOfCoil); - private void CoilsChanged(int coil, int numberOfCoil) - { - if (preventInvokeCoils) - return; - if (this.tabControl1.InvokeRequired) - { - - { - coilsChangedCallback d = new coilsChangedCallback(CoilsChanged); - this.Invoke(d, coil, numberOfCoil); - } - } - else - { - if (tabControl1.SelectedIndex == 1) - tabControl1_SelectedIndexChanged(null, null); - } - } - - delegate void registersChangedCallback(int register, int numberOfRegisters); - bool registersChanegesLocked; - private void HoldingRegistersChanged(int register, int numberOfRegisters) - { - if (preventInvokeHoldingRegisters) - return; - - try - { - if (this.tabControl1.InvokeRequired) - { - { - if (!registersChanegesLocked) - lock (this) - { - registersChanegesLocked = true; - - registersChangedCallback d = new registersChangedCallback(HoldingRegistersChanged); - this.Invoke(d, register, numberOfRegisters); - } - } - } - else - { - if (tabControl1.SelectedIndex == 3) - tabControl1_SelectedIndexChanged(null, null); - } - } - catch (Exception) { } - registersChanegesLocked = false; - } - - - bool LockNumberOfConnectionsChanged=false; - delegate void numberOfConnectionsCallback(); - private void NumberOfConnectionsChanged() - { - if (this.label3.InvokeRequired & !LockNumberOfConnectionsChanged) - { - { - lock (this) - { - LockNumberOfConnectionsChanged = true; - numberOfConnectionsCallback d = new numberOfConnectionsCallback(NumberOfConnectionsChanged); - try - { - this.Invoke(d); - } - catch (Exception) { } - finally - { - LockNumberOfConnectionsChanged = false; - } - } - } - } - else - { - try - { - label3.Text = easyModbusTCPServer.NumberOfConnections.ToString(); - } - catch (Exception) - { } - } - } - - private void dataGridView2_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - int rowindex = dataGridView2.SelectedCells[0].RowIndex; - if (easyModbusTCPServer.coils[rowindex + startingAddressCoils] == false) - easyModbusTCPServer.coils[rowindex + startingAddressCoils] = true; - else - easyModbusTCPServer.coils[rowindex + startingAddressCoils] = false; - tabControl1_SelectedIndexChanged(null, null); - - } - - private void dataGridView3_CellValueChanged(object sender, DataGridViewCellEventArgs e) - { - if (dataGridView3.SelectedCells.Count > 0) - { - int rowindex = dataGridView3.SelectedCells[0].RowIndex; - try - { - easyModbusTCPServer.inputRegisters[rowindex + startingAddressInputRegisters] = Int16.Parse(dataGridView3.SelectedCells[0].Value.ToString()); - } - catch (Exception) { } - tabControl1_SelectedIndexChanged(null, null); - } - } - - private void dataGridView4_CellValueChanged(object sender, DataGridViewCellEventArgs e) - { - if (dataGridView4.SelectedCells.Count > 0) - { - int rowindex = dataGridView4.SelectedCells[0].RowIndex; - try - { - easyModbusTCPServer.holdingRegisters[rowindex + startingAddressHoldingRegisters] = Int16.Parse(dataGridView4.SelectedCells[0].Value.ToString()); - } - catch (Exception) { } - tabControl1_SelectedIndexChanged(null, null); - } - } - - private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - System.Diagnostics.Process.Start("http://www.EasyModbusTCP.net");     - } - - private void vScrollBar1_ValueChanged(object sender, EventArgs e) - { - startingAddressDiscreteInputs=(ushort)vScrollBar1.Value; - tabControl1_SelectedIndexChanged(null, null); - } - - private void vScrollBar2_ValueChanged(object sender, EventArgs e) - { - startingAddressCoils = (ushort)vScrollBar2.Value; - tabControl1_SelectedIndexChanged(null, null); - } - - private void vScrollBar3_ValueChanged(object sender, EventArgs e) - { - startingAddressInputRegisters = (ushort)vScrollBar3.Value; - tabControl1_SelectedIndexChanged(null, null); - } - - private void vScrollBar4_ValueChanged(object sender, EventArgs e) - { - startingAddressHoldingRegisters = (ushort)vScrollBar4.Value; - tabControl1_SelectedIndexChanged(null, null); - } - - delegate void logDataChangedCallback(); - bool locked; - private void LogDataChanged() - { - - if (showProtocolInformations == true) - { - - if (this.listBox1.InvokeRequired) - { - if (!locked) - { - lock (this) - { - locked = true; - try - { - logDataChangedCallback d = new logDataChangedCallback(LogDataChanged); - this.Invoke(d); - } - catch (Exception) - { - } - - - } - - } - } - else - { - - try - { - listBox1.Items.Clear(); - string listBoxData; - for (int i = 0; i < easyModbusTCPServer.ModbusLogData.Length; i++) - { - if (easyModbusTCPServer.ModbusLogData[i] == null) - break; - if (easyModbusTCPServer.ModbusLogData[i].request) - { - listBoxData = easyModbusTCPServer.ModbusLogData[i].timeStamp.ToString("H:mm:ss.ff") + " Request from Client - Functioncode: " + easyModbusTCPServer.ModbusLogData[i].functionCode.ToString(); - if (easyModbusTCPServer.ModbusLogData[i].functionCode <= 4) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " Quantity: " + easyModbusTCPServer.ModbusLogData[i].quantity.ToString(); - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 5) - { - listBoxData = listBoxData + " ; Output Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " Output Value: "; - if (easyModbusTCPServer.ModbusLogData[i].receiveCoilValues[0] == 0) - listBoxData = listBoxData + "False"; - if (easyModbusTCPServer.ModbusLogData[i].receiveCoilValues[0] == 0xFF00) - listBoxData = listBoxData + "True"; - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 6) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " Register Value: " + easyModbusTCPServer.ModbusLogData[i].receiveRegisterValues[0].ToString(); - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 15) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " Quantity: " + easyModbusTCPServer.ModbusLogData[i].quantity.ToString() + " Byte Count: " + easyModbusTCPServer.ModbusLogData[i].byteCount.ToString() + " Values Received: "; - for (int j = 0; j < easyModbusTCPServer.ModbusLogData[i].quantity; j++) - { - int shift = j % 16; - if ((i == easyModbusTCPServer.ModbusLogData[i].quantity - 1) & (easyModbusTCPServer.ModbusLogData[i].quantity % 2 != 0)) - { - if (shift < 8) - shift = shift + 8; - else - shift = shift - 8; - } - int mask = 0x1; - mask = mask << (shift); - if ((easyModbusTCPServer.ModbusLogData[i].receiveCoilValues[j / 16] & (ushort)mask) == 0) - listBoxData = listBoxData + " False"; - else - listBoxData = listBoxData + " True"; - } - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 16) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " Quantity: " + easyModbusTCPServer.ModbusLogData[i].quantity.ToString() + " Byte Count: " + easyModbusTCPServer.ModbusLogData[i].byteCount.ToString() + " Values Received: "; - for (int j = 0; j < easyModbusTCPServer.ModbusLogData[i].quantity; j++) - { - listBoxData = listBoxData + " " + easyModbusTCPServer.ModbusLogData[i].receiveRegisterValues[j]; - } - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 23) - { - listBoxData = listBoxData + " ; Starting Address Read: " + easyModbusTCPServer.ModbusLogData[i].startingAddressRead.ToString() + " ; Quantity Read: " + easyModbusTCPServer.ModbusLogData[i].quantityRead.ToString() + " ; Starting Address Write: " + easyModbusTCPServer.ModbusLogData[i].startingAddressWrite.ToString() + " ; Quantity Write: " + easyModbusTCPServer.ModbusLogData[i].quantityWrite.ToString() + " ; Byte Count: " + easyModbusTCPServer.ModbusLogData[i].byteCount.ToString() + " ; Values Received: "; - for (int j = 0; j < easyModbusTCPServer.ModbusLogData[i].quantityWrite; j++) - { - listBoxData = listBoxData + " " + easyModbusTCPServer.ModbusLogData[i].receiveRegisterValues[j]; - } - } - - listBox1.Items.Add(listBoxData); - } - if (easyModbusTCPServer.ModbusLogData[i].response) - { - if (easyModbusTCPServer.ModbusLogData[i].exceptionCode > 0) - { - listBoxData = easyModbusTCPServer.ModbusLogData[i].timeStamp.ToString("H:mm:ss.ff"); - listBoxData = listBoxData + (" Response To Client - Error code: " + Convert.ToString(easyModbusTCPServer.ModbusLogData[i].errorCode, 16)); - listBoxData = listBoxData + " Exception Code: " + easyModbusTCPServer.ModbusLogData[i].exceptionCode.ToString(); - listBox1.Items.Add(listBoxData); - - - } - else - { - listBoxData = (easyModbusTCPServer.ModbusLogData[i].timeStamp.ToString("H:mm:ss.ff") + " Response To Client - Functioncode: " + easyModbusTCPServer.ModbusLogData[i].functionCode.ToString()); - - if (easyModbusTCPServer.ModbusLogData[i].functionCode <= 4) - { - listBoxData = listBoxData + " ; Bytecount: " + easyModbusTCPServer.ModbusLogData[i].byteCount.ToString() + " ; Send values: "; - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 5) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " ; Output Value: "; - if (easyModbusTCPServer.ModbusLogData[i].receiveCoilValues[0] == 0) - listBoxData = listBoxData + "False"; - if (easyModbusTCPServer.ModbusLogData[i].receiveCoilValues[0] == 0xFF00) - listBoxData = listBoxData + "True"; - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 6) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " ; Register Value: " + easyModbusTCPServer.ModbusLogData[i].receiveRegisterValues[0].ToString(); - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 15) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " ; Quantity: " + easyModbusTCPServer.ModbusLogData[i].quantity.ToString(); - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 16) - { - listBoxData = listBoxData + " ; Starting Address: " + easyModbusTCPServer.ModbusLogData[i].startingAdress.ToString() + " ; Quantity: " + easyModbusTCPServer.ModbusLogData[i].quantity.ToString(); - } - if (easyModbusTCPServer.ModbusLogData[i].functionCode == 23) - { - listBoxData = listBoxData + " ; ByteCount: " + easyModbusTCPServer.ModbusLogData[i].byteCount.ToString() + " ; Send Register Values: "; - } - if (easyModbusTCPServer.ModbusLogData[i].sendCoilValues != null) - { - for (int j = 0; j < easyModbusTCPServer.ModbusLogData[i].sendCoilValues.Length; j++) - { - listBoxData = listBoxData + easyModbusTCPServer.ModbusLogData[i].sendCoilValues[j].ToString() + " "; - } - } - if (easyModbusTCPServer.ModbusLogData[i].sendRegisterValues != null) - { - for (int j = 0; j < easyModbusTCPServer.ModbusLogData[i].sendRegisterValues.Length; j++) - { - listBoxData = listBoxData + easyModbusTCPServer.ModbusLogData[i].sendRegisterValues[j].ToString() + " "; - } - } - listBox1.Items.Add(listBoxData); - } - } - } - } - catch (Exception) { } - - locked = false; - - - } - - } - } - - private void checkBox1_CheckedChanged(object sender, EventArgs e) - { - if (checkBox1.Checked) - showProtocolInformations = true; - else - showProtocolInformations = false; - } - - - private void MainForm_FormClosing(object sender, FormClosingEventArgs e) - - { - - easyModbusTCPServer.StopListening(); - Environment.Exit(0); - } - - private void checkBox2_CheckedChanged(object sender, EventArgs e) - { - easyModbusTCPServer.FunctionCode1Disabled = !checkBox2.Checked; - } - - private void checkBox3_CheckedChanged(object sender, EventArgs e) - { - CheckBox checkBox = (CheckBox)sender; - easyModbusTCPServer.FunctionCode2Disabled = !checkBox3.Checked; - } - - private void checkBox4_CheckedChanged(object sender, EventArgs e) - { - CheckBox checkBox = (CheckBox)sender; - easyModbusTCPServer.FunctionCode3Disabled = !checkBox4.Checked; - } - - private void checkBox5_CheckedChanged(object sender, EventArgs e) - { - CheckBox checkBox = (CheckBox)sender; - easyModbusTCPServer.FunctionCode4Disabled = !checkBox5.Checked; - } - - private void checkBox6_CheckedChanged(object sender, EventArgs e) - { - CheckBox checkBox = (CheckBox)sender; - easyModbusTCPServer.FunctionCode5Disabled = !checkBox6.Checked; - } - - private void checkBox7_CheckedChanged(object sender, EventArgs e) - { - CheckBox checkBox = (CheckBox)sender; - easyModbusTCPServer.FunctionCode6Disabled = !checkBox7.Checked; - } - - private void checkBox9_CheckedChanged(object sender, EventArgs e) - { - easyModbusTCPServer.FunctionCode15Disabled = !checkBox9.Checked; - } - - private void checkBox8_CheckedChanged(object sender, EventArgs e) - { - easyModbusTCPServer.FunctionCode16Disabled = !checkBox8.Checked; - } - - private void dataGridView2_MouseEnter(object sender, EventArgs e) - { - preventInvokeCoils = true; - } - - private void dataGridView2_MouseLeave(object sender, EventArgs e) - { - preventInvokeCoils = false; - } - - private void tabControl1_MouseEnter(object sender, EventArgs e) - { - - } - - private void tabControl1_MouseLeave(object sender, EventArgs e) - { - - } - - private void dataGridView4_MouseEnter(object sender, EventArgs e) - { - preventInvokeHoldingRegisters = true; - } - - private void dataGridView4_MouseLeave(object sender, EventArgs e) - { - preventInvokeHoldingRegisters = false; - } - - private void MainForm_FormClosed(object sender, FormClosedEventArgs e) - { - - } - - private void btnProperties_Click(object sender, EventArgs e) - { - settings.ComPort = easyModbusTCPServer.SerialPort; - settings.SlaveAddress = easyModbusTCPServer.UnitIdentifier; - PropertyForm propertryForm = new PropertyForm(settings); - propertryForm.SettingsChangedEvent += new PropertyForm.settingsChangedEvent(SettingsChanged); - propertryForm.Show(); - } - - private void SettingsChanged() - { - easyModbusTCPServer.StopListening(); - easyModbusTCPServer.Port = settings.Port; - easyModbusTCPServer.SerialPort = settings.ComPort; - easyModbusTCPServer.UnitIdentifier = settings.SlaveAddress; - if (settings.ModbusTypeSelection == Settings.ModbusType.ModbusUDP) - { - easyModbusTCPServer.UDPFlag = true; - easyModbusTCPServer.SerialFlag = false; - label4.Text = "...Modbus-UDP Server Listening (Port " + settings.Port + ")..."; - } - else if (settings.ModbusTypeSelection == Settings.ModbusType.ModbusTCP) - { - easyModbusTCPServer.UDPFlag = false; - easyModbusTCPServer.SerialFlag = false; - label4.Text = "...Modbus-TCP Server Listening (Port " + settings.Port + ")..."; - } - else if (settings.ModbusTypeSelection == Settings.ModbusType.ModbusRTU) - { - easyModbusTCPServer.UDPFlag = false; - easyModbusTCPServer.SerialFlag = true; - label4.Text = "...Modbus-RTU Client Listening (Com-Port: " + settings.ComPort + ")..."; - } - easyModbusTCPServer.PortChanged = true; - - easyModbusTCPServer.Listen(); - } - void EasyModbusTCPServerBindingSourceCurrentChanged(object sender, EventArgs e) - { - - } - - private void pictureBox1_Click(object sender, EventArgs e) - { - System.Diagnostics.Process.Start("http://www.EasyModbusTCP.net");  - } - - private void checkBox10_CheckedChanged(object sender, EventArgs e) - { - easyModbusTCPServer.FunctionCode23Disabled = !checkBox10.Checked; - } - - - - private void panel1_MouseLeave(object sender, EventArgs e) - { - if (checkBox1.Checked) - showProtocolInformations = true; - else - showProtocolInformations = false; - } - - private void panel1_MouseEnter(object sender, EventArgs e) - { - showProtocolInformations = false; - } - - private void panel1_MouseLeave_1(object sender, EventArgs e) - { - if (checkBox1.Checked) - showProtocolInformations = true; - else - showProtocolInformations = false; - } - - - - private void MainForm_MouseMove(object sender, MouseEventArgs e) - { - if (checkBox1.Checked) - showProtocolInformations = true; - else - showProtocolInformations = false; - } - - private int xLastLocation; - private int yLastLocation; - private void listBox1_MouseMove(object sender, MouseEventArgs e) - { - - - - if ((Math.Abs(e.Location.X - xLastLocation) < 50) & (Math.Abs(e.Location.Y - yLastLocation) < 50)) - return; - xLastLocation = e.Location.X; - yLastLocation = e.Location.Y; - - showProtocolInformations = false; - string strToolTip = ""; - - //Get the item - int nIdx = listBox1.IndexFromPoint(e.Location); - if ((nIdx >= 0) && (nIdx < listBox1.Items.Count)) - strToolTip = listBox1.Items[nIdx].ToString(); - - toolTip1.SetToolTip(listBox1, strToolTip); - - } - - private void infoToolStripMenuItem_Click(object sender, EventArgs e) - { - Info infoWindow = new Info(); - infoWindow.Show(); - } - - private void setupToolStripMenuItem_Click(object sender, EventArgs e) - { - settings.ComPort = easyModbusTCPServer.SerialPort; - settings.SlaveAddress = easyModbusTCPServer.UnitIdentifier; - PropertyForm propertryForm = new PropertyForm(settings); - propertryForm.SettingsChangedEvent += new PropertyForm.settingsChangedEvent(SettingsChanged); - propertryForm.Show(); - } - - } -} diff --git a/EasyModbusServerSimulator/MainForm.resx b/EasyModbusServerSimulator/MainForm.resx deleted file mode 100644 index e0e4f67..0000000 --- a/EasyModbusServerSimulator/MainForm.resx +++ /dev/null @@ -1,503 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - Activated Function codes: - - FC 01 (Read Coils) - FC 02 (Read Discrete Inputs) - FC 03 (Read Holding Registers) - FC 04 (Read Input Registers) - FC 05 (Write Single Coil) - FC 06 (Write Single Register) - FC 15 (Write Multiple Coils) - FC 16 (Write Multiple Registers) - FC 23 (Read/Write Multiple Registers) - - - 17, 17 - - - 180, 17 - - - 435, 17 - - - 607, 17 - - - 704, 17 - - - - - AAABAAEAVDgAAAEAIABITAAAFgAAACgAAABUAAAAcAAAAAEAIAAAAAAAgEkAAMMOAADDDgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfYRaGAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAJ9fHwieYBWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACpVBwJnmAaHZ1h - GCqgXxQzn18WOJ9fFTueYBQylFUVDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJxiF0GcXxZoAAAAAAAA - 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 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlmAAWfYhVTn2AWs55gFsGeYBbBnWEWuJ9fF0AAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFs05FhbOvRYWzuIWFs6zFxfPKwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ9fF0ueYBa3nmAWwZ5gFsGeYBW7n2EWc6BeFSMAAAAAAAAAAAAA - AAATE8QNFhbPcBYWzukXF8+QGBjNNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfXw8Qn2IXWJ9g - FqueYBbBnmAWwZ5gFsGeYBWZnmAaHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACiXBcWn2EVgJ9gFsCeYBbBnmAWwZ5gFsGfYBaen18XY6FiFDGZZhkKAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKpVAAObXBUknmAVUp5gFoqfYRa9nmAWwZ5gFsGeYBbBnmAWtJ1hFVSqVQADAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJtdGCmfXxeFnmAWv55g - FsGeYBbBnmAWwZ5gFsGeYBbAn2AWqp9hFpOdYRaGn18VgJ1fF4OeYBeOnmAWop5gF7yeYBbBnmAWwZ5g - FsGeYBbBnmAWwZ5gFrOdXxdjnGITDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo2UUGZ1hF2GeYBahnmAWwZ5gFsGeYBbBnmAWwZ5g - FsGeYBbBnmAWwZ5gFsGeYBbBnmAWwZ5gFsGeYBbBnmAWwZ9gF7ueYBaJoGIVRpFtJAcAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAm2MWF55gFkWdXxVrnmAWiZ9gFp6eYBasnmAWs55gF7GdYRaonmAVl59h - Fn6fXxVdoWIYNJ9fHwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////v//////8AD//////P///gH/ - 8AD//////P//wAB/8AD4AB//+P//AAB/8ADwAB/x8f/8H/w/8ADwAB/A4//4//4/8ADwAB/AR//z//4/ - 8ADwAB/MD/////4/8ADwAB/ED/////4/8ADxER/AH/////4/8ADx3/+AB/////4/8ADx//8IAf////4/ - 8ADx+/8cQPB///4/8ADx8x48cCAf//4f8ADx8AA4/AAP//8H8ADx4AB4/weP//+D8AD/4fBx/4+P///B - 8AD/w/xx/5/H///h8AD/h54xwB/H///w8AD/jw4wAA/P///w8AD/ng8AAY+P///h8AD/ng8Af4AP///h - 8AD/GAMT/8Af///D8AD/lAER/8B////D8AD/kQkR/4j///+H8AD/gAAR/wj///+H8AD/hAYB/xj///8P - 8AD/w/wB/jj///8P8AD/4fBgfDj///8f8AD/8ADwAHj///8f8AD/+AP4AHj///4f8AD//h/4hHif//4f - 8AD//j/4DH4H//4f8AD//j/8AEAH//4f8AD//n/wAAAD//4/8AD//H+AAIAD//w/8AD//HwCDwwH//w/ - 8AD/+GAPDwwH//g/8AD/4AB/h4Af//B/8AD/4AP/g4AH/+D/8AD/4h//wMAH/8H/8AD/4j//4HMj/wP/ - 8AD/4D//8B8H/Af/8AD/8H///AcH8A//8AD//////gB/AB//8AD//////4AAAH//8AD//////+AAAf// - 8AD///////wAD///8AD/////////////8AD/////////////8AD/////////////8AD///////////// - 8AD/////////////8AD/////////////8AD/////////////8AD/////////////8AA= - - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/PLCLoggerCompact.ico b/EasyModbusServerSimulator/PLCLoggerCompact.ico deleted file mode 100644 index cb47648..0000000 Binary files a/EasyModbusServerSimulator/PLCLoggerCompact.ico and /dev/null differ diff --git a/EasyModbusServerSimulator/Program.cs b/EasyModbusServerSimulator/Program.cs deleted file mode 100644 index c57be66..0000000 --- a/EasyModbusServerSimulator/Program.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Windows.Forms; -using EasyModbus; - -namespace EasyModbusServerSimulator -{ - /// - /// Class with program entry point. - /// - static class Program - { - /// - /// Program entry point. - /// - [STAThread] - static void Main(string[] args) - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm()); - } - - } -} diff --git a/EasyModbusServerSimulator/Properties/AssemblyInfo.cs b/EasyModbusServerSimulator/Properties/AssemblyInfo.cs deleted file mode 100644 index d660c5f..0000000 --- a/EasyModbusServerSimulator/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -#region Using directives -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle ("EasyModbusServerSimulator")] -[assembly: AssemblyDescription ("")] -[assembly: AssemblyConfiguration ("")] -[assembly: AssemblyCompany ("Stefan Rossmann Engineering Solutions")] -[assembly: AssemblyProduct ("EasyModbusServerSimulator")] -[assembly: AssemblyCopyright("Copyright 2018-2020")] -[assembly: AssemblyTrademark ("")] -[assembly: AssemblyCulture ("")] -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible (false)] -// The assembly version has following format : -// -// Major.Minor.Build.Revision -// -// You can specify all the values or you can use the default the Revision and -// Build Numbers by using the '*' as shown below: -[assembly: AssemblyVersion("5.6.0")] diff --git a/EasyModbusServerSimulator/Properties/Resources.Designer.cs b/EasyModbusServerSimulator/Properties/Resources.Designer.cs deleted file mode 100644 index 75306e7..0000000 --- a/EasyModbusServerSimulator/Properties/Resources.Designer.cs +++ /dev/null @@ -1,133 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace EasyModbusServerSimulator.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EasyModbusServerSimulator.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap button2_Image { - get { - object obj = ResourceManager.GetObject("button2.Image", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap configure_2 { - get { - object obj = ResourceManager.GetObject("configure-2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap pictureBox1_Image { - get { - object obj = ResourceManager.GetObject("pictureBox1.Image", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Icon ähnlich wie (Symbol). - /// - internal static System.Drawing.Icon PLCLoggerCompact { - get { - object obj = ResourceManager.GetObject("PLCLoggerCompact", resourceCulture); - return ((System.Drawing.Icon)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap PLCLoggerCompactBitmap { - get { - object obj = ResourceManager.GetObject("PLCLoggerCompactBitmap", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap red { - get { - object obj = ResourceManager.GetObject("red", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap small { - get { - object obj = ResourceManager.GetObject("small", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/EasyModbusServerSimulator/Properties/Resources.resx b/EasyModbusServerSimulator/Properties/Resources.resx deleted file mode 100644 index cddc039..0000000 --- a/EasyModbusServerSimulator/Properties/Resources.resx +++ /dev/null @@ -1,707 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAEAQEAAAAEAIAAoQAAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAADgAAAAhwAAAAAAAAAAAAAAAAAAAMEAAACaAAAAKQAAAAAAAAApAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAKQAAAJoAAADBAAAAAAAAAIcAAACaAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmgAAAIcAAADgAAAAKQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ACkAAADgAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAOAAAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD//wAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP//AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A//8AAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A//8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//wAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAACkAAADgAAAAhwAAAJoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaAAAAhwAAAAAAAADBAAAAmgAAACkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkAAACaAAAAwQAAAAAAAAAAAAAAAAAA - AIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA4AAAAP8AAADgAAAAhwAA - AAAAAAAA - - - - - R0lGODlhFAAUAIYAAP/hpf/gov/cmP/jq//iqP/enf/25P/jrP/iqv/z3P/rxf/v0f/35//fov/uy//j - rf/tyv/qwf/14P/rxP/z2//mtP/ouv/x1//pvf/kr//w0f/pvn5+fv/x1f/y2P/v0P/hpP/04P/sxv/x - 1P/lsv/y2f/vzv/sx//qv//mtSoqKv/03//iq//ntygoKP/uzLKysv/sxVZWVqOjo//14v/x1q+vr3p6 - ev/ouf/ovP/ty//25lJSUv/y109PT15eXv/rwkVFRY2NjUBAQGpqaqSkpP/245aWlra2tpycnP/vz//1 - 4f/nuP/krmhoaFxcXP/qwKGhof/w1Dk5Of/ntoqKihgYGP/tyGFhYTAwMKqqqkJCQv/ksB4eHoeHh5iY - mP/03mNjYzs7O//fof/cl//go//iqf/foP/dmf/gpP/hp//dmv/hpv/enP/fn//dm//enhQUFAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEBAAAh+QQA - AAAAACwAAAAAFAAUAAAI/wAZCGSwwwCNEAk8jFACYcKGFlzMjFljoKIBI0tWJCjRYYGDGChwkBhQ5g2Z - EBJSrgBDwUPHFyIiWKhwAEQbMmgoJNhJocQFKR9enIjgpMIDAHBwrqlxoceFDiM0mIAQs4qMJmzcKH2z - QIOGBR9MOLgyAUWUG1OykhGw5k0bHQ4cQIBwQkEEDDCOPLGila1bOAoCTwACBYMFJFo4iImztm0bOG42 - bMCQwwKTFDBsfPnRJQ4ax5DPtKCSogKJDDOKJOGwJU4c0G7ONMiQ4cEAM2yEeOEQJovrNgVCNyhDgA2I - AG7aCCCCxYcK18HPjAlQJo0bOG/QrEWDhkcQF65jT2GvDoDMWgGfHQ8BH2fM8DQA2LDh/vmN2+Bwnseh - Dp+NGjVtuQVcaNK51t9/BJhxHxyhucdfHP6pkaAZCOAnHn8HSmgGhSwM0CCG8SG4IQIdHnCAdCBGmCAC - CAwwgIkPPBAQADs= - - - - - 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 - fQZM4BfEYlY3R4GTBgAAAABJRU5ErkJggg== - - - - - /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/+IMWElDQ19QUk9GSUxFAAEBAAAMSExp - bm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAA - AAEAAPbWAAEAAAAA0y1IUCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAARY3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAA - AhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVlZAAA - A0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAA - BDwAAAgMZ1RSQwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3 - bGV0dC1QYWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAA - AAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA - b6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNjAAAAAAAA - ABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAuSUVDIDYx - OTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAuSUVDIDYxOTY2 - LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRl - c2MAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAA - AAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4AFF8uABDPFAAD7cwABBMLAANcngAAAAFYWVogAAAAAABM - CVYAUAAAAFcf521lYXMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1 - cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3 - AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQET - ARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHp - AfIB+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAML - AxYDIQMtAzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+ - BIwEmgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZI - BlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghu - CIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3Arz - CwsLIgs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3e - DfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExEx - EU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTw - FRIVNBVWFXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkg - GUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3D - HeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLd - IwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhx - KKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6C - Lrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUT - NU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76Dwn - PGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPA - RANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkvi - TCpMcky6TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSP - VNtVKFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3J - XhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeT - Z+loP2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHw - cktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzh - fUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhp - iM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSK - lPSVX5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFH - obaiJqKWowajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6h - rxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8Ibyb - vRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2 - y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - 2vvbgNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb - 6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn - +3f8B/yY/Sn9uv5L/tz/bf///9sAQwABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB - AQEBAQEBAgICAgICAgICAgIDAwMDAwMDAwMD/9sAQwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMD - AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAZAAkAwERAAIRAQMRAf/EAB8A - AAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFB - BhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldY - WVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI - ycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYH - 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 - 8z//2Q== - - - - - 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 - TLCsU8Lyie2qEyy7uxKLPeUTmH3dX3/9DzE9z88PrjUbAAAAAElFTkSuQmCC - - - - - /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcI - CQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwM - DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABAAEADASIAAhEBAxEB/8QA - HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh - MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW - V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG - x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF - BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV - YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE - hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq - 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD7Jvbj9nHwJ/wTt+EP7Rv7RHwg0f4x+LfjLpej6rquqax4c0/x - HqMd9qenNqBhhN8VW3soQrxRQxFVjRIgFPzNXk3/AA3t/wAE4/8Aoz3wz/4anwx/8do/b2/5VyP2Pf8A - sDeC/wD1GJ6/L+vy7izizMMvzB4fDtctk9Vfc/vD6P30fuEeLuEYZznMKjrOpOPuzcVaLVtLH7jfsGeC - f2Hv+CiH/CV/8IV+yn8LNL/4Q/7J9s/tv4ZaBB5v2nz/AC/L8oS5x9nfO7bjK4zzj6H/AOHTv7LH/RtP - 7P8A/wCG80j/AOR6+GP+DXb/AJrl/wBwH/3JV+s1fZ8M5hWx2W08VX+KV7202k1+SP5m8cOEMu4X42xu - RZUmqFL2fKpPmfvUac3d9fek/keAf8Onf2WP+jaf2f8A/wAN5pH/AMj0f8Onf2WP+jaf2f8A/wAN5pH/ - AMj17/RXvH5QeAf8Onf2WP8Ao2n9n/8A8N5pH/yPXmP7bH7E/wAIv2Sf2RfiR8WPhP8ADfwH8KvH/wAK - vC+peLNE1vwnoVtos6zWFtLdi3nNrGnn2svltHLBIHR0lf5ckGvs2vAP+CsX/KLL9pb/ALJV4o/9NF1Q - B88eCf2DP+HiH/BD39lPwV/wlf8Awh/9l+CPCOt/bP7M/tDzfL0BYfK8vzYsZ+0bt2442YxzkeP/APEL - t/1XL/yzP/u6vuf/AIJO/wDKLL9mn/slXhf/ANNFrXv9eDmHDOW46t7fFU+aW17yW3o0j9X4Q8cONuF8 - uWVZFjfZUE3Ll9nRlrLd3nTlLX1sfJn/AAS7/wCCXf8Aw7Z/4Tn/AIrn/hNP+E0+wf8AMG/s77H9l+0/ - 9N5d+77R/s42d88fWdFfl7+0B+0B480b48eNrOz8beLrS0tNfvoYIIdYuI44UW4kCoqh8KoAAAHAAr5L - jLjLAcE4CglQlKEpOKUXt9p6yv3P528evHrE5ZiY8R8Rxliq+KkoylFQh8EIxWkVGPwxS0S2u9bs/UKi - vxj/AOHgut/9FS8a/wDgzv8A/Gv0G/4fA/s6f9FE/wDKDqf/AMjV+gcH4Hi7O/bfWMgxmF9ny29rQqx5 - ubm+G8Ffltr6o+l4Cy3jriL2/wBb4YzDB+z5be2w1aPPzc1+W9NX5eVX/wASPpavAP8AgrF/yiy/aW/7 - JV4o/wDTRdVkf8Pgf2dP+iif+UHU/wD5GryX/goF/wAFIPgv8e/+Ce/7QvhPwn4z/tbxBq3wq8W/ZbX+ - yL6DzfL0O9lf55YVQYSNzywzjA5IFfYV+DOIKFKVatga0YRTbbpTSSWrbbjZJLVt7H3mJ8PuKcNRniMR - luIhCCcpSlRqJRSV223GySWrb0SPcf8Agk7/AMosv2af+yVeF/8A00Wte/14B/wSd/5RZfs0/wDZKvC/ - /pota9/r5o+QCvyQ/aS/5OJ8ff8AYx6j/wClMlfrfRX5r4k+Hn+tmGo4f6x7H2cnK/Jz3urW+KNvxPyH - xd8Kv9eMHh8L9a9h7KTlfk573VrW54W+9n4Mf8M0aF/z96v/AN/Y/wD4iv0G/wCHBPwd/wChl+Jf/gws - f/kSvuGvAP8Ago5/wUc8Ef8ABML4IaV4+8faV4q1fR9X1yHw/DD4ftre4uVnkt7idWZZpoVEey2kBIYn - JXggkj9m8OM58T/rry6pndbH1q7iqceVRaa5rpe9K/Nddrcp+0cDeIPilkMcRPPOKK+NU+Xl5oKHs+Xm - 5re9K/NddrcvW547/wAOCfg7/wBDL8S//BhY/wDyJXnH7aX/AASG+Gv7L37DXx98daBrfji81fQ/hV4v - 8iHULy1ktn83Qb6BtypboxwsrEYYcgdRweU/4i9f2a/+hI+OP/gm0v8A+WNdV4v/AOCvXw1/4Kr/APBL - L9sz/hXmh+OdG/4QP4Va1/aH/CRWdrb+d9s0jU/L8ryLibOPssm7dtxlcZycfsfFOU+LOXZTXxWe068M - LblqOXLy2m1Czt/M5KPzPsMT42cU5jRngK2ZznCpGUZRbVpRaaknps1e59Vf8Enf+UWX7NP/AGSrwv8A - +mi1r3+viz9in9uD4P8A7Hn7Ivwv+EXxd+JngX4WfEL4YeGNN8Haxo3i7XLbRbhrjT7RLZriEXLoJrWY - Q+bFPGWjdJEw2TivVP8Ah7F+yx/0ct+z/wD+HD0j/wCSK/AD4U9/orwD/h7F+yx/0ct+z/8A+HD0j/5I - o/4exfssf9HLfs//APhw9I/+SKAPf6/Kz/g71/5RseCP+yl2H/pr1avtT/h7F+yx/wBHLfs//wDhw9I/ - +SK+Vf8Agr14v/ZY/wCCq/7Neh/Dz/hsz9n/AMB/2N4mg8Rf2h/wlekap53lWt3b+T5f2+HGftW7duON - mNpzkfo/hDn2AyTjLLs1zOp7OhSqKU5WlKys9bRTk/kmzjzClKrh504K7aP5oK/UT/ghb/yiy/4KTf8A - ZKm/9NHiGj/hxb+yx/0km/Z//wC+9I/+XVfSf7HX7Ifwg/ZG/ZH/AGk/hN8Jf2kvAP7THxA/aT8ML4R0 - fQ/CS20s+nzva6haie4Fre3RS1X+0DLLNIYkjjt3O4kgD+1/Hrx64E4j4Ex2TZNjva4ir7Llj7KtG/LW - pzes6cYq0Yt6tbWWtkfOZXleKo4qNSpGyV+q7PzP/9k= - - - - - ..\Resources\small.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/PropertyForm.Designer.cs b/EasyModbusServerSimulator/PropertyForm.Designer.cs deleted file mode 100644 index a364bed..0000000 --- a/EasyModbusServerSimulator/PropertyForm.Designer.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace EasyModbusServerSimulator -{ - partial class PropertyForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PropertyForm)); - this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); - this.btnDischard = new System.Windows.Forms.Button(); - this.btnAccept = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // propertyGrid1 - // - this.propertyGrid1.Location = new System.Drawing.Point(3, 1); - this.propertyGrid1.Name = "propertyGrid1"; - this.propertyGrid1.Size = new System.Drawing.Size(280, 206); - this.propertyGrid1.TabIndex = 0; - this.propertyGrid1.Click += new System.EventHandler(this.propertyGrid1_Click); - // - // btnDischard - // - this.btnDischard.Image = ((System.Drawing.Image)(resources.GetObject("btnDischard.Image"))); - this.btnDischard.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.btnDischard.Location = new System.Drawing.Point(3, 228); - this.btnDischard.Name = "btnDischard"; - this.btnDischard.Size = new System.Drawing.Size(75, 56); - this.btnDischard.TabIndex = 37; - this.btnDischard.Text = "Dischard"; - this.btnDischard.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.btnDischard.UseVisualStyleBackColor = true; - this.btnDischard.Click += new System.EventHandler(this.btnDischard_Click); - // - // btnAccept - // - this.btnAccept.Image = ((System.Drawing.Image)(resources.GetObject("btnAccept.Image"))); - this.btnAccept.ImageAlign = System.Drawing.ContentAlignment.TopCenter; - this.btnAccept.Location = new System.Drawing.Point(206, 228); - this.btnAccept.Name = "btnAccept"; - this.btnAccept.Size = new System.Drawing.Size(75, 56); - this.btnAccept.TabIndex = 38; - this.btnAccept.Text = "Accept"; - this.btnAccept.TextAlign = System.Drawing.ContentAlignment.BottomCenter; - this.btnAccept.UseVisualStyleBackColor = true; - this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click); - // - // PropertyForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(284, 286); - this.ControlBox = false; - this.Controls.Add(this.btnAccept); - this.Controls.Add(this.btnDischard); - this.Controls.Add(this.propertyGrid1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "PropertyForm"; - this.Text = "Properties"; - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.PropertyGrid propertyGrid1; - private System.Windows.Forms.Button btnDischard; - private System.Windows.Forms.Button btnAccept; - } -} \ No newline at end of file diff --git a/EasyModbusServerSimulator/PropertyForm.cs b/EasyModbusServerSimulator/PropertyForm.cs deleted file mode 100644 index 4e24cfe..0000000 --- a/EasyModbusServerSimulator/PropertyForm.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; - -namespace EasyModbusServerSimulator -{ - - public partial class PropertyForm : Form - { - public delegate void settingsChangedEvent(); - public event settingsChangedEvent SettingsChangedEvent; - - Settings settings = new Settings(); - Settings settingsFromMainForm = new Settings(); - public PropertyForm(Settings settings) - { - this.settingsFromMainForm.Port = settings.Port; - this.settingsFromMainForm.ModbusTypeSelection = settings.ModbusTypeSelection; - this.settings = settings; - InitializeComponent(); - propertyGrid1.SelectedObject = settings; - } - - private void btnDischard_Click(object sender, EventArgs e) - { - settings.Port = settingsFromMainForm.Port; - settings.ModbusTypeSelection = settingsFromMainForm.ModbusTypeSelection; - if (SettingsChangedEvent != null) - SettingsChangedEvent(); - this.Close(); - } - - private void btnAccept_Click(object sender, EventArgs e) - { - - if (SettingsChangedEvent != null) - SettingsChangedEvent(); - this.Close(); - } - - private void propertyGrid1_Click(object sender, EventArgs e) - { - - } - } -} diff --git a/EasyModbusServerSimulator/PropertyForm.resx b/EasyModbusServerSimulator/PropertyForm.resx deleted file mode 100644 index 757e89f..0000000 --- a/EasyModbusServerSimulator/PropertyForm.resx +++ /dev/null @@ -1,434 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - 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 - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAADgAAAAhwAAAAAAAAAAAAAAAAAAAMEAAACaAAAAKQAAAAAAAAApAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAKQAAAJoAAADBAAAAAAAAAIcAAACaAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmgAAAIcAAADgAAAAKQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ACkAAADgAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAOAAAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP8AAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA/wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//wAA//8AAP//AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8A - AP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP8AAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD//wAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP//AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A//8AAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD//wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A//8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A - ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//wAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/ - AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAA - AAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAA - AAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAA - AAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAA - AAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA - AP8AAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA - //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP8AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAACkAAADgAAAAhwAAAJoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaAAAAhwAAAAAAAADBAAAAmgAAACkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkAAACaAAAAwQAAAAAAAAAAAAAAAAAA - AIcAAADgAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA - AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA4AAAAP8AAADgAAAAhwAA - AAAAAAAA - - - \ No newline at end of file diff --git a/EasyModbusServerSimulator/Resources/PLCLoggerCompact.jpg b/EasyModbusServerSimulator/Resources/PLCLoggerCompact.jpg deleted file mode 100644 index 48d8d88..0000000 Binary files a/EasyModbusServerSimulator/Resources/PLCLoggerCompact.jpg and /dev/null differ diff --git a/EasyModbusServerSimulator/Resources/button2.Image.png b/EasyModbusServerSimulator/Resources/button2.Image.png deleted file mode 100644 index 9946594..0000000 Binary files a/EasyModbusServerSimulator/Resources/button2.Image.png and /dev/null differ diff --git a/EasyModbusServerSimulator/Resources/configure-2.png b/EasyModbusServerSimulator/Resources/configure-2.png deleted file mode 100644 index 016ea77..0000000 Binary files a/EasyModbusServerSimulator/Resources/configure-2.png and /dev/null differ diff --git a/EasyModbusServerSimulator/Resources/pictureBox1.Image.png b/EasyModbusServerSimulator/Resources/pictureBox1.Image.png deleted file mode 100644 index 836cfa7..0000000 Binary files a/EasyModbusServerSimulator/Resources/pictureBox1.Image.png and /dev/null differ diff --git a/EasyModbusServerSimulator/Resources/red.png b/EasyModbusServerSimulator/Resources/red.png deleted file mode 100644 index b31b44c..0000000 Binary files a/EasyModbusServerSimulator/Resources/red.png and /dev/null differ diff --git a/EasyModbusServerSimulator/Resources/small.png b/EasyModbusServerSimulator/Resources/small.png deleted file mode 100644 index 48cf80f..0000000 Binary files a/EasyModbusServerSimulator/Resources/small.png and /dev/null differ diff --git a/EasyModbusServerSimulator/Settings.cs b/EasyModbusServerSimulator/Settings.cs deleted file mode 100644 index 91a717a..0000000 --- a/EasyModbusServerSimulator/Settings.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; - -namespace EasyModbusServerSimulator -{ - public class Settings - { - public enum ModbusType { ModbusTCP, ModbusUDP, ModbusRTU }; - private int port = 502; - [DescriptionAttribute("Listenig Port for Modbus-TCP or Modbus-UDP Server")] - [CategoryAttribute("ModbusProperties")] - public int Port - { - get - { - return port; - } - set - { - port = value; - } - } - - private ModbusType modbusType; - [DescriptionAttribute("Activate Modbus UDP; Disable Modbus TCP")] - [CategoryAttribute("ModbusProperties")] - public ModbusType ModbusTypeSelection - { - get - { - return modbusType; - } - set - { - modbusType = value; - } - } - - private string comPort; - [DescriptionAttribute("ComPort Used for Modbus RTU connection ")] - [CategoryAttribute("Modbus RTU Properties")] - public string ComPort - { - get - { - return comPort; - } - set - { - comPort = value; - } - } - - private byte slaveAddress; - [DescriptionAttribute("UnitIdentifier (Slave address) for Modbus RTU connection")] - [CategoryAttribute("Modbus RTU Properties")] - public byte SlaveAddress - { - get - { - return slaveAddress; - } - set - { - slaveAddress = value; - } - } - - } -} diff --git a/EasyModbusServerSimulator/app.config b/EasyModbusServerSimulator/app.config deleted file mode 100644 index c5e1dae..0000000 --- a/EasyModbusServerSimulator/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico b/EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico deleted file mode 100644 index c14eb7a..0000000 Binary files a/EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico and /dev/null differ diff --git a/EasyModbus_NET5/EasyModbus.StoreLogData.cs b/EasyModbus_NET5/EasyModbus.StoreLogData.cs deleted file mode 100644 index 3345038..0000000 --- a/EasyModbus_NET5/EasyModbus.StoreLogData.cs +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace EasyModbus -{ - /// - /// Store Log-Data in a File - /// - public sealed class StoreLogData - { - private String filename = null; - private static volatile StoreLogData instance; - private static object syncObject = new Object(); - - /// - /// Private constructor; Ensures the access of the class only via "instance" - /// - private StoreLogData() - { - } - - /// - /// Returns the instance of the class (singleton) - /// - /// instance (Singleton) - public static StoreLogData Instance - { - get - { - if (instance == null) - { - lock (syncObject) - { - if (instance == null) - instance = new StoreLogData(); - } - } - - return instance; - } - } - - /// - /// Store message in Log-File - /// - /// Message to append to the Log-File - public void Store(String message) - { - if (this.filename == null) - return; - - using (System.IO.StreamWriter file = - new System.IO.StreamWriter(Filename, true)) - { - file.WriteLine(message); - } - } - - /// - /// Store message in Log-File including Timestamp - /// - /// Message to append to the Log-File - /// Timestamp to add to the same Row - public void Store(String message, DateTime timestamp) - { - try - { - using (System.IO.StreamWriter file = - new System.IO.StreamWriter(Filename, true)) - { - file.WriteLine(timestamp.ToString("dd.MM.yyyy H:mm:ss.ff ") + message); - } - } - catch (Exception e) - { - - } - } - - /// - /// Gets or Sets the Filename to Store Strings in a File - /// - public string Filename - { - get - { - return filename; - } - set - { - filename = value; - } - } - } -} diff --git a/EasyModbus_NET5/EasyModbus_V5.0.csproj b/EasyModbus_NET5/EasyModbus_V5.0.csproj deleted file mode 100644 index 9c1ace3..0000000 --- a/EasyModbus_NET5/EasyModbus_V5.0.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - net5.0 - EasyModbus - EasyModbus - false - - - - - - - - - - - - - diff --git a/EasyModbus_NET5/Exceptions/Exceptions.cs b/EasyModbus_NET5/Exceptions/Exceptions.cs deleted file mode 100644 index 8d1db4f..0000000 --- a/EasyModbus_NET5/Exceptions/Exceptions.cs +++ /dev/null @@ -1,211 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Runtime.Serialization; - -namespace EasyModbus.Exceptions -{ - /// - /// Exception to be thrown if serial port is not opened - /// - public class SerialPortNotOpenedException : ModbusException - { - public SerialPortNotOpenedException() - : base() - { - } - - public SerialPortNotOpenedException(string message) - : base(message) - { - } - - public SerialPortNotOpenedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected SerialPortNotOpenedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Connection to Modbus device failed - /// - public class ConnectionException : ModbusException - { - public ConnectionException() - : base() - { - } - - public ConnectionException(string message) - : base(message) - { - } - - public ConnectionException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected ConnectionException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "Function code not supported" - /// - public class FunctionCodeNotSupportedException : ModbusException - { - public FunctionCodeNotSupportedException() - : base() - { - } - - public FunctionCodeNotSupportedException(string message) - : base(message) - { - } - - public FunctionCodeNotSupportedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected FunctionCodeNotSupportedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "quantity invalid" - /// - public class QuantityInvalidException : ModbusException - { - public QuantityInvalidException() - : base() - { - } - - public QuantityInvalidException(string message) - : base(message) - { - } - - public QuantityInvalidException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected QuantityInvalidException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "starting adddress and quantity invalid" - /// - public class StartingAddressInvalidException : ModbusException - { - public StartingAddressInvalidException() - : base() - { - } - - public StartingAddressInvalidException(string message) - : base(message) - { - } - - public StartingAddressInvalidException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected StartingAddressInvalidException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "Function Code not executed (0x04)" - /// - public class ModbusException : Exception - { - public ModbusException() - : base() - { - } - - public ModbusException(string message) - : base(message) - { - } - - public ModbusException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected ModbusException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if CRC Check failed - /// - public class CRCCheckFailedException : ModbusException - { - public CRCCheckFailedException() - : base() - { - } - - public CRCCheckFailedException(string message) - : base(message) - { - } - - public CRCCheckFailedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected CRCCheckFailedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - -} diff --git a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Core.cs b/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Core.cs deleted file mode 100644 index 16b6cb4..0000000 --- a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Core.cs +++ /dev/null @@ -1,328 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Net.Sockets; -using System.IO.Ports; - - - - - -namespace EasyModbus -{ - - public partial class ModbusClient - { - - - #region Class Variables - private bool debug = false; - private TcpClient tcpClient; - private bool udpFlag = false; - private string ipAddress = "127.0.0.1"; - private int port = 502; - private int baudRate = 9600; - private int connectTimeout = 1000; - private bool connected; - - 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 bool dataReceived = false; - private int bytesToRead = 0; - public byte[] sendData; - public byte[] receiveData; - private byte[] readBuffer = new byte[256]; - private int portOut; - - public int NumberOfRetries { get; set; } = 3; - private int countRetries = 0; - - private uint transactionIdentifierInternal = 0; - private byte[] transactionIdentifier = new byte[2]; - - private SerialPort serialport; - private bool receiveActive = false; - - public delegate void ConnectedChangedHandler(object sender); - public event ConnectedChangedHandler ConnectedChanged; - - public delegate void ReceiveDataChangedHandler(object sender); - public event ReceiveDataChangedHandler ReceiveDataChanged; - - public delegate void SendDataChangedHandler(object sender); - public event SendDataChangedHandler SendDataChanged; - - NetworkStream stream; - #endregion - - - /// - /// 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); - tcpClient = new TcpClient(); - var result = tcpClient.BeginConnect(ipAddress, port, null, null); - var success = result.AsyncWaitHandle.WaitOne(connectTimeout); - if (!success) - { - throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); - } - tcpClient.EndConnect(result); - - //tcpClient = new TcpClient(ipAddress, port); - stream = tcpClient.GetStream(); - stream.ReadTimeout = connectTimeout; - connected = true; - } - else - { - tcpClient = new TcpClient(); - connected = true; - } - - if (ConnectedChanged != null) - ConnectedChanged(this); - } - - - /// - /// Close connection to Master Device. - /// - public void Disconnect() - { - if (debug) StoreLogData.Instance.Store("Disconnect", System.DateTime.Now); - if (serialport != null) - { - if (serialport.IsOpen & !receiveActive) - serialport.Close(); - if (ConnectedChanged != null) - ConnectedChanged(this); - return; - } - if (stream != null) - stream.Close(); - if (tcpClient != null) - tcpClient.Close(); - connected = false; - if (ConnectedChanged != null) - ConnectedChanged(this); - - } - - - - /// - /// Read Discrete Inputs from Server device (FC2). - /// - /// First discrete input to read - /// 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 (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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"); - } - - // Create Request - ApplicationDataUnit request = new ApplicationDataUnit(2); - request.QuantityRead = (ushort)quantity; - request.StartingAddressRead = (ushort)startingAddress; - request.TransactionIdentifier = (ushort)transactionIdentifierInternal; - - - ApplicationDataUnit response = new ApplicationDataUnit(2); - response.QuantityRead = (ushort)quantity; - - byte[] data = new byte[255]; - if (serialport != null) - { - dataReceived = false; - if (quantity % 8 == 0) - bytesToRead = 5 + quantity / 8; - else - bytesToRead = 6 + quantity / 8; - - serialport.Write(request.Payload, 6, 8); - if (debug) - { - byte[] debugData = new byte[8]; - Array.Copy(request.Payload, 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(request.Payload, 6, sendData, 0, 8); - SendDataChanged(this); - - } - - - - readBuffer = new byte[256]; - DateTime dateTimeSend = DateTime.UtcNow; - - response.UnitIdentifier = 0xFF; - - while (response.UnitIdentifier != unitIdentifier & !((DateTime.UtcNow.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * connectTimeout)) - { - while (dataReceived == false & !((DateTime.UtcNow.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * connectTimeout)) - System.Threading.Thread.Sleep(1); - data = new byte[255]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - - } - if (response.UnitIdentifier != unitIdentifier) - data = new byte[255]; - else - countRetries = 0; - } - else if (tcpClient.Client.Connected | udpFlag) - { - if (udpFlag) - { - UdpClient udpClient = new UdpClient(); - System.Net.IPEndPoint endPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port); - udpClient.Send(data, data.Length - 2, endPoint); - portOut = ((System.Net.IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - else - { - stream.Write(request.Payload, 0, request.Payload.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); - } - data = new Byte[255]; - int NumberOfBytes = stream.Read(response.Payload, 0, response.Payload.Length); - if (ReceiveDataChanged != null) - { - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x82 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadDiscreteInputs(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 ReadDiscreteInputs(startingAddress, quantity); - } - } - } - - return response.RegisterDataBool; - } - - - - - } -} diff --git a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Helpers.cs b/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Helpers.cs deleted file mode 100644 index e9340b8..0000000 --- a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Helpers.cs +++ /dev/null @@ -1,508 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace EasyModbus -{ - public partial class ModbusClient - { - - public enum RegisterOrder { LowHigh = 0, HighLow = 1 }; - - /// - /// Calculates the CRC16 for Modbus-RTU - /// - /// Byte buffer to send - /// Number of bytes to calculate CRC - /// First byte in buffer to start calculating CRC - internal 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, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, - 0xC0, 0x80, 0x41, 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, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, - 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 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, 0x80, 0x41, 0x01, - 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 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, - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, - 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, - 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, - 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, - 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, - 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, - 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, - 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, - 0x40 - }; - UInt16 usDataLen = numberOfBytes; - byte uchCRCHi = 0xFF; - byte uchCRCLo = 0xFF; - int i = 0; - int uIndex; - while (usDataLen > 0) - { - usDataLen--; - if ((i + startByte) < data.Length) - { - uIndex = uchCRCLo ^ data[i + startByte]; - uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]); - uchCRCHi = auchCRCLo[uIndex]; - } - i++; - } - return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); - } - - /// - /// Converts two ModbusRegisters to Float - Example: EasyModbus.ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(19,2)) - /// - /// Two Register values received from Modbus - /// Connected float value - public static float ConvertRegistersToFloat(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] floatBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToSingle(floatBytes, 0); - } - - - /// - /// Converts two ModbusRegisters to Float, Registers can by swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// 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] }; - return ConvertRegistersToFloat(swappedRegisters); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer value - /// - /// Two Register values received from Modbus - /// Connected 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] doubleBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt32(doubleBytes, 0); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer Value - Registers can be swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connecteds 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers, RegisterOrder registerOrder) - { - int[] swappedRegisters = { registers[0], registers[1] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[1], registers[0] }; - return ConvertRegistersToInt(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - - public static Int64 ConvertRegistersToLong(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt64(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected 64 Bit Integer value - public static Int64 ConvertRegistersToLong(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToLong(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - public static double ConvertRegistersToDouble(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToDouble(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected double prec. float value - public static double ConvertRegistersToDouble(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToDouble(swappedRegisters); - } - - /// - /// Converts float to two ModbusRegisters - Example: modbusClient.WriteMultipleRegisters(24, EasyModbus.ModbusClient.ConvertFloatToTwoRegisters((float)1.22)); - /// - /// Float value which has to be converted into two registers - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue) - { - byte[] floatBytes = BitConverter.GetBytes(floatValue); - byte[] highRegisterBytes = - { - floatBytes[2], - floatBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - floatBytes[0], - floatBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts float to two ModbusRegisters Registers - Registers can be swapped - /// - /// Float value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertFloatToRegisters(floatValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters - /// - /// Int value which has to be converted into two registers - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue) - { - byte[] doubleBytes = BitConverter.GetBytes(intValue); - byte[] highRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters Registers - Registers can be swapped - /// - /// Double value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertIntToRegisters(intValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - /// - /// long value which has to be converted into four registers - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue) - { - byte[] longBytes = BitConverter.GetBytes(longValue); - byte[] highRegisterBytes = - { - longBytes[6], - longBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - longBytes[4], - longBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - longBytes[2], - longBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - longBytes[0], - longBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - Registers can be swapped - /// - /// long value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertLongToRegisters(longValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec Value to four ModbusRegisters - /// - /// double value which has to be converted into four registers - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue) - { - byte[] doubleBytes = BitConverter.GetBytes(doubleValue); - byte[] highRegisterBytes = - { - doubleBytes[6], - doubleBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - doubleBytes[4], - doubleBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec. Value to four ModbusRegisters - Registers can be swapped - /// - /// double value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertDoubleToRegisters(doubleValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 16 - Bit Register values to String - /// - /// Register array received via Modbus - /// First Register containing the String to convert - /// 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++) - { - registerResult = BitConverter.GetBytes(registers[offset + i]); - result[i * 2] = registerResult[0]; - result[i * 2 + 1] = registerResult[1]; - } - return System.Text.Encoding.Default.GetString(result); - } - - /// - /// Converts a String to 16 - Bit Registers - /// - /// Register array received via Modbus - /// Converted String - public static int[] ConvertStringToRegisters(string stringToConvert) - { - byte[] array = System.Text.Encoding.ASCII.GetBytes(stringToConvert); - int[] returnarray = new int[stringToConvert.Length / 2 + stringToConvert.Length % 2]; - for (int i = 0; i < returnarray.Length; i++) - { - returnarray[i] = array[i * 2]; - if (i * 2 + 1 < array.Length) - { - returnarray[i] = returnarray[i] | ((int)array[i * 2 + 1] << 8); - } - } - return returnarray; - } - - - - } -} diff --git a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Protocol.cs b/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Protocol.cs deleted file mode 100644 index 161ffba..0000000 --- a/EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Protocol.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace EasyModbus -{ - - - - /// - /// Protocol Data Unit (PDU) - As Specified in the Modbus Appliction Protocol specification V1.1b3 Page 3 - /// The PDU consists of: - /// Function code - 1 byte - /// Data - x bytes - /// The "Data" section is described in the Documentation of the Function code and will be created according to the given Function code - /// - class ProtocolDataUnit - { - public byte FunctionCode { get; set; } - private byte[] data; - public ushort StartingAddressRead { get; set; } - public ushort StartingAddressWrite { get; set; } - public ushort QuantityRead { get; set; } - public ushort QuantityWrite { get; set; } - public byte ByteCount { get; } - public byte ErroCode { get; } - public byte ExceptionCode { get; } - public int[] RegisterDataInt { get; set; } - - public bool[] RegisterDataBool { get; set; } - - - - public byte[] Data - { - //return the data in case of a request - get - { - Byte[] returnvalue = null; - switch (FunctionCode) - { - - // FC01 (0x01) "Read Coils" Page 11 - case 1: - returnvalue = new byte[] - { - BitConverter.GetBytes((ushort)StartingAddressRead)[1], - BitConverter.GetBytes((ushort)StartingAddressRead)[0], - BitConverter.GetBytes((ushort)QuantityRead)[1], - BitConverter.GetBytes((ushort)QuantityRead)[0], - - }; - break; - // FC02 (0x02) "Read Discrete Inputs" Page 12 - case 2: - returnvalue = new byte[] - { - BitConverter.GetBytes((ushort)StartingAddressRead)[1], - BitConverter.GetBytes((ushort)StartingAddressRead)[0], - BitConverter.GetBytes((ushort)QuantityRead)[1], - BitConverter.GetBytes((ushort)QuantityRead)[0], - - }; - break; - } - return returnvalue; - } - //set the data in case of a response - set - { - switch (FunctionCode) - { - // FC 01: Read Coils and 02 Read Discrete Inputs provide the same response - case 1: case 2: - byte byteCount = value[1]; - RegisterDataBool = new bool[QuantityRead]; - for (int i = 0; i < QuantityRead; i++) - { - int intData = data[i / 8]; - int mask = Convert.ToInt32(Math.Pow(2, (i % 8))); - RegisterDataBool[i] = (Convert.ToBoolean((intData & mask) / mask)); - } - break; - - } - } - - - } - - } - - /// - /// Application Data Unit (ADU) - As Specified in the Modbus Appliction Protocol specification V1.1b3 Page 3 (or Modbus Messaging on TCP/IP Implementation Guide Page 4) - /// The ADU consists of: - /// - /// MBAP Header (only for Modbus TCP) - /// Transaction Identifier - 2 Bytes - /// Protocol Identiifier - 2 Bytes - /// Length - 2 Bytes - /// - /// Additional Address - 1 byte - /// PDU - x Byte - /// CRC - 2 byte (not used for Modbus TCP) - /// The "Data" section is described in the Documentation of the Function code and will be created according to the given Function code - /// - class ApplicationDataUnit : ProtocolDataUnit - { - - public ushort TransactionIdentifier { get; set; } - private ushort protocolIdentifier = 0; - - public byte UnitIdentifier { get; set; } - /// - /// Constructor, the Function code has to be handed over at instantiation - /// - /// - public ApplicationDataUnit(byte functionCode) - { - this.FunctionCode = functionCode; - } - - public byte[] Mbap_Header - { - get - { - ushort length = 0x0006; - if (FunctionCode == 15) - { - byte byteCount = (byte)((RegisterDataBool.Length % 8 != 0 ? RegisterDataBool.Length / 8 + 1 : (RegisterDataBool.Length / 8))); - length = (ushort)(7 + byteCount); - } - if (FunctionCode == 16) - length = (ushort)(7 + RegisterDataInt.Length * 2); - if (FunctionCode == 23) - length = (ushort)(11 + RegisterDataInt.Length * 2); - - Byte[] returnvalue = new byte[] - { - BitConverter.GetBytes((ushort)TransactionIdentifier)[1], - BitConverter.GetBytes((ushort)TransactionIdentifier)[0], - BitConverter.GetBytes((ushort)protocolIdentifier)[1], - BitConverter.GetBytes((ushort)protocolIdentifier)[0], - BitConverter.GetBytes((ushort)length)[1], - BitConverter.GetBytes((ushort)length)[0], - UnitIdentifier - }; - - return returnvalue; - } - } - - - - public byte[] Payload { - // Return the Payload in case of a request - get - { - List returnvalue = new List(); - - returnvalue.AddRange(this.Mbap_Header); - returnvalue.Add(FunctionCode); - returnvalue.AddRange(Data); - - byte [] crc = BitConverter.GetBytes(ModbusClient.calculateCRC(returnvalue.ToArray(), (ushort)(returnvalue.Count - 8), 6)); - returnvalue.AddRange(crc); - return returnvalue.ToArray(); - } - // Set the Payload in case of a resonse - set - { - - TransactionIdentifier = BitConverter.ToUInt16(value, 0); - UnitIdentifier = value[6]; - - } - - - } - - - } - - - - - } diff --git a/EasyModbus_Net60/AdvancedModbusClient.cs b/EasyModbus_Net60/AdvancedModbusClient.cs deleted file mode 100644 index 2c322f0..0000000 --- a/EasyModbus_Net60/AdvancedModbusClient.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace EasyModbus -{ - public partial class ModbusClient - { - /* - public enum DataType { Short = 0, UShort = 1, Long = 2, ULong = 3, Float = 4, Double = 5 }; - public object[] ReadHoldingRegisters(int startingAddress, int quantity, DataType dataType, RegisterOrder registerOrder) - { - int quantityToRead = quantity; - if (dataType == DataType.Long | dataType == DataType.ULong | dataType == DataType.Float) - quantityToRead = quantity * 2; - if (dataType == DataType.Float) - quantityToRead = quantity * 4; - int[] response = this.ReadHoldingRegisters(startingAddress, quantityToRead); - switch (dataType) - { - case DataType.Short: return response.Cast().ToArray(); - break; - default: return response.Cast().ToArray(); - break; - - } - - - } - */ - } -} diff --git a/EasyModbus_Net60/EasyModbus_Net60.csproj b/EasyModbus_Net60/EasyModbus_Net60.csproj deleted file mode 100644 index 27f1e16..0000000 --- a/EasyModbus_Net60/EasyModbus_Net60.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - net6.0 - enable - enable - EasyModbus - EasyModbus - - - - - - - diff --git a/EasyModbus_Net60/Exceptions/Exceptions.cs b/EasyModbus_Net60/Exceptions/Exceptions.cs deleted file mode 100644 index 8d1db4f..0000000 --- a/EasyModbus_Net60/Exceptions/Exceptions.cs +++ /dev/null @@ -1,211 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -using System; -using System.Runtime.Serialization; - -namespace EasyModbus.Exceptions -{ - /// - /// Exception to be thrown if serial port is not opened - /// - public class SerialPortNotOpenedException : ModbusException - { - public SerialPortNotOpenedException() - : base() - { - } - - public SerialPortNotOpenedException(string message) - : base(message) - { - } - - public SerialPortNotOpenedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected SerialPortNotOpenedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Connection to Modbus device failed - /// - public class ConnectionException : ModbusException - { - public ConnectionException() - : base() - { - } - - public ConnectionException(string message) - : base(message) - { - } - - public ConnectionException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected ConnectionException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "Function code not supported" - /// - public class FunctionCodeNotSupportedException : ModbusException - { - public FunctionCodeNotSupportedException() - : base() - { - } - - public FunctionCodeNotSupportedException(string message) - : base(message) - { - } - - public FunctionCodeNotSupportedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected FunctionCodeNotSupportedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "quantity invalid" - /// - public class QuantityInvalidException : ModbusException - { - public QuantityInvalidException() - : base() - { - } - - public QuantityInvalidException(string message) - : base(message) - { - } - - public QuantityInvalidException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected QuantityInvalidException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "starting adddress and quantity invalid" - /// - public class StartingAddressInvalidException : ModbusException - { - public StartingAddressInvalidException() - : base() - { - } - - public StartingAddressInvalidException(string message) - : base(message) - { - } - - public StartingAddressInvalidException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected StartingAddressInvalidException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if Modbus Server returns error code "Function Code not executed (0x04)" - /// - public class ModbusException : Exception - { - public ModbusException() - : base() - { - } - - public ModbusException(string message) - : base(message) - { - } - - public ModbusException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected ModbusException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - - /// - /// Exception to be thrown if CRC Check failed - /// - public class CRCCheckFailedException : ModbusException - { - public CRCCheckFailedException() - : base() - { - } - - public CRCCheckFailedException(string message) - : base(message) - { - } - - public CRCCheckFailedException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected CRCCheckFailedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } - -} diff --git a/EasyModbus_Net60/ModbusClient.cs b/EasyModbus_Net60/ModbusClient.cs deleted file mode 100644 index c1e8f38..0000000 --- a/EasyModbus_Net60/ModbusClient.cs +++ /dev/null @@ -1,2851 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -using System; -using System.Net.Sockets; -using System.Net; -using System.IO.Ports; -using System.Reflection; -using System.Text; -using System.Collections.Generic; - -namespace EasyModbus -{ - /// - /// 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 uint transactionIdentifierInternal = 0; - 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 bool udpFlag = false; - private int portOut; - private int baudRate = 9600; - private int connectTimeout = 1000; - public byte[] receiveData; - public byte[] sendData; - private SerialPort serialport; - private Parity parity = Parity.Even; - private StopBits stopBits = StopBits.One; - private bool connected = false; - public int NumberOfRetries { get; set; } = 3; - private int countRetries = 0; - - public delegate void ReceiveDataChangedHandler(object sender); - public event ReceiveDataChangedHandler ReceiveDataChanged; - - public delegate void SendDataChangedHandler(object sender); - public event SendDataChangedHandler SendDataChanged; - - public delegate void ConnectedChangedHandler(object sender); - 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); -#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; - } - - /// - /// Constructor which determines the Serial-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 (!COMMERCIAL) - Console.WriteLine("EasyModbus Client Library Version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); - Console.WriteLine("Copyright (c) Stefan Rossmann Engineering Solutions"); - Console.WriteLine(); -#endif - this.serialport = new SerialPort(); - serialport.PortName = serialPort; - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - } - - /// - /// Parameterless constructor - /// - public ModbusClient() - { - 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() - { - if (serialport != null) - { - if (!serialport.IsOpen) - { - if (debug) StoreLogData.Instance.Store("Open Serial port " + serialport.PortName,System.DateTime.Now); - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - serialport.Open(); - connected = true; - - - } - if (ConnectedChanged != null) - try - { - ConnectedChanged(this); - } - catch - { - - } - return; - } - if (!udpFlag) - { - if (debug) StoreLogData.Instance.Store("Open TCP-Socket, IP-Address: " + ipAddress + ", Port: " + port, System.DateTime.Now); - tcpClient = new TcpClient(); - var result = tcpClient.BeginConnect(ipAddress, port, null, null); - var success = result.AsyncWaitHandle.WaitOne(connectTimeout); - if (!success) - { - throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); - } - tcpClient.EndConnect(result); - - //tcpClient = new TcpClient(ipAddress, port); - stream = tcpClient.GetStream(); - stream.ReadTimeout = connectTimeout; - connected = true; - } - else - { - tcpClient = new TcpClient(); - connected = true; - } - if (ConnectedChanged != null) - try - { - ConnectedChanged(this); - } - catch - { - - } - } - - /// - /// 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); - tcpClient = new TcpClient(); - var result = tcpClient.BeginConnect(ipAddress, port, null, null); - var success = result.AsyncWaitHandle.WaitOne(connectTimeout); - if (!success) - { - throw new EasyModbus.Exceptions.ConnectionException("connection timed out"); - } - tcpClient.EndConnect(result); - - //tcpClient = new TcpClient(ipAddress, port); - stream = tcpClient.GetStream(); - stream.ReadTimeout = connectTimeout; - connected = true; - } - else - { - tcpClient = new TcpClient(); - connected = true; - } - - if (ConnectedChanged != null) - ConnectedChanged(this); - } - - /// - /// Converts two ModbusRegisters to Float - Example: EasyModbus.ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(19,2)) - /// - /// Two Register values received from Modbus - /// Connected float value - public static float ConvertRegistersToFloat(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] floatBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToSingle(floatBytes, 0); - } - - /// - /// Converts two ModbusRegisters to Float, Registers can by swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// 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]}; - return ConvertRegistersToFloat(swappedRegisters); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer value - /// - /// Two Register values received from Modbus - /// Connected 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers) - { - if (registers.Length != 2) - throw new ArgumentException("Input Array length invalid - Array langth must be '2'"); - int highRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] doubleBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt32(doubleBytes, 0); - } - - /// - /// Converts two ModbusRegisters to 32 Bit Integer Value - Registers can be swapped - /// - /// Two Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connecteds 32 Bit Integer value - public static Int32 ConvertRegistersToInt(int[] registers, RegisterOrder registerOrder) - { - int[] swappedRegisters = { registers[0], registers[1] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[1], registers[0] }; - return ConvertRegistersToInt(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - public static Int64 ConvertRegistersToLong(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToInt64(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit Integer value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected 64 Bit Integer value - public static Int64 ConvertRegistersToLong(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToLong(swappedRegisters); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value Register Order "LowHigh": Reg0: Low Word.....Reg3: High Word, "HighLow": Reg0: High Word.....Reg3: Low Word - /// - /// four Register values received from Modbus - /// 64 bit value - public static double ConvertRegistersToDouble(int[] registers) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int highRegister = registers[3]; - int highLowRegister = registers[2]; - int lowHighRegister = registers[1]; - int lowRegister = registers[0]; - byte[] highRegisterBytes = BitConverter.GetBytes(highRegister); - byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister); - byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister); - byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister); - byte[] longBytes = { - lowRegisterBytes[0], - lowRegisterBytes[1], - lowHighRegisterBytes[0], - lowHighRegisterBytes[1], - highLowRegisterBytes[0], - highLowRegisterBytes[1], - highRegisterBytes[0], - highRegisterBytes[1] - }; - return BitConverter.ToDouble(longBytes, 0); - } - - /// - /// Convert four 16 Bit Registers to 64 Bit double prec. value - Registers can be swapped - /// - /// four Register values received from Modbus - /// Desired Word Order (Low Register first or High Register first - /// Connected double prec. float value - public static double ConvertRegistersToDouble(int[] registers, RegisterOrder registerOrder) - { - if (registers.Length != 4) - throw new ArgumentException("Input Array length invalid - Array langth must be '4'"); - int[] swappedRegisters = { registers[0], registers[1], registers[2], registers[3] }; - if (registerOrder == RegisterOrder.HighLow) - swappedRegisters = new int[] { registers[3], registers[2], registers[1], registers[0] }; - return ConvertRegistersToDouble(swappedRegisters); - } - - /// - /// Converts float to two ModbusRegisters - Example: modbusClient.WriteMultipleRegisters(24, EasyModbus.ModbusClient.ConvertFloatToTwoRegisters((float)1.22)); - /// - /// Float value which has to be converted into two registers - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue) - { - byte[] floatBytes = BitConverter.GetBytes(floatValue); - byte[] highRegisterBytes = - { - floatBytes[2], - floatBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - floatBytes[0], - floatBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts float to two ModbusRegisters Registers - Registers can be swapped - /// - /// Float value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertFloatToRegisters(float floatValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertFloatToRegisters(floatValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters - /// - /// Int value which has to be converted into two registers - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue) - { - byte[] doubleBytes = BitConverter.GetBytes(intValue); - byte[] highRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 32 Bit Value to two ModbusRegisters Registers - Registers can be swapped - /// - /// Double value which has to be converted into two registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertIntToRegisters(Int32 intValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertIntToRegisters(intValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new Int32[] { registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - /// - /// long value which has to be converted into four registers - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue) - { - byte[] longBytes = BitConverter.GetBytes(longValue); - byte[] highRegisterBytes = - { - longBytes[6], - longBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - longBytes[4], - longBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - longBytes[2], - longBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - longBytes[0], - longBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit Value to four ModbusRegisters - Registers can be swapped - /// - /// long value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertLongToRegisters(Int64 longValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertLongToRegisters(longValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec Value to four ModbusRegisters - /// - /// double value which has to be converted into four registers - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue) - { - byte[] doubleBytes = BitConverter.GetBytes(doubleValue); - byte[] highRegisterBytes = - { - doubleBytes[6], - doubleBytes[7], - 0, - 0 - }; - byte[] highLowRegisterBytes = - { - doubleBytes[4], - doubleBytes[5], - 0, - 0 - }; - byte[] lowHighRegisterBytes = - { - doubleBytes[2], - doubleBytes[3], - 0, - 0 - }; - byte[] lowRegisterBytes = - { - - doubleBytes[0], - doubleBytes[1], - 0, - 0 - }; - int[] returnValue = - { - BitConverter.ToInt32(lowRegisterBytes,0), - BitConverter.ToInt32(lowHighRegisterBytes,0), - BitConverter.ToInt32(highLowRegisterBytes,0), - BitConverter.ToInt32(highRegisterBytes,0) - }; - return returnValue; - } - - /// - /// Converts 64 Bit double prec. Value to four ModbusRegisters - Registers can be swapped - /// - /// double value which has to be converted into four registers - /// Desired Word Order (Low Register first or High Register first - /// Register values - public static int[] ConvertDoubleToRegisters(double doubleValue, RegisterOrder registerOrder) - { - int[] registerValues = ConvertDoubleToRegisters(doubleValue); - int[] returnValue = registerValues; - if (registerOrder == RegisterOrder.HighLow) - returnValue = new int[] { registerValues[3], registerValues[2], registerValues[1], registerValues[0] }; - return returnValue; - } - - /// - /// Converts 16 - Bit Register values to String - /// - /// Register array received via Modbus - /// First Register containing the String to convert - /// 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++) - { - registerResult = BitConverter.GetBytes(registers[offset + i]); - result[i * 2] = registerResult[0]; - result[i * 2 + 1] = registerResult[1]; - } - return System.Text.Encoding.Default.GetString(result); - } - - /// - /// Converts a String to 16 - Bit Registers - /// - /// Register array received via Modbus - /// Converted String - public static int[] ConvertStringToRegisters(string stringToConvert) - { - byte[] array = System.Text.Encoding.ASCII.GetBytes(stringToConvert); - int[] returnarray = new int[stringToConvert.Length / 2 + stringToConvert.Length % 2]; - for (int i = 0; i < returnarray.Length; i++) - { - returnarray[i] = array[i * 2]; - if (i*2 +1< array.Length) - { - returnarray[i] = returnarray[i] | ((int)array[i * 2 + 1] << 8); - } - } - return returnarray; - } - - - /// - /// Calculates the CRC16 for Modbus-RTU - /// - /// Byte buffer to send - /// 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, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, - 0xC0, 0x80, 0x41, 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, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, - 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 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, 0x80, 0x41, 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, 0x80, 0x41, 0x01, - 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 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, - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, - 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, - 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, - 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, - 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, - 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, - 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, - 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, - 0x40 - }; - UInt16 usDataLen = numberOfBytes; - byte uchCRCHi = 0xFF ; - byte uchCRCLo = 0xFF ; - int i = 0; - int uIndex ; - while (usDataLen>0) - { - usDataLen--; - if ((i + startByte) < data.Length) - { - uIndex = uchCRCLo ^ data[i + startByte]; - uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]); - uchCRCHi = auchCRCLo[uIndex]; - } - i++; - } - return (UInt16)((UInt16)uchCRCHi << 8 | uchCRCLo); - } - - private bool dataReceived = false; - private bool receiveActive = false; - private byte[] readBuffer = new byte[256]; - 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; - } - - 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); - - } - - - //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; - if (bytesToRead == 0) - { - sp.DiscardInBuffer(); - receiveActive = false; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - return; - } - readBuffer = new byte[256]; - 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){ - - } - - if (bytesToRead <= actualPositionToRead) - break; - - if (DetectValidModbusFrame(readBuffer, (actualPositionToRead < readBuffer.Length) ? actualPositionToRead : readBuffer.Length) | bytesToRead <= actualPositionToRead) - break; - } - 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); - bytesToRead = 0; - - - - - dataReceived = true; - receiveActive = false; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - if (ReceiveDataChanged != null) - { - - 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; - //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; - return true; - } - - - - /// - /// Read Discrete Inputs from Server device (FC2). - /// - /// First discrete input to read - /// 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 (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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); - 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] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - - if (serialport != null) - { - dataReceived = false; - if (quantity % 8 == 0) - bytesToRead = 5 + quantity / 8; - else - 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); - } - 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; - - - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x82 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadDiscreteInputs(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 ReadDiscreteInputs(startingAddress, 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); - } - - - /// - /// Read Coils from Server device (FC1). - /// - /// First coil to read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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[]{ - 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] - }; - - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - if (quantity % 8 == 0) - bytesToRead = 5 + quantity/8; - else - 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); - } - 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; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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 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); - - } - 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-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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x81 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadCoils(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 ReadCoils(startingAddress, 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); - } - - - /// - /// Read Holding Registers from Master device (FC3). - /// - /// First holding register to be read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 5 + 2 * quantity; -// 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); - } - 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; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - if (SendDataChanged != null) - { - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x83 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadHoldingRegisters(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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 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); - } - - - - /// - /// Read Input Registers from Master device (FC4). - /// - /// First input register to be read - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 5 + 2 * quantity; - - - // 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); - } - 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; - - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x84 & data[8] == 0x04) - { - 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) - { - if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - return ReadInputRegisters(startingAddress, quantity); - } - } - else if (!dataReceived) - { - 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). - /// - /// Coil 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - throw new EasyModbus.Exceptions.ConnectionException("connection error"); - } - byte[] coilValue = new byte[2]; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)0x0006); - this.functionCode = 0x05; - this.startingAddress = BitConverter.GetBytes(startingAddress); - if (value == true) - { - coilValue = BitConverter.GetBytes((int)0xFF00); - } - else - { - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 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); - } - 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; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x85 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteSingleCoil(startingAddress, value); - } - } - else if (!dataReceived) - { - 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++; - WriteSingleCoil(startingAddress, value); - } - } - } - } - - - /// - /// Write single Register to Master device (FC6). - /// - /// Register to be written - /// 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); - transactionIdentifierInternal++; - if (serialport != null) - if (!serialport.IsOpen) - { - 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); - 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], - this.crc[0], - this.crc[1] - }; - crc = BitConverter.GetBytes(calculateCRC(data, 6, 6)); - data[12] = crc[0]; - data[13] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 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); - } - 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; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x86 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteSingleRegister(startingAddress, value); - } - } - else if (!dataReceived) - { - 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++; - WriteSingleRegister(startingAddress, value); - } - } - } - } - - /// - /// Write multiple coils to Master device (FC15). - /// - /// First coil to be written - /// Coil Values to be written - 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); - transactionIdentifierInternal++; - 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); - 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); - 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.functionCode = 0x0F; - this.startingAddress = BitConverter.GetBytes(startingAddress); - - - - 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[10] = quantityOfOutputs[1]; - data[11] = quantityOfOutputs[0]; - data[12] = byteCount; - for (int i = 0; i < values.Length; i++) - { - if ((i % 8) == 0) - singleCoilValue = 0; - byte CoilValue; - if (values[i] == true) - CoilValue = 1; - else - CoilValue = 0; - - - singleCoilValue = (byte)((int)CoilValue<<(i%8) | (int)singleCoilValue); - - data[13 + (i / 8)] = singleCoilValue; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 8; - // 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); - } - 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; - byte receivedUnitIdentifier = 0xFF; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x8F & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteMultipleCoils(startingAddress, values); - } - } - else if (!dataReceived) - { - 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++; - WriteMultipleCoils(startingAddress, values); - } - } - } - } - - /// - /// Write multiple registers to Master device (FC16). - /// - /// First register to be written - /// register Values to be written - 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); - 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); - 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); - 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.functionCode = 0x10; - this.startingAddress = BitConverter.GetBytes(startingAddress); - - Byte[] data = new byte[13+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] = this.startingAddress[1]; - data[9] = this.startingAddress[0]; - data[10] = quantityOfOutputs[1]; - data[11] = quantityOfOutputs[0]; - data[12] = byteCount; - 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]; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - bytesToRead = 8; -// 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); - } - 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; - byte receivedUnitIdentifier = 0xFF; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x90 & data[8] == 0x04) - { - 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); - if (NumberOfRetries <= countRetries) - { - countRetries = 0; - throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed"); - } - else - { - countRetries++; - WriteMultipleRegisters(startingAddress, values); - } - } - else if (!dataReceived) - { - 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++; - WriteMultipleRegisters(startingAddress, values); - } - } - } - } - - /// - /// Read/Write Multiple Registers (FC23). - /// - /// First input register to read - /// Number of input registers to read - /// First input register to write - /// Values to write - /// Int Array which contains the Holding registers - public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRead, int startingAddressWrite, int[] values) - { - - 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); - transactionIdentifierInternal++; - 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); - 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); - 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"); - } - int[] response; - this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal); - this.protocolIdentifier = BitConverter.GetBytes((int)0x0000); - this.length = BitConverter.GetBytes((int)11 + values.Length * 2); - this.functionCode = 0x17; - startingAddressReadLocal = BitConverter.GetBytes(startingAddressRead); - quantityReadLocal = BitConverter.GetBytes(quantityRead); - 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; - - 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]; - } - crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data.Length - 8), 6)); - data[data.Length - 2] = crc[0]; - data[data.Length - 1] = crc[1]; - if (serialport != null) - { - dataReceived = false; - 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); - } - 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; - byte receivedUnitIdentifier = 0xFF; - 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)) - System.Threading.Thread.Sleep(1); - data = new byte[2100]; - Array.Copy(readBuffer, 0, data, 6, readBuffer.Length); - receivedUnitIdentifier = data[6]; - } - if (receivedUnitIdentifier != this.unitIdentifier) - data = new byte[2100]; - else - countRetries = 0; - } - 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); - portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - udpClient.Client.ReceiveTimeout = 5000; - endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut); - data = udpClient.Receive(ref endPoint); - } - 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); - } - 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); - 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); - 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); - 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); - throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid"); - } - if (data[7] == 0x97 & data[8] == 0x04) - { - if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now); - throw new EasyModbus.Exceptions.ModbusException("error reading"); - } - response = new int[quantityRead]; - for (int i = 0; i < quantityRead; 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); - } - - /// - /// 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) - serialport.Close(); - if (ConnectedChanged != null) - ConnectedChanged(this); - return; - } - if (stream != null) - stream.Close(); - if (tcpClient != null) - tcpClient.Close(); - connected = false; - if (ConnectedChanged != null) - ConnectedChanged(this); - - } - - /// - /// Destructor - Close connection to Master Device. - /// - ~ 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(); - } - } - - /// - /// 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 - { - if (serialport != null) - { - return (serialport.IsOpen); - } - - if (udpFlag & tcpClient != null) - return true; - if (tcpClient == null) - return false; - else - { - return connected; - - } - - } - } - - public bool Available(int timeout) - { - // Ping's the local machine. - System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping(); - IPAddress address = System.Net.IPAddress.Parse(ipAddress); - - // Create a buffer of 32 bytes of data to be transmitted. - string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - byte[] buffer = System.Text.Encoding.ASCII.GetBytes(data); - - // Wait 10 seconds for a reply. - System.Net.NetworkInformation.PingReply reply = pingSender.Send(address, timeout, buffer); - - if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) - return true; - else - return false; - } - - /// - /// Gets or Sets the IP-Address of the Server. - /// - public string IPAddress - { - 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; - } - } - - /// - /// Gets or Sets the UDP-Flag to activate Modbus UDP. - /// - public bool UDPFlag - { - get - { - return udpFlag; - } - set - { - udpFlag = value; - } - } - - /// - /// Gets or Sets the Unit identifier in case of serial connection (Default = 0) - /// - public byte UnitIdentifier - { - get - { - return unitIdentifier; - } - set - { - unitIdentifier = value; - } - } - - - /// - /// Gets or Sets the Baudrate for serial connection (Default = 9600) - /// - public int Baudrate - { - get - { - return baudRate; - } - set - { - baudRate = value; - } - } - - /// - /// Gets or Sets the of Parity in case of serial connection - /// - public Parity Parity - { - get - { - if (serialport != null) - return parity; - else - return Parity.Even; - } - set - { - if (serialport != null) - parity = value; - } - } - - - /// - /// Gets or Sets the number of stopbits in case of serial connection - /// - public StopBits StopBits - { - get - { - if (serialport != null) - return stopBits; - else - return StopBits.One; - } - set - { - if (serialport != null) - stopBits = value; - } - } - - /// - /// Gets or Sets the connection Timeout in case of ModbusTCP connection - /// - public int ConnectionTimeout - { - get - { - return connectTimeout; - } - set - { - connectTimeout = value; - } - } - - /// - /// Gets or Sets the serial Port - /// - public string SerialPort - { - get - { - - return serialport.PortName; - } - set - { - if (value == null) - { - serialport = null; - return; - } - if (serialport != null) - serialport.Close(); - this.serialport = new SerialPort(); - this.serialport.PortName = value; - serialport.BaudRate = baudRate; - serialport.Parity = parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = connectTimeout; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - } - } - - /// - /// Gets or Sets the Filename for the LogFile - /// - public string LogFileFilename - { - get - { - return StoreLogData.Instance.Filename; - } - set - { - StoreLogData.Instance.Filename = value; - if (StoreLogData.Instance.Filename != null) - debug = true; - else - debug = false; - } - } - - } -} diff --git a/EasyModbus_Net60/ModbusServer.cs b/EasyModbus_Net60/ModbusServer.cs deleted file mode 100644 index 13374cd..0000000 --- a/EasyModbus_Net60/ModbusServer.cs +++ /dev/null @@ -1,2266 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Net.Sockets; -using System.Net; -using System.Threading; -using System.Net.NetworkInformation; -using System.IO.Ports; - -namespace EasyModbus -{ -#region class ModbusProtocol - /// - /// Modbus Protocol informations. - /// - public class ModbusProtocol - { - public enum ProtocolType { ModbusTCP = 0, ModbusUDP = 1, ModbusRTU = 2}; - public DateTime timeStamp; - public bool request; - public bool response; - public UInt16 transactionIdentifier; - public UInt16 protocolIdentifier; - public UInt16 length; - public byte unitIdentifier; - public byte functionCode; - public UInt16 startingAdress; - public UInt16 startingAddressRead; - public UInt16 startingAddressWrite; - public UInt16 quantity; - public UInt16 quantityRead; - public UInt16 quantityWrite; - public byte byteCount; - public byte exceptionCode; - public byte errorCode; - public UInt16[] receiveCoilValues; - public UInt16[] receiveRegisterValues; - public Int16[] sendRegisterValues; - public bool[] sendCoilValues; - public UInt16 crc; - } -#endregion - -#region structs - struct NetworkConnectionParameter - { - public NetworkStream stream; //For TCP-Connection only - public Byte[] bytes; - public int portIn; //For UDP-Connection only - public IPAddress ipAddressIn; //For UDP-Connection only - } -#endregion - -#region TCPHandler class - internal class TCPHandler - { - public delegate void DataChanged(object networkConnectionParameter); - public event DataChanged dataChanged; - - public delegate void NumberOfClientsChanged(); - public event NumberOfClientsChanged numberOfClientsChanged; - - TcpListener server = null; - - - private List tcpClientLastRequestList = new List(); - - public int NumberOfConnectedClients { get; set; } - - public string ipAddress = null; - - /// When making a server TCP listen socket, will listen to this IP address. - public IPAddress LocalIPAddress { - get { return localIPAddress; } - } - private IPAddress localIPAddress = IPAddress.Any; - - /// - /// Listen to all network interfaces. - /// - /// TCP port to listen - public TCPHandler(int port) - { - server = new TcpListener(LocalIPAddress, port); - server.Start(); - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - } - - /// - /// Listen to a specific network interface. - /// - /// IP address of network interface to listen - /// TCP port to listen - public TCPHandler(IPAddress localIPAddress, int port) - { - this.localIPAddress = localIPAddress; - server = new TcpListener(LocalIPAddress, port); - server.Start(); - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - } - - - private void AcceptTcpClientCallback(IAsyncResult asyncResult) - { - TcpClient tcpClient = new TcpClient(); - try - { - tcpClient = server.EndAcceptTcpClient(asyncResult); - tcpClient.ReceiveTimeout = 4000; - if (ipAddress != null) - { - string ipEndpoint = tcpClient.Client.RemoteEndPoint.ToString(); - ipEndpoint = ipEndpoint.Split(':')[0]; - if (ipEndpoint != ipAddress) - { - tcpClient.Client.Disconnect(false); - return; - } - } - } - catch (Exception) { } - try - { - server.BeginAcceptTcpClient(AcceptTcpClientCallback, null); - Client client = new Client(tcpClient); - NetworkStream networkStream = client.NetworkStream; - networkStream.ReadTimeout = 4000; - networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); - } - catch (Exception) { } - } - - private int GetAndCleanNumberOfConnectedClients(Client client) - { - lock (this) - { - int i = 0; - bool objetExists = false; - foreach (Client clientLoop in tcpClientLastRequestList) - { - if (client.Equals(clientLoop)) - objetExists = true; - } - try - { - tcpClientLastRequestList.RemoveAll(delegate (Client c) - { - return ((DateTime.Now.Ticks - c.Ticks) > 40000000); - } - - ); - } - catch (Exception) { } - if (!objetExists) - tcpClientLastRequestList.Add(client); - - - return tcpClientLastRequestList.Count; - } - } - - private void ReadCallback(IAsyncResult asyncResult) - { - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - Client client = asyncResult.AsyncState as Client; - client.Ticks = DateTime.Now.Ticks; - NumberOfConnectedClients = GetAndCleanNumberOfConnectedClients(client); - if (numberOfClientsChanged != null) - numberOfClientsChanged(); - if (client != null) - { - int read; - NetworkStream networkStream = null; - try - { - networkStream = client.NetworkStream; - - read = networkStream.EndRead(asyncResult); - } - catch (Exception ex) - { - return; - } - - - if (read == 0) - { - //OnClientDisconnected(client.TcpClient); - //connectedClients.Remove(client); - return; - } - byte[] data = new byte[read]; - Buffer.BlockCopy(client.Buffer, 0, data, 0, read); - networkConnectionParameter.bytes = data; - networkConnectionParameter.stream = networkStream; - if (dataChanged != null) - dataChanged(networkConnectionParameter); - try - { - networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client); - } - catch (Exception) - { - } - } - } - - public void Disconnect() - { - try - { - foreach (Client clientLoop in tcpClientLastRequestList) - { - clientLoop.NetworkStream.Close(00); - } - } - catch (Exception) { } - server.Stop(); - - } - - - internal class Client - { - private readonly TcpClient tcpClient; - private readonly byte[] buffer; - public long Ticks { get; set; } - - public Client(TcpClient tcpClient) - { - this.tcpClient = tcpClient; - int bufferSize = tcpClient.ReceiveBufferSize; - buffer = new byte[bufferSize]; - } - - public TcpClient TcpClient - { - get { return tcpClient; } - } - - public byte[] Buffer - { - get { return buffer; } - } - - public NetworkStream NetworkStream - { - get { - - return tcpClient.GetStream(); - - } - } - } - } -#endregion - - /// - /// Modbus TCP Server. - /// - public class ModbusServer - { - private bool debug = false; - Int32 port = 502; - ModbusProtocol receiveData; - ModbusProtocol sendData = new ModbusProtocol(); - Byte[] bytes = new Byte[2100]; - //public Int16[] _holdingRegisters = new Int16[65535]; - public HoldingRegisters holdingRegisters; - public InputRegisters inputRegisters; - public Coils coils; - public DiscreteInputs discreteInputs; - private int numberOfConnections = 0; - private bool udpFlag; - private bool serialFlag; - private int baudrate = 9600; - private System.IO.Ports.Parity parity = Parity.Even; - private System.IO.Ports.StopBits stopBits = StopBits.One; - private string serialPort = "COM1"; - private SerialPort serialport; - private byte unitIdentifier = 1; - private int portIn; - private IPAddress ipAddressIn; - private UdpClient udpClient; - private IPEndPoint iPEndPoint; - private TCPHandler tcpHandler; - Thread listenerThread; - Thread clientConnectionThread; - private ModbusProtocol[] modbusLogData = new ModbusProtocol[100]; - public bool FunctionCode1Disabled {get; set;} - public bool FunctionCode2Disabled { get; set; } - public bool FunctionCode3Disabled { get; set; } - public bool FunctionCode4Disabled { get; set; } - public bool FunctionCode5Disabled { get; set; } - public bool FunctionCode6Disabled { get; set; } - public bool FunctionCode15Disabled { get; set; } - public bool FunctionCode16Disabled { get; set; } - public bool FunctionCode23Disabled { get; set; } - public bool PortChanged { get; set; } - object lockCoils = new object(); - object lockHoldingRegisters = new object(); - private volatile bool shouldStop; - - private IPAddress localIPAddress = IPAddress.Any; - - /// - /// When creating a TCP or UDP socket, the local IP address to attach to. - /// - public IPAddress LocalIPAddress - { - get { return localIPAddress; } - set { if (listenerThread == null) localIPAddress = value; } - } - - public ModbusServer() - { - holdingRegisters = new HoldingRegisters(this); - inputRegisters = new InputRegisters(this); - coils = new Coils(this); - discreteInputs = new DiscreteInputs(this); - - } - - #region events - public delegate void CoilsChangedHandler(int coil, int numberOfCoils); - public event CoilsChangedHandler CoilsChanged; - - public delegate void HoldingRegistersChangedHandler(int register, int numberOfRegisters); - public event HoldingRegistersChangedHandler HoldingRegistersChanged; - - public delegate void NumberOfConnectedClientsChangedHandler(); - public event NumberOfConnectedClientsChangedHandler NumberOfConnectedClientsChanged; - - public delegate void LogDataChangedHandler(); - public event LogDataChangedHandler LogDataChanged; - #endregion - - public void Listen() - { - - listenerThread = new Thread(ListenerThread); - listenerThread.Start(); - } - - public void StopListening() - { - if (SerialFlag & (serialport != null)) - { - if (serialport.IsOpen) - serialport.Close(); - shouldStop = true; - } - try - { - tcpHandler.Disconnect(); - listenerThread.Abort(); - - } - catch (Exception) { } - listenerThread.Join(); - try - { - - clientConnectionThread.Abort(); - } - catch (Exception) { } - } - - private void ListenerThread() - { - if (!udpFlag & !serialFlag) - { - if (udpClient != null) - { - try - { - udpClient.Close(); - } - catch (Exception) { } - } - tcpHandler = new TCPHandler(LocalIPAddress, port); - if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); - tcpHandler.dataChanged += new TCPHandler.DataChanged(ProcessReceivedData); - tcpHandler.numberOfClientsChanged += new TCPHandler.NumberOfClientsChanged(numberOfClientsChanged); - } - else if (serialFlag) - { - if (serialport == null) - { - if (debug) StoreLogData.Instance.Store("EasyModbus RTU-Server listing for incomming data at Serial Port " + serialPort, System.DateTime.Now); - serialport = new SerialPort(); - serialport.PortName = serialPort; - serialport.BaudRate = this.baudrate; - serialport.Parity = this.parity; - serialport.StopBits = stopBits; - serialport.WriteTimeout = 10000; - serialport.ReadTimeout = 1000; - serialport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); - serialport.Open(); - } - } - else - while (!shouldStop) - { - if (udpFlag) - { - if (udpClient == null | PortChanged) - { - IPEndPoint localEndoint = new IPEndPoint(LocalIPAddress, port); - udpClient = new UdpClient(localEndoint); - if (debug) StoreLogData.Instance.Store($"EasyModbus Server listing for incomming data at Port {port}, local IP {LocalIPAddress}", System.DateTime.Now); - udpClient.Client.ReceiveTimeout = 1000; - iPEndPoint = new IPEndPoint(IPAddress.Any, port); - PortChanged = false; - } - if (tcpHandler != null) - tcpHandler.Disconnect(); - try - { - bytes = udpClient.Receive(ref iPEndPoint); - portIn = iPEndPoint.Port; - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - networkConnectionParameter.bytes = bytes; - ipAddressIn = iPEndPoint.Address; - networkConnectionParameter.portIn = portIn; - networkConnectionParameter.ipAddressIn = ipAddressIn; - ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); - Thread processDataThread = new Thread(pts); - processDataThread.Start(networkConnectionParameter); - } - catch (Exception) - { - } - } - - } - } - - #region SerialHandler - private bool dataReceived = false; - private byte[] readBuffer = new byte[2094]; - private DateTime lastReceive; - private int nextSign = 0; - private void DataReceivedHandler(object sender, - SerialDataReceivedEventArgs e) - { - int silence = 4000 / baudrate; - if ((DateTime.Now.Ticks - lastReceive.Ticks) > TimeSpan.TicksPerMillisecond*silence) - nextSign = 0; - - - SerialPort sp = (SerialPort)sender; - - int numbytes = sp.BytesToRead; - byte[] rxbytearray = new byte[numbytes]; - - sp.Read(rxbytearray, 0, numbytes); - - Array.Copy(rxbytearray, 0, readBuffer, nextSign, rxbytearray.Length); - lastReceive= DateTime.Now; - nextSign = numbytes+ nextSign; - if (ModbusClient.DetectValidModbusFrame(readBuffer, nextSign)) - { - - dataReceived = true; - nextSign= 0; - - NetworkConnectionParameter networkConnectionParameter = new NetworkConnectionParameter(); - networkConnectionParameter.bytes = readBuffer; - ParameterizedThreadStart pts = new ParameterizedThreadStart(this.ProcessReceivedData); - Thread processDataThread = new Thread(pts); - processDataThread.Start(networkConnectionParameter); - dataReceived = false; - - } - else - dataReceived = false; - } - #endregion - - #region Method numberOfClientsChanged - private void numberOfClientsChanged() - { - numberOfConnections = tcpHandler.NumberOfConnectedClients; - if (NumberOfConnectedClientsChanged != null) - NumberOfConnectedClientsChanged(); - } - #endregion - - object lockProcessReceivedData = new object(); - #region Method ProcessReceivedData - private void ProcessReceivedData(object networkConnectionParameter) - { - lock (lockProcessReceivedData) - { - Byte[] bytes = new byte[((NetworkConnectionParameter)networkConnectionParameter).bytes.Length]; - if (debug) StoreLogData.Instance.Store("Received Data: " + BitConverter.ToString(bytes), System.DateTime.Now); - NetworkStream stream = ((NetworkConnectionParameter)networkConnectionParameter).stream; - int portIn = ((NetworkConnectionParameter)networkConnectionParameter).portIn; - IPAddress ipAddressIn = ((NetworkConnectionParameter)networkConnectionParameter).ipAddressIn; - - - Array.Copy(((NetworkConnectionParameter)networkConnectionParameter).bytes, 0, bytes, 0, ((NetworkConnectionParameter)networkConnectionParameter).bytes.Length); - - ModbusProtocol receiveDataThread = new ModbusProtocol(); - ModbusProtocol sendDataThread = new ModbusProtocol(); - - try - { - UInt16[] wordData = new UInt16[1]; - byte[] byteData = new byte[2]; - receiveDataThread.timeStamp = DateTime.Now; - receiveDataThread.request = true; - if (!serialFlag) - { - //Lese Transaction identifier - byteData[1] = bytes[0]; - byteData[0] = bytes[1]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.transactionIdentifier = wordData[0]; - - //Lese Protocol identifier - byteData[1] = bytes[2]; - byteData[0] = bytes[3]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.protocolIdentifier = wordData[0]; - - //Lese length - byteData[1] = bytes[4]; - byteData[0] = bytes[5]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.length = wordData[0]; - } - - //Lese unit identifier - receiveDataThread.unitIdentifier = bytes[6 - 6 * Convert.ToInt32(serialFlag)]; - //Check UnitIdentifier - if ((receiveDataThread.unitIdentifier != this.unitIdentifier) & (receiveDataThread.unitIdentifier != 0)) - return; - - // Lese function code - receiveDataThread.functionCode = bytes[7 - 6 * Convert.ToInt32(serialFlag)]; - - // Lese starting address - byteData[1] = bytes[8 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[9 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAdress = wordData[0]; - - if (receiveDataThread.functionCode <= 4) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - } - if (receiveDataThread.functionCode == 5) - { - receiveDataThread.receiveCoilValues = new ushort[1]; - // Lese Value - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveCoilValues, 0, 2); - } - if (receiveDataThread.functionCode == 6) - { - receiveDataThread.receiveRegisterValues = new ushort[1]; - // Lese Value - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, 0, 2); - } - if (receiveDataThread.functionCode == 15) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - - receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - - if ((receiveDataThread.byteCount % 2) != 0) - receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2 + 1]; - else - receiveDataThread.receiveCoilValues = new ushort[receiveDataThread.byteCount / 2]; - // Lese Value - Buffer.BlockCopy(bytes, 13 - 6 * Convert.ToInt32(serialFlag), receiveDataThread.receiveCoilValues, 0, receiveDataThread.byteCount); - } - if (receiveDataThread.functionCode == 16) - { - // Lese quantity - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantity = wordData[0]; - - receiveDataThread.byteCount = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantity]; - for (int i = 0; i < receiveDataThread.quantity; i++) - { - // Lese Value - byteData[1] = bytes[13 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[14 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); - } - - } - if (receiveDataThread.functionCode == 23) - { - // Lese starting Address Read - byteData[1] = bytes[8 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[9 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAddressRead = wordData[0]; - // Lese quantity Read - byteData[1] = bytes[10 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[11 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantityRead = wordData[0]; - // Lese starting Address Write - byteData[1] = bytes[12 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[13 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.startingAddressWrite = wordData[0]; - // Lese quantity Write - byteData[1] = bytes[14 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[15 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, wordData, 0, 2); - receiveDataThread.quantityWrite = wordData[0]; - - receiveDataThread.byteCount = bytes[16 - 6 * Convert.ToInt32(serialFlag)]; - receiveDataThread.receiveRegisterValues = new ushort[receiveDataThread.quantityWrite]; - for (int i = 0; i < receiveDataThread.quantityWrite; i++) - { - // Lese Value - byteData[1] = bytes[17 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - byteData[0] = bytes[18 + i * 2 - 6 * Convert.ToInt32(serialFlag)]; - Buffer.BlockCopy(byteData, 0, receiveDataThread.receiveRegisterValues, i * 2, 2); - } - } - } - catch (Exception exc) - { } - this.CreateAnswer(receiveDataThread, sendDataThread, stream, portIn, ipAddressIn); - //this.sendAnswer(); - this.CreateLogData(receiveDataThread, sendDataThread); - - if (LogDataChanged != null) - LogDataChanged(); - } - } - #endregion - - #region Method CreateAnswer - private void CreateAnswer(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - - switch (receiveData.functionCode) - { - // Read Coils - case 1: - if (!FunctionCode1Disabled) - this.ReadCoils(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - break; - // Read Input Registers - case 2: - if (!FunctionCode2Disabled) - this.ReadDiscreteInputs(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Read Holding Registers - case 3: - if (!FunctionCode3Disabled) - this.ReadHoldingRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Read Input Registers - case 4: - if (!FunctionCode4Disabled) - this.ReadInputRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write single coil - case 5: - if (!FunctionCode5Disabled) - this.WriteSingleCoil(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write single register - case 6: - if (!FunctionCode6Disabled) - this.WriteSingleRegister(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write Multiple coils - case 15: - if (!FunctionCode15Disabled) - this.WriteMultipleCoils(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Write Multiple registers - case 16: - if (!FunctionCode16Disabled) - this.WriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Error: Function Code not supported - case 23: - if (!FunctionCode23Disabled) - this.ReadWriteMultipleRegisters(receiveData, sendData, stream, portIn, ipAddressIn); - else - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - } - - break; - // Error: Function Code not supported - default: sendData.errorCode = (byte) (receiveData.functionCode + 0x80); - sendData.exceptionCode = 1; - sendException(sendData.errorCode, sendData.exceptionCode, receiveData, sendData, stream, portIn, ipAddressIn); - break; - } - sendData.timeStamp = DateTime.Now; - } - #endregion - - private void ReadCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if ((receiveData.quantity % 8) == 0) - sendData.byteCount = (byte)(receiveData.quantity / 8); - else - sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); - - sendData.sendCoilValues = new bool[receiveData.quantity]; - lock (lockCoils) - Array.Copy(coils.localArray, receiveData.startingAdress + 1, sendData.sendCoilValues, 0, receiveData.quantity); - } - if (true) - { - Byte[] data; - - if (sendData.exceptionCode > 0) - data = new byte[9 + 2*Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount+ 2*Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendCoilValues = null; - } - - if (sendData.sendCoilValues != null) - for (int i = 0; i < (sendData.byteCount); i++) - { - byteData = new byte[2]; - for (int j = 0; j < 8; j++) - { - - byte boolValue; - if (sendData.sendCoilValues[i * 8 + j] == true) - boolValue = 1; - else - boolValue = 0; - byteData[1] = (byte)((byteData[1]) | (boolValue << j)); - if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) - break; - } - data[9 + i] = byteData[1]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadDiscreteInputs(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x07D0)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if ((receiveData.quantity % 8) == 0) - sendData.byteCount = (byte)(receiveData.quantity / 8); - else - sendData.byteCount = (byte)(receiveData.quantity / 8 + 1); - - sendData.sendCoilValues = new bool[receiveData.quantity]; - Array.Copy(discreteInputs.localArray, receiveData.startingAdress + 1, sendData.sendCoilValues, 0, receiveData.quantity); - } - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendCoilValues = null; - } - - if (sendData.sendCoilValues != null) - for (int i = 0; i < (sendData.byteCount); i++) - { - byteData = new byte[2]; - for (int j = 0; j < 8; j++) - { - - byte boolValue; - if (sendData.sendCoilValues[i * 8 + j] == true) - boolValue = 1; - else - boolValue = 0; - byteData[1] = (byte)((byteData[1]) | (boolValue << j)); - if ((i * 8 + j + 1) >= sendData.sendCoilValues.Length) - break; - } - data[9 + i] = byteData[1]; - } - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if(debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadHoldingRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.byteCount = (byte)(2 * receiveData.quantity); - sendData.sendRegisterValues = new Int16[receiveData.quantity]; - lock (lockHoldingRegisters) - Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAdress * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - - - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void ReadInputRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - if ((receiveData.quantity < 1) | (receiveData.quantity > 0x007D)) //Invalid quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1 + receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.byteCount = (byte)(2 * receiveData.quantity); - sendData.sendRegisterValues = new Int16[receiveData.quantity]; - Buffer.BlockCopy(inputRegisters.localArray, receiveData.startingAdress * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantity * 2); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - - - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void WriteSingleCoil(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.receiveCoilValues = receiveData.receiveCoilValues; - if ((receiveData.receiveCoilValues[0] != 0x0000) & (receiveData.receiveCoilValues[0] != 0xFF00)) //Invalid Value - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - if (receiveData.receiveCoilValues[0] == 0xFF00) - { - lock (lockCoils) - coils[receiveData.startingAdress + 1] = true; - } - if (receiveData.receiveCoilValues[0] == 0x0000) - { - lock (lockCoils) - coils[receiveData.startingAdress + 1] = false; - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.receiveCoilValues[0]); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (CoilsChanged != null) - CoilsChanged(receiveData.startingAdress+1, 1); - } - } - - private void WriteSingleRegister(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.receiveRegisterValues = receiveData.receiveRegisterValues; - - if ((receiveData.receiveRegisterValues[0] < 0x0000) | (receiveData.receiveRegisterValues[0] > 0xFFFF)) //Invalid Value - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if (((receiveData.startingAdress + 1) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockHoldingRegisters) - holdingRegisters[receiveData.startingAdress + 1] = unchecked((short)receiveData.receiveRegisterValues[0]); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.receiveRegisterValues[0]); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAdress+1, 1); - } - } - - private void WriteMultipleCoils(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.quantity = receiveData.quantity; - - if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAdress + 1 + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockCoils) - for (int i = 0; i < receiveData.quantity; i++) - { - int shift = i % 16; - /* if ((i == receiveData.quantity - 1) & (receiveData.quantity % 2 != 0)) - { - if (shift < 8) - shift = shift + 8; - else - shift = shift - 8; - }*/ - int mask = 0x1; - mask = mask << (shift); - if ((receiveData.receiveCoilValues[i / 16] & (ushort)mask) == 0) - - coils[receiveData.startingAdress + i + 1] = false; - else - - coils[receiveData.startingAdress + i + 1] = true; - - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.quantity); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (CoilsChanged != null) - CoilsChanged(receiveData.startingAdress+1, receiveData.quantity); - } - } - - private void WriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - sendData.startingAdress = receiveData.startingAdress; - sendData.quantity = receiveData.quantity; - - if ((receiveData.quantity == 0x0000) | (receiveData.quantity > 0x07B0)) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAdress + 1 + (int)receiveData.quantity) > 65535) | (receiveData.startingAdress < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - lock (lockHoldingRegisters) - for (int i = 0; i < receiveData.quantity; i++) - { - holdingRegisters[receiveData.startingAdress + i + 1] = unchecked((short)receiveData.receiveRegisterValues[i]); - } - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = 0x06; - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[12 + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - byteData = BitConverter.GetBytes((int)receiveData.startingAdress); - data[8] = byteData[1]; - data[9] = byteData[0]; - byteData = BitConverter.GetBytes((int)receiveData.quantity); - data[10] = byteData[1]; - data[11] = byteData[0]; - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAdress+1, receiveData.quantity); - } - } - - private void ReadWriteMultipleRegisters(ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = this.unitIdentifier; - sendData.functionCode = receiveData.functionCode; - - - if ((receiveData.quantityRead < 0x0001) | (receiveData.quantityRead > 0x007D) | (receiveData.quantityWrite < 0x0001) | (receiveData.quantityWrite > 0x0079) | (receiveData.byteCount != (receiveData.quantityWrite * 2))) //Invalid Quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 3; - } - if ((((int)receiveData.startingAddressRead + 1 + (int)receiveData.quantityRead) > 65535) | (((int)receiveData.startingAddressWrite + 1 + (int)receiveData.quantityWrite) > 65535) | (receiveData.quantityWrite < 0) | (receiveData.quantityRead < 0)) //Invalid Starting adress or Starting address + quantity - { - sendData.errorCode = (byte)(receiveData.functionCode + 0x80); - sendData.exceptionCode = 2; - } - if (sendData.exceptionCode == 0) - { - sendData.sendRegisterValues = new Int16[receiveData.quantityRead]; - lock (lockHoldingRegisters) - Buffer.BlockCopy(holdingRegisters.localArray, receiveData.startingAddressRead * 2 + 2, sendData.sendRegisterValues, 0, receiveData.quantityRead * 2); - - lock (holdingRegisters) - for (int i = 0; i < receiveData.quantityWrite; i++) - { - holdingRegisters[receiveData.startingAddressWrite + i + 1] = unchecked((short)receiveData.receiveRegisterValues[i]); - } - sendData.byteCount = (byte)(2 * receiveData.quantityRead); - } - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = Convert.ToUInt16(3 + 2 * receiveData.quantityRead); - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - - Byte[] byteData = new byte[2]; - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - //Function Code - data[7] = sendData.functionCode; - - //ByteCount - data[8] = sendData.byteCount; - - - if (sendData.exceptionCode > 0) - { - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - sendData.sendRegisterValues = null; - } - else - { - if (sendData.sendRegisterValues != null) - for (int i = 0; i < (sendData.byteCount / 2); i++) - { - byteData = BitConverter.GetBytes((Int16)sendData.sendRegisterValues[i]); - data[9 + i * 2] = byteData[1]; - data[10 + i * 2] = byteData[0]; - } - - } - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - if (HoldingRegistersChanged != null) - HoldingRegistersChanged(receiveData.startingAddressWrite+1, receiveData.quantityWrite); - } - } - - private void sendException(int errorCode, int exceptionCode, ModbusProtocol receiveData, ModbusProtocol sendData, NetworkStream stream, int portIn, IPAddress ipAddressIn) - { - sendData.response = true; - - sendData.transactionIdentifier = receiveData.transactionIdentifier; - sendData.protocolIdentifier = receiveData.protocolIdentifier; - - sendData.unitIdentifier = receiveData.unitIdentifier; - sendData.errorCode = (byte)errorCode; - sendData.exceptionCode = (byte)exceptionCode; - - if (sendData.exceptionCode > 0) - sendData.length = 0x03; - else - sendData.length = (ushort)(0x03 + sendData.byteCount); - - if (true) - { - Byte[] data; - if (sendData.exceptionCode > 0) - data = new byte[9 + 2 * Convert.ToInt32(serialFlag)]; - else - data = new byte[9 + sendData.byteCount + 2 * Convert.ToInt32(serialFlag)]; - Byte[] byteData = new byte[2]; - sendData.length = (byte)(data.Length - 6); - - //Send Transaction identifier - byteData = BitConverter.GetBytes((int)sendData.transactionIdentifier); - data[0] = byteData[1]; - data[1] = byteData[0]; - - //Send Protocol identifier - byteData = BitConverter.GetBytes((int)sendData.protocolIdentifier); - data[2] = byteData[1]; - data[3] = byteData[0]; - - //Send length - byteData = BitConverter.GetBytes((int)sendData.length); - data[4] = byteData[1]; - data[5] = byteData[0]; - - //Unit Identifier - data[6] = sendData.unitIdentifier; - - - data[7] = sendData.errorCode; - data[8] = sendData.exceptionCode; - - - try - { - if (serialFlag) - { - if (!serialport.IsOpen) - throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened"); - //Create CRC - sendData.crc = ModbusClient.calculateCRC(data, Convert.ToUInt16(data.Length - 8), 6); - byteData = BitConverter.GetBytes((int)sendData.crc); - data[data.Length - 2] = byteData[0]; - data[data.Length - 1] = byteData[1]; - 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); - } - } - else if (udpFlag) - { - //UdpClient udpClient = new UdpClient(); - IPEndPoint endPoint = new IPEndPoint(ipAddressIn, portIn); - udpClient.Send(data, data.Length, endPoint); - - } - else - { - stream.Write(data, 0, data.Length); - if (debug) StoreLogData.Instance.Store("Send Data: " + BitConverter.ToString(data), System.DateTime.Now); - } - } - catch (Exception) { } - } - } - - private void CreateLogData(ModbusProtocol receiveData, ModbusProtocol sendData) - { - for (int i = 0; i < 98; i++) - { - modbusLogData[99 - i] = modbusLogData[99 - i - 2]; - - } - modbusLogData[0] = receiveData; - modbusLogData[1] = sendData; - - } - - - - public int NumberOfConnections - { - get - { - return numberOfConnections; - } - } - - public ModbusProtocol[] ModbusLogData - { - get - { - return modbusLogData; - } - } - - public int Port - { - get - { - return port; - } - set - { - port = value; - - - } - } - - public bool UDPFlag - { - get - { - return udpFlag; - } - set - { - udpFlag = value; - } - } - - public bool SerialFlag - { - get - { - return serialFlag; - } - set - { - serialFlag = value; - } - } - - public int Baudrate - { - get - { - return baudrate; - } - set - { - baudrate = value; - } - } - - public System.IO.Ports.Parity Parity - { - get - { - return parity; - } - set - { - parity = value; - } - } - - public System.IO.Ports.StopBits StopBits - { - get - { - return stopBits; - } - set - { - stopBits = value; - } - } - - public string SerialPort - { - get - { - return serialPort; - } - set - { - serialPort = value; - if (serialPort != null) - serialFlag = true; - else - serialFlag = false; - } - } - - public byte UnitIdentifier - { - get - { - return unitIdentifier; - } - set - { - unitIdentifier = value; - } - } - - - - - /// - /// Gets or Sets the Filename for the LogFile - /// - public string LogFileFilename - { - get - { - return StoreLogData.Instance.Filename; - } - set - { - StoreLogData.Instance.Filename = value; - if (StoreLogData.Instance.Filename != null) - debug = true; - else - debug = false; - } - } - - - - - public class HoldingRegisters - { - public Int16[] localArray = new Int16[65535]; - ModbusServer modbusServer; - - public HoldingRegisters(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public Int16 this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class InputRegisters - { - public Int16[] localArray = new Int16[65535]; - ModbusServer modbusServer; - - public InputRegisters(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public Int16 this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class Coils - { - public bool[] localArray = new bool[65535]; - ModbusServer modbusServer; - - public Coils(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public bool this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - } - - public class DiscreteInputs - { - public bool[] localArray = new bool[65535]; - ModbusServer modbusServer; - - public DiscreteInputs(EasyModbus.ModbusServer modbusServer) - { - this.modbusServer = modbusServer; - } - - public bool this[int x] - { - get { return this.localArray[x]; } - set - { - this.localArray[x] = value; - - } - } - - - } - } -} - \ No newline at end of file diff --git a/EasyModbus_Net60/StoreLogData.cs b/EasyModbus_Net60/StoreLogData.cs deleted file mode 100644 index 3345038..0000000 --- a/EasyModbus_Net60/StoreLogData.cs +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright (c) 2018-2020 Rossmann-Engineering -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software -and associated documentation files (the "Software"), -to deal in the Software without restriction, -including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission -notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace EasyModbus -{ - /// - /// Store Log-Data in a File - /// - public sealed class StoreLogData - { - private String filename = null; - private static volatile StoreLogData instance; - private static object syncObject = new Object(); - - /// - /// Private constructor; Ensures the access of the class only via "instance" - /// - private StoreLogData() - { - } - - /// - /// Returns the instance of the class (singleton) - /// - /// instance (Singleton) - public static StoreLogData Instance - { - get - { - if (instance == null) - { - lock (syncObject) - { - if (instance == null) - instance = new StoreLogData(); - } - } - - return instance; - } - } - - /// - /// Store message in Log-File - /// - /// Message to append to the Log-File - public void Store(String message) - { - if (this.filename == null) - return; - - using (System.IO.StreamWriter file = - new System.IO.StreamWriter(Filename, true)) - { - file.WriteLine(message); - } - } - - /// - /// Store message in Log-File including Timestamp - /// - /// Message to append to the Log-File - /// Timestamp to add to the same Row - public void Store(String message, DateTime timestamp) - { - try - { - using (System.IO.StreamWriter file = - new System.IO.StreamWriter(Filename, true)) - { - file.WriteLine(timestamp.ToString("dd.MM.yyyy H:mm:ss.ff ") + message); - } - } - catch (Exception e) - { - - } - } - - /// - /// Gets or Sets the Filename to Store Strings in a File - /// - public string Filename - { - get - { - return filename; - } - set - { - filename = value; - } - } - } -} diff --git a/README.md b/README.md index e5658f9..5fee2c8 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,27 @@ Supported Function Codes: Modbus TCP, Modbus UDP and Modbus RTU client/server library +Poll主机 +2023-6-27:修复NumberOfRetries无效错误 if (NumberOfRetries > countRetries) +2023-6-27:修复TCP连接断线无法触发ConnectedChanged的问题 +2020-8-15:增加响应延时属性ResposeDelay 事件ResposeDelayChanged +2020-8-11:修正Modbus主机模式下退出报不能为Null异常错误 详见:~ModbusClient() +2020-8-11:修正UDP连接connected属性一直为True的问题 +2020-8-2:规范化ReceiveDataChanged(Byte[] data) SendDataChanged(Byte[] data)回调 +2020-8-1:增加ModbusType 规范化编程 +2020-8-1:增加UDP模式发送回传(全模式支持发送、接收通信数据回传) +2020-7-31:修正Modbus主机模式下连接超时 详见:connectTimeout + +Client从机 +2023-6-29:删除numberOfClientsChanged、NumberOfConnectedClientsChanged事件 +2020-8-13:解决ModbusUDP无法二次启动问题 关闭未结束线程 listenerThread +2020-8-2:增加ReceiveDataChanged(Byte[] data) SendDataChanged(Byte[] data)回调 +2020-8-2:解决从机模式接收数据debug信息全部为00的问题 +2020-8-1:增加ModbusType 规范化编程 +2020-8-1:解决UDP从机模式关闭后不能打开的问题 +2020-7-30:解决ModbusRTU从机模式下数据接收错误的问题 详见:SerialHandler + + Copyright (c) 2018-2020 Rossmann-Engineering Permission is hereby granted, free of charge, to any person obtaining a copy of this software