From e37e1410a44fc58c12b241f06d4c0659cd254814 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:29:41 +0800 Subject: [PATCH 01/12] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主机 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 --- EasyModbus/ModbusPoll.cs | 3550 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3550 insertions(+) create mode 100644 EasyModbus/ModbusPoll.cs 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; + } + } + + } +} From db270b82f947de1f9032a8c9399befd6942d0301 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:30:26 +0800 Subject: [PATCH 02/12] Delete ModbusServer.cs --- EasyModbus/ModbusServer.cs | 2266 ------------------------------------ 1 file changed, 2266 deletions(-) delete mode 100644 EasyModbus/ModbusServer.cs 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 From 1e1be6563ea4652b936cc0d5eff5a3986f7112d3 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:31:31 +0800 Subject: [PATCH 03/12] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从机 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 --- EasyModbus/ModbusClient.cs | 5349 +++++++++++++++++------------------- 1 file changed, 2473 insertions(+), 2876 deletions(-) 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; + + } + } + + + } + } +} From 7fa00703b25a20d310bd0be037f68fd4935be631 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:35:58 +0800 Subject: [PATCH 04/12] Update EasyModbus_Net40.csproj --- EasyModbus/EasyModbus_Net40.csproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) 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 + From 872e2a13d3653cdbf62f029b472258bb89764f95 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:37:25 +0800 Subject: [PATCH 05/12] Delete ConsoleAppStd directory --- ConsoleAppStd/ConsoleAppStd.csproj | 12 ------------ ConsoleAppStd/Program.cs | 22 ---------------------- 2 files changed, 34 deletions(-) delete mode 100644 ConsoleAppStd/ConsoleAppStd.csproj delete mode 100644 ConsoleAppStd/Program.cs 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(); - } - } -} From 85ab91f72a2e01357f9679853108a32a284bed19 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:37:48 +0800 Subject: [PATCH 06/12] Delete EasyModbusAdvancedClient directory --- .../AddConnectionForm.Designer.cs | 88 -- EasyModbusAdvancedClient/AddConnectionForm.cs | 211 ---- .../AddConnectionForm.resx | 120 --- .../AddFunctionCodeForm.Designer.cs | 88 -- .../AddFunctionCodeForm.cs | 73 -- .../AddFunctionCodeForm.resx | 120 --- .../EasyModbusAdvancedClient.csproj | 152 --- EasyModbusAdvancedClient/EasyModbusManager.cs | 553 ---------- EasyModbusAdvancedClient/MainForm.Designer.cs | 756 -------------- EasyModbusAdvancedClient/MainForm.cs | 789 -------------- EasyModbusAdvancedClient/MainForm.resx | 984 ------------------ EasyModbusAdvancedClient/Program.cs | 46 - .../Properties/AssemblyInfo.cs | 31 - .../Properties/Resources.Designer.cs | 143 --- .../Properties/Resources.resx | 145 --- .../Resources/network-connect-2.ico | Bin 4286 -> 0 bytes .../Resources/network-connect.ico | Bin 4286 -> 0 bytes .../Resources/network-disconnect-2.ico | Bin 4286 -> 0 bytes .../Resources/process-stop-2.ico | Bin 4286 -> 0 bytes .../Resources/tab-close.ico | Bin 4286 -> 0 bytes .../Resources/tab-new.ico | Bin 4286 -> 0 bytes EasyModbusAdvancedClient/Resources/tab.ico | Bin 4286 -> 0 bytes .../Resources/view-refresh-2.ico | Bin 4286 -> 0 bytes EasyModbusAdvancedClient/app.config | 3 - 24 files changed, 4302 deletions(-) delete mode 100644 EasyModbusAdvancedClient/AddConnectionForm.Designer.cs delete mode 100644 EasyModbusAdvancedClient/AddConnectionForm.cs delete mode 100644 EasyModbusAdvancedClient/AddConnectionForm.resx delete mode 100644 EasyModbusAdvancedClient/AddFunctionCodeForm.Designer.cs delete mode 100644 EasyModbusAdvancedClient/AddFunctionCodeForm.cs delete mode 100644 EasyModbusAdvancedClient/AddFunctionCodeForm.resx delete mode 100644 EasyModbusAdvancedClient/EasyModbusAdvancedClient.csproj delete mode 100644 EasyModbusAdvancedClient/EasyModbusManager.cs delete mode 100644 EasyModbusAdvancedClient/MainForm.Designer.cs delete mode 100644 EasyModbusAdvancedClient/MainForm.cs delete mode 100644 EasyModbusAdvancedClient/MainForm.resx delete mode 100644 EasyModbusAdvancedClient/Program.cs delete mode 100644 EasyModbusAdvancedClient/Properties/AssemblyInfo.cs delete mode 100644 EasyModbusAdvancedClient/Properties/Resources.Designer.cs delete mode 100644 EasyModbusAdvancedClient/Properties/Resources.resx delete mode 100644 EasyModbusAdvancedClient/Resources/network-connect-2.ico delete mode 100644 EasyModbusAdvancedClient/Resources/network-connect.ico delete mode 100644 EasyModbusAdvancedClient/Resources/network-disconnect-2.ico delete mode 100644 EasyModbusAdvancedClient/Resources/process-stop-2.ico delete mode 100644 EasyModbusAdvancedClient/Resources/tab-close.ico delete mode 100644 EasyModbusAdvancedClient/Resources/tab-new.ico delete mode 100644 EasyModbusAdvancedClient/Resources/tab.ico delete mode 100644 EasyModbusAdvancedClient/Resources/view-refresh-2.ico delete mode 100644 EasyModbusAdvancedClient/app.config 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== - - - - - 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 - 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 1c6d3f65e85089c5143f9a4d0db8600d94266665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 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 TKAnsJVh8%s2AcXwzrOw(MZh{$ diff --git a/EasyModbusAdvancedClient/Resources/process-stop-2.ico b/EasyModbusAdvancedClient/Resources/process-stop-2.ico deleted file mode 100644 index 71a0f72215f0c99ce50dd309cbcbac7c24d86fea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 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 diff --git a/EasyModbusAdvancedClient/Resources/tab-new.ico b/EasyModbusAdvancedClient/Resources/tab-new.ico deleted file mode 100644 index 6f6c98ed0d1523c65ae287c559502e47b468004f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmc(jdr(y88OD#IjYMoxAd*R4N>Yu0f?JG;Qxh)}MI#e0)VuXU35|h;Bx0heHr`rm z)5Jz=Cx6AvGz}nfS=5QKL)0Py3(Mtj*HDphBBO>lOnaDz zbJ%nCdw$>hz3=;-f#b%}Pe=&oJu;u>xT$m%N(vz@CedB`O$Xf@c>v)4pK5Js@t0h# zpAFb;GN&MTWw+U6E>V<;PUiz9I2^J8yIt1b*Dveq?UD6#cgeb}7MZ29L)OvWCTlad z%34h(nW?#1)@(G&j0U|-r_p$&X{eXg@insgT0U4^t_mdoX!74f{tEK?-lv;FCI`T^FJbgba!{V$zNi!TCHyKm&pHnB@8$uVvvYIA_j>VBw~<= zK_UjJ&1{y;ttP3-XmmFj4U$o>muL;#6c1!(eD(MI{Jitbzq7NGc?(RP9UT(+3*&l~^J!h9`tby+Mfih+w_;Hs*ubeUUQosfh9W-*He&ShoN z{PVr*f5+cRbGW5#Xz;MH9!Io}o|fij55?2Vpl`g*K>i-`bW<*fWu+w|)du-zT~6$v$_#zr*3AzBWj) z1LYJb2Ob~?oQ~U~+`ywmH33_HKl*!nK{XFcXXg;*gIG~sF47q}=dF#z_s?{Q$k(-k{+zxO2+l@)r|f%OO0e^_4R=jC3$pj77Ek|fZYOEuNiw@5>DA9Nle`iy-}V)sXi z=7evqUcl^)FCr#uK76tQFunXGEU#UU(9{{YTv&igbp=W7rv5^Eh8+dU{3}#{*_7); z?!iGDG1;j8-7Kf?<z%ZZfa=;SdcOeeYq+8M7ISumBPKTnPh?F+c=-aX(riZf`=L-(7Y)kg^0g5W5pS=E zU4C@w(xu7K(b3P1eD_LEPrvFQPU=5sH=Dg2)H8|2bdSYg(4n%X6ea3wD57|67iwHEYR#Cax4K2jvTA{%NG&@W1KZ&?hB1rG(X!rK1D1 zZ-Mp>bTF1XJdC5Nt{ktY$0B-{9P%CEkSEN7JaHBx6GO4+{g<)wLM*tCo`j!r8eUe# z;rV?pAadWV@BFs;c5pi;W^kK)GA3=9oH;q(@8n2-MM_GEOLW3&vB28d$$A!vv2=J@ zsDGop<|gKBorTnI--GX`0hshzASQkJ41CW8!T&-Cre*#dK6|Gi;ENE%m2N;%WeSq2 zQ}9;JJ4mi1snT$~=3_*r%*!0H9u$ZW8OAxww1`_gi zgFE;nd_MQbQ_5fjU73mJz79ih&TK?}z5p?2mSACaES49pLww10Y*D>|Uzfd!U8TwR zed!-CB{tyfaDR54n3z~dXRzK)wczca-X2apl=TnR!)mo^gl~Hh376i2&sYAKeq%0{ z>Ep50vKtBQso2=?8!RtchsFO`iC0g@VddF%Sev~C8}oKzdtMUWRHotZ_2ZZ_?GU+3>OJzri0^)@dK)J+Cvmp@pUAae#EJe- zal&>QM|%E@?e)8{>YMf0eIXSm>(1aW)u-@D&1syhK7-TzXZWk?3>L0lbYJ`#2i3&f zsHmt4p0cyzPZPzhytx|7gh**T*gJQI3lmuMAimSP;A>_{{LRkHs~YH1W$rZO8F}`54|P zOGR=)D!AD3*<&&GXvW}nPRKggcoh4MN03~cjy=k~;9eb{Kbr53#WUQd30dz|96&mM z5PPnCfc^Ogz%BV7`mgcH+H-9m4ip{5(SM!5kxR$G&E$SJ7IPcT7{03~=j7=Nkgd%} zjz)=#hOZI0V(O*Qe0MCK@s0C6`Sj}n#Xd_W7W*umQ2fk_pyFxkrv2>^W7DnM$07Ew dg2y~;9QRYwQzUMH=h1lSf0(}#Dj{{!0ZmVf{N diff --git a/EasyModbusAdvancedClient/Resources/tab.ico b/EasyModbusAdvancedClient/Resources/tab.ico deleted file mode 100644 index 50b6170ff2a71d73ed6463f0638d4e2ecc13e94a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmeHLS#KLv81)r@03k#XXlNhPN|k6+PFu%yLK+qIg^5n?EY6&B&$ry`xLg81 z$Bwz2W9n6x>kXWZ0LOs$0X)TT9C$W(5RvO;A`y=Xt=SaKdR;X3Laioh)rzQWZHaQJ zB#MQCDCBY?m&u4sIwjJoD%3NL(lyNi;vkuZAsMzD&%ugE}M}M6Dg&t5@I4H zVlfFZkwU?s19&092MK<><5^yM9sFb9zYKmE{0_h`gI@;!o`43qQE$lgT2+Py85(40 zkfA|_1{oS;Xpo^nMqbFs2O05@5f6D|eN7H-tbc(Vc<=A~_b-D#27U$n4#2N~UjhHV zfCh#C4jL3_P@qA91_c@vXi%U*fd&N{6yyUCQ6iy`f}B(~gMsMXJ9oaBpP%~){8TQN zJK(n%#bU7oehd8n3a#0)puvI$3mPnFu%N+$1`8UjOge3)Q>qn@#X87KD;9}Zh(QN_ z(A4Cwzs$|e-e&%MKF{15BcIDz;Mc%^AfSFVXwaZRg9Z&6G-%MELCa;c8tOwsO5vK9mJH4h5(3KMx_)~Zz#eab|iGE0Sm2@gzoVEVjX6FovlK4{BJOFDGW z^wd-SU?AYkA6^=vP^g2?+RqET+lF^`A|AIf2OA#S;ZVp9ZEo7$m6c9POHLnPeO0Dc>s9pr+s_-MgEZGeCJ z-uw`L)|<^_y2#x_0lsyiqYE8fc+rhVqg}t>*Tww~YQk7rTr@C}`_|3f{H>ObzP1hT z2suT_fgxy--s%ClLHhwUL0B`WR;dtbo(lPV7x`eUEH4`v$$k6QE`GdA2iUtIy!~3h zuN^=`vq@N29S!Kev{fomxmYwjD=S8+P$ake_96NEweb1gdRp)Zo)Th8s0+f{X?i^# z10&72-7koLh@OGiM8YBXP$jJ2T#E)qnw^>1hkvj5@67jrIl%eB{-FQ$asmB;`w!>E z-0aM~-{+igmD14$M*q#{(SHf_B`bCdI;Wk&|k1-H0Zbaxj#^U zw~*`I&h~a4n(C`VvoBA);W!P^;^;^?`GbD54gdF@ zKl^dv!i7IEqG#0!wLlHjsnf%&Rl;`=?jKY|ALCwDDVKUZb(hZkj&G0SmvKH@E|+xp ze|gaJ!RwKckZ93>*6)2L{HW&~+Pi>_ErZ57cwJR;y*k$H%`N3w-F96@8?rvc2Kk~Z=`ToCtx!=Fx|Ip(q|J&e@N8ROm8#p=$ L3-`8xe!_nM7H3-I diff --git a/EasyModbusAdvancedClient/Resources/view-refresh-2.ico b/EasyModbusAdvancedClient/Resources/view-refresh-2.ico deleted file mode 100644 index 2925a539597a790a8cf1b615f2f176dcee0bd782..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmcJRd0dl68pq!x2E!2ofnZ1k!WF`mP!b><666$7w1A@0dROf#M@2wHMIm5S4v$p< zTR;Ip5D!+VMLgJgY>TZ`sw)~lEU-UIB8{_%X zEFW;!taP zLh@M>4;cKkaHX3drPh+{Br?FUTr7_RrYRq#uPuQ7+bn_>c8QjNi zt34r^D{Cg(1qQ|7xbb;HE6i3n4NV_cyMft!QjSEYn+qaUP)eIe^mz^ls_?jQNW z^@jh!21Y^E%h4ocOa4rd9dY%WP4h}}On1Zp>2#j?`prF3z@+j?h$xDLN-I3YWDDk5D=^+S2ff(@v>i;)mX888n+|RoAC_;99qEsr74Mbd zrHR=Th0ua9gp?3>4Vm{t#C<#fvcD_gbuj=QSIIiu^n>#q1w`Na!v3BQg!jEM=Dr8G zUyH%%6T#$~0L+i9!8mCFdaEgD?-+qrNc@Y5Kb82G+l}z+=Yzj6ceW_a^@({V7o$t8 z!QLl;@I7}(&iO;p6M@)oXCmd%QY_MBArl42M+wx}ib8Bb9yTJC{LXojj)VvE5q)<$ zf^Nh@ay|gOHYd<3j6khsfcq97+*S4?{Okos$MDn7+A$WFFXgPVdCI6^!=g^heyX}v8Gu=M)H~0D^h$HI><-BrrJV$;loFl(Z_&ku~(-X*%URH2iyL_0= zwSGzB5>Ev5#K5f022>Tvzr+^YQqk}E<$|0GbEwQav&@SzSyp{yi|alwZN!~;O#N{# zGOz|7&Aw+1_w66mr9H|3aXER8^i9)QopjJrdq-)xJBfd%<4MDQ?D>BS7p(edHI@BU zme~ef*2KN|OUjA126=mkZXw=6IjYEg5b|6<*T1!Jv_th#ef;2m21#8?JRVHFH|I0K zdAA;_iP>XSEx5_8c6@h)f8OB)LEgpPRL-4ktPPrN;kDSdq64M8x$48J)2e^Bp#$TN zL_XKgk?!rvYJLQ|W91R)g+)TgVy7E31{Uve{8(B`9Wbi3+AD0ds&~p6;h){|2Jv@N zIel$(^^-PvCE6CXqmwBt-Q#v4EHtHk9{lUWE*SPRteeZ~PIul07Vd}E*l+WPqD{{2 zbB0ovi?1j$se?wDR`tS_HchV64g0ZE>I(#`y8Ec?8$HzepL#@F(35-!x9Rp3!|xp7 zpM)kjZIz6eH^VqAue#F}7lEt}Ancv*!5g36H&6Sf%JZ5sj`$~W>xEPJ&2CD=e(dCT zs|2|pg37!;M6JC)#4gedMefsr=2&&a@Y+ABGd*fg=bh9cp$Tx^sfBat4e&zOoR{77 zwwnbuR7=xX-qt-V2AD}XNK&|=`^xOgX*E|K&Y1i;xrLrEgsJtgEDiB;~22|3{XOL;f`)#7g^`+z>9jF}QUiKOJ&p8e%z6x~J8nPF1VPwCg{h9NBkCxFZYog0<;FWc~@Giau_maDC z+4dbAsvf~^j}Ef^Km>{ZD(OA*eISJ}gJd(6-02Yq0Uz>@&fg7;D%XNiKO9~|D*ZC3 z1*bqw+Yc(X0<_pl*i6_A=2(3uzkTnv8lPITpza$a?ED7tyS_$T^>>JAc!$ zAdGn8jsr<2fMminvcD%2zlw}WO2+26M+4i+pJB7*0jxKC4U4?b!A|dn>4FnrB_9AY zVIM{%wtyG+R~Wm!+G^o5iCm-r&&#(|Po9IXwFKd>%crh)0j!#G}WQ+R$Um_<9%< zO8JbK&3s1m+k8f3A)g9a=`vQS?p)b?7b}|XBBS9;EN}i77L|2_?X6$2U)+Kc$$#Io zpPhSAN0xnB-PVr#*l~IQyFM5~anl#DRLnTZsI&So)u^01Sn%~rJN&VqV4{@ds zXgqrtB1vQ&W4;ajMdkOrIBdb(`dbgQIQ{9DaFd7aqbMHZd3|1FJ7-LC!`bf35PQnE zQ#8|;HqZZW%uW(%s@zZi6#V^tKH~fXa^@1DoWKEe1P$S5ied~9ZvTqDtUpKEhS6~b u8MiqPN8g?@kbfqfkUyXzIGmv<4q-Hb@hkc=i8$auP!aM8MD~#I6#oGXliyeX 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 @@ - - - From 471aa77753b977c9bf1e23bf1d155de41e90d4be Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:38:01 +0800 Subject: [PATCH 07/12] Delete EasyModbusClientExample directory --- .../EasyModbusClientExample.csproj | 134 ---- EasyModbusClientExample/MainForm.Designer.cs | 663 ------------------ EasyModbusClientExample/MainForm.cs | 512 -------------- EasyModbusClientExample/MainForm.resx | 451 ------------ EasyModbusClientExample/Program.cs | 46 -- .../Properties/AssemblyInfo.cs | 31 - .../Properties/Resources.Designer.cs | 143 ---- .../Properties/Resources.resx | 145 ---- .../Resources/PLCLoggerCompact.jpg | Bin 2612 -> 0 bytes EasyModbusClientExample/Resources/arrow_1.png | Bin 1248 -> 0 bytes EasyModbusClientExample/Resources/arrow_2.png | Bin 1245 -> 0 bytes .../Resources/arrow_left.png | Bin 1383 -> 0 bytes .../Resources/circle_delete.png | Bin 2187 -> 0 bytes .../Resources/circle_delete1.png | Bin 1532 -> 0 bytes .../Resources/circle_minus.png | Bin 1503 -> 0 bytes EasyModbusClientExample/Resources/small.png | Bin 8359 -> 0 bytes EasyModbusClientExample/app.config | 6 - 17 files changed, 2131 deletions(-) delete mode 100644 EasyModbusClientExample/EasyModbusClientExample.csproj delete mode 100644 EasyModbusClientExample/MainForm.Designer.cs delete mode 100644 EasyModbusClientExample/MainForm.cs delete mode 100644 EasyModbusClientExample/MainForm.resx delete mode 100644 EasyModbusClientExample/Program.cs delete mode 100644 EasyModbusClientExample/Properties/AssemblyInfo.cs delete mode 100644 EasyModbusClientExample/Properties/Resources.Designer.cs delete mode 100644 EasyModbusClientExample/Properties/Resources.resx delete mode 100644 EasyModbusClientExample/Resources/PLCLoggerCompact.jpg delete mode 100644 EasyModbusClientExample/Resources/arrow_1.png delete mode 100644 EasyModbusClientExample/Resources/arrow_2.png delete mode 100644 EasyModbusClientExample/Resources/arrow_left.png delete mode 100644 EasyModbusClientExample/Resources/circle_delete.png delete mode 100644 EasyModbusClientExample/Resources/circle_delete1.png delete mode 100644 EasyModbusClientExample/Resources/circle_minus.png delete mode 100644 EasyModbusClientExample/Resources/small.png delete mode 100644 EasyModbusClientExample/app.config 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 48d8d884fb80eea3ae142a5f6ef32afdf33ba900..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2612 zcmbVN2~<;88onVwLO>KXLZKyq>_Sr&6~vm#s%13d7KM=vDk369(E_sMRY0i=rY82VibM#Aia;X*CX9q622>Iai)kRqyYtfabk3ROoSFIGz3;qp-+%w}fB*O0 z|H2n=7|i)HWL*fr;c(zD*aP4o2n0qroMHTKcoV$AOpT54CInLg!7zzt=4M19iAW%j zW|2td7MKytEN9QMurz!df*7_Nc45PUNFW+K{x^dUfE5vZ0lvWFoPd!P4sV5nZGZv* z&IHTWknrz@Gr}92m|`iB%rS@BIavC5yb+eHiLo)}or(Pi##SbC9T%@LofjTWa5^-9 z$+2@K#DxJ>E#yrCmGjbFNm*v31=cnn*}Ay8xqEo}EL*<9*KcKDP;f}-+I3%U-m-NY zWBZPX-Fss8#_o&TfB4AP$tkHv)3S4ppUD08R&X|GX`8Zfd38F zAISa*mlcM~2;;z*V8DelO2H=H%GktlvFY43;e_Zz^PH9(BhC*vS5nntws7et6?s>Z zfV9BbN8&PWfc7i0{|;Ez|Ap)iVE@1+0v322MjqY@(16xeEmI#-x#{NBOJ*zWv_TmT z0(7yaUiN7r=k49wWtFLi>ErgCPt>KQ%dbY~h{=)Z?g35VfmU1d<~q#Rbw#a*V3raB zV;KaT&s9CBZLtM1E}|tSPBRv&KZoF_6^ommsj1Px1%c{fZ)XBS_odHX?CNtk|DS( zhu|PZ|ClkhEVI~Rgj^*|ShW>7#khY*w4SvV-8;_DS@OcZ4eN7dy0kD($IEx4i-yCP*rq5Kx(3vrPc)X>)c8r_tjMPFL?Iy^wF-$ zxKUB3{7zDf!;vHT=%2rfSBO-zHH)lu*E-b&5L9oKvh_YYHxhd6&GgwciIk!W6btDs zOjSMvtrUIXFq=4r96+C+;9KeXRKHvcdBfWwF`0fjGHN0+&4=Bm3GA?3F3D(&*|A`S zaO3*ULZP6b`sL6Oxp(G)j7yjz?qRWZLcp&>Bz_Q_8b#;PHS1TmK=4_j;(e9AP)VB_ z+No_8pxw(;dMG;t%tGEBf)Xd|vXgb>RVs7|(y_3x^{g2ihurNAXMMxJaweTBQI%ue zbqa!r~0lkknXEyVUX zvW;$WSWw-)euX~Z8qWsP$?#pVo=mlcV7MCsUHp_CO2KPaB7z_czGW#!Zr==nFr0eN zUoGDLXmJrUwlgt4pz>&AW3ycgvp_V%d6R1HExYZch9FXMhEGsTCn$gF|=4b(VO-^2q*U~eVYsqS|X6d)?oAUR+ zuodKNPPn^yol8YRgV4D)L6JG)#((F*55Ka|szB;Ubo2Of%YK*n`GW}$AG=f}2C)zQ z2dW9WxhZIPjMfJNp{I(6UiOX`kBzXuBk8`=U+2A&W@JLJ+nxi#jU|k+O!74M$Yg(@X*_S4JWZpm)kBT@dnP=Q_MebqZQZXtPSZeBl<^=H>+6|2;XNP zbMlu82*fWS(45knLXc~$`viiLLMaoq@It2NHcNi3-dUt2bd?n*s8)^RjZ|%ih;gbm zlfoEqROvp`utY;rdF=Ti>DPOA+&mtX?tR_(gqusM!+F|XmCSFPHpcz5?1%o2{@c>B zj{M-8jkgQ$FPhw$T<@U`#iwRV3j#k5n(TJx=53bCN3wEj6Oa5ETq3^$Eb+r4@Px~crW|FV;axJ_Y z_xmMHh!O(2#ZO;xCRg+4$ztb^_{4s5>r(f@vX4T-6C%Rn%G_>tMUD0`RqMpl!G(%m z2=-L8LNK$hmWyyt({>dPW)DN4II4BhQ8mHiDbmfkbT90JPOnhI3lCDX&R#ZU{>aC?= z=a&DBHtp2B6;tp1RGy)~W>uhFX%v2s=0FeDnjau9hFr7Tm?DZQ|BY?w5AukYgVU>- zgOZ1=zI(~Cydu%zb2GFYKQ-Q2=5=q`)3@m>=a+kI*mkk9^243Y7p7giSG8U&myB*8 zDLKo4rSf7^*$EoWEXvYY5HT~Ybwp{L+k diff --git a/EasyModbusClientExample/Resources/arrow_1.png b/EasyModbusClientExample/Resources/arrow_1.png deleted file mode 100644 index 63aeb17628787ff341f3b53e8857e341a77b8ec7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1248 zcmbVLU2NM_6n49UvO-G`l{OF*&(kD?7Tedc-Pj~;65ClbElroEtP&EcW8XGb>Yv&! zaVr5`)oKC_X}lD)O_~rBTL_tdtgstrXh2hdq3FICphd1vqygUi2;|MxC&ZGR zYx+XB6jAkkN2I8Fy-wESr0q^pKoA6qW+;Yf} zF|o4+M!CDQqfimC5sR*YilR=*wl-rz%g@Ux0=7Ir6PT_5n=r^` zSV2L=C8-&CAIK@Fg)&)%cQ~1(fsJLF+R{jGvlJ+ z=zcN(1%|bC=jBW}xO(He{hbTxo+b6!`zL-l812Yh?qB%0YwN+{uj5DCmX2Kc`sGXB z?R$RS|J!q?4}0hTTHCh#W=CT%(el`rqe~BGuSQS2`p&=`CG7MzwtwjL`O6R+#ILpA z=zVPs8()q5ezLgZzF!Vx_g?rYA5CLBw*J`N9>M3ajpfL^v!$&gn!c0{9{uB!3RO}dK}~LJ>7mUmh34XKc+5@hO)deB%jTWFZ=`Cah7lZ diff --git a/EasyModbusClientExample/Resources/arrow_2.png b/EasyModbusClientExample/Resources/arrow_2.png deleted file mode 100644 index 5dd7b6047f58151fe2c32471075056f47dcd429f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1245 zcmbVMZD`zd7*E%29MyT9ADmjzG@}JyF3CT4$z9@|+g)DVZA(4wZg}`XO_P6nv6tkU zq+WX4pw3zlrWN45o*Td_<5MduL3nvKN zG&01qtV*kO5mwDzO&6A$LuI`=rt=1|<0(8H2*`j1eGLz+n(YZehFGyHpmQju2z&+N zk7bBeQWdp;i;fF%mZW1k%>kTCkRUY8EOYbOe&j0&_m1xT8*tT3(>wC5M$KQz`wd*#VGq>9jUCR`oW zV`O_r8RhQIjzS<}BRu1ps3=-Za`Xuc+J0Wj5a*DrIakkbaeB!=WDhOJAO^%S5kN; zC-JE}>I$L@HQ#Z|j#KM&K%wgRj#qW+xL9IIfUBBr+My&Y&}zIAbj_Ecp}3BPuVh#- z*I|&$CU_YU7sYnuNubE6g|a!BWtli2+PcR7$r^>oP+@!gt6e%G)Pv!1t@+VqZG51O zX2wOs(a)Xx6vMji%1haDuz2IB+H;z|e^Y5&S1V@h`{}Fwkwe$F_H2q?;Rbt?XK!g= z4muBit`1x|+`qhaF=)Nv-lL==JFyMDQ`pAd;+|TyuNnPCT=;G8Ao=ZVv-CE7pcfy| zc26Ciww0;r=}1G)&D~pD{PC|1mly9FIQ2etBmUXGnc0JnooPLP@{_9vg_3c#u|G2Z z%Iv$3jDGjR7nSIN50^^c9J~9^ceD>)TAmv}-VBc1x^({Z?Df}<_g&b%B&!oAyQAr) z|1P)tel~u+ys+)&*H0d4&3}B(x?PyL*ne!f`{JW#PDD=y?=dy(hu`PAFTFMM$L6!I jVjFR+D^j?yXQ~T(^P$I|@K9* diff --git a/EasyModbusClientExample/Resources/arrow_left.png b/EasyModbusClientExample/Resources/arrow_left.png deleted file mode 100644 index 700d60514e9792347a9c72101263cb731e39097f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1383 zcmbVLZA=?w9Di0&nuSf63>4kG9BQ&bdoS%>dzW^j?X^&$NJ`Nzk+Gva=t=GcICMHR4|4Q=sSvvJXDV-Sa&E z=l}ct-;Y;UmF?JGxE%nn!&%O`;a-~h)DOe|fY`DGx5pK`SE-R2l^8Dzz~Yx01jHHQ zn*_JO``cTt3MK$D0;0#OcwLpOPYP-Il#VtYia;~~ri1Ya?`swmq(NvB!)A2l@@FU_ z`pxKzlnZx7Y(hXR?~sL>jw+9@quIy!(SrvNQ=EkaAwl7hcqkZ-vT-xI#>>KUN{pe% znu^kFM%SJ4x~dVIBnt?o#Wg;hCJXG#zfCvc1)G2EabaF#N#IDu>|6k3!0 zjjWqr|ThvA}-e^aX7k>D3~%V&POmpi({csDy}u{sNxp>bz@8IsHZ(5 zU~VBQwaPwNkH(@j80PN5hEj^q8}@lwghkvmox{!$gk5Llbex^02%Mvh4hv1DvCeQ* z;ln;5ZC8YLNs`plIIVvmmbJ+OuSl{-l7i_Ds18Vq6b(ob#8yLT3B<+w#BfTID$sho zoFI#Bg5M!aA!IGXthj{-R*Rmo+bx96wh_63aM)oBS*&)7B6S41f%X5NtYOd@EY%+W zX_vGJ_F(F`+5GUbIX*%d&WsF)qcs0`Edbk2J2{IdzIgjAQ88JXbL``eCohivmUZaR zowqYB#+<>+&kYr1e%^f7&~?mP|4d8%m~rx4i>^Pp^wq=%yS^C57W~P!IXt`Wdg~49 z@HPZwc7hzBDg}X0^3N7j?7O!xG5W&L`3s$gM|NGwt9$*eXP+Lu7`)FsvT|Z@WV%1Rc(v@C1;g|b_g0i92(DYY51TppJzuMS|L9Df+FT53)wkZc6;x+`^jC?xM?3ec zgWz53C4MFMTF$Q(;n~soqLJcL3;9g$@GFt)i$!{R&$oTw^_{kN_e>wK{Oy^q)tHuc j|L!$y=1mPA`(xh(SbcM+S!w*R7{KMUS8;>ZBVGRh6CC1h diff --git a/EasyModbusClientExample/Resources/circle_delete.png b/EasyModbusClientExample/Resources/circle_delete.png deleted file mode 100644 index 06b0e9bbb4b9ee0a13154b4f7c5f88ac0b6728ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2187 zcmbVOX;c&E8jiAqph3ifT#Shx`Dzvqm`&u62l zv9&P@g)-%CV)2pPQ~Mg~BWt-hz7N@~lgWa z+)*faE~=Db z$dfanXz`|G7z#-C5eSoGg)|Y?V*|!rMMo4!ASH-VN#djmx{87Qq?eAIwPFGm^9iDi zWne!$6~yzyFl8`=A>)b8LLvpgP+akVE0N|(bHb2_0FeNY2t+q$fJi61(TMY9-nNeU6s}!Qw~#b5Ej+sl>4W_tll=3L}%0EdmVke4@` zOeVPi*g3A~|H&EwafYC6kN;_xc@ffs+T)kzM=oE+2a+N)10%yxU?I7WLg`j>SzZEF zckhmmQ9JxCYIms*nR~CX%jR>8kfrt6O5)5*``OZL^VSExrHA;Nt%T|R^vLu}57T+) z16t4B;r>Js#*vEdJulgsC_UpQo*Auv_uK4~nm6N_zYu8e_IBK2^pEagwAH-Pv0s4O z57s$;D5%wc|G{D$-9Oo-Q@3HjbYS^QZz~-E>gxX7Rf+yxLEYSU3tIOxOiI`fZU8f# zEO(PCooMRnK8^m-Jl?54O+Ej>P59i6H|v88FXdn+eBz1@-pkGZroY-uRak9STfA}K z5!(-j<3{5K6;Y_|6AtYf3jlt0Y{s<8NcHMArI{`Tv-3A82?B zJ972kpOzoqR!8$wINc1~kdm~$M784B7B6h>@k2xQ@b6jIR$o`A6s>d4%A_{aVSX;J z<&5vr=|o)I(#gJGejcq2SO0U{BaNWFVdYS2@wtblc5CR3_WrEQy|I~>`gSjWi+gHh znsHnGdXwxW}hh7GCrl%R0~(iVcoQeQ}Zml5>cBbji(>Rnv}Rq5g{= zV>di0BfLUa*L;6hGiG4fas=eD%UMy+y%*me8g=3J6~-R&H1AqW&Z1==RhaF`3z{vz z{4YN{eaq%6a;HG_^nskI#hMo*dTB|#n}!r+*-YghQx6E%P8HQs7kynp%ge|jwRadk zE?%>iv0SarM(@mA%oYIfXw=A)vb1+LmJTBvIWK?J3CEh#>%VoZq7GMin`o--Zy!r5 zOK42gU4Gs@`-1c0q3WGWpAGlk?z~l&#>|gN=o+$uHP(+;)T*4Sq7@%`U51pFfXt&^ zdiC7*quo{5m7Kh0^N-&*nZK<#d)qoK!){4K(881oyMb;aeSII|_#<65C?|QnuKa2Q?>cKgw7qu7q)I*>$LW8jBRsI88)zl zvyAy4%Uj^_`oI-QwW+L@An`zz3{TGv2H53jOO z_2aa`;KkDNqc4ME?_90FTiKYH%FqMPD1s>)hlA4Ff4>w{T-ju@%QOFcjf2zEDe8&f z`s7}9Q?j=)A7BdbAZD$2!{(*wdQro^W#V8=AOf(eZ+R``iMm zc`ZAm2G@oOUmwik(i;zm+OHgA#yy%4ByO5nU9^POG_(=w%KHv?tz6<9cBIsVm32pb z@=k~_XI*!Ai|vVF2YS9^2Y3VC9{kWjIeK*>WOrTowFNsv*IPf1`DvP((I(GGE_gn& zV*KgjEp-NQ^|p^@I|>plZ!FvAQEK(;dz{M^RK{*x$uB#)4jWc_UH5#KBD(95R<&QO0(3ZxsBD@2QlVKnn_oJjF%n*~O_V4Pw sIGE915Rpx-tL@~ diff --git a/EasyModbusClientExample/Resources/circle_delete1.png b/EasyModbusClientExample/Resources/circle_delete1.png deleted file mode 100644 index fa28fa576398eefcc8e6b774d1dea4f2291d9567..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1532 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%o&*>5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8KW+g=7RhMR$W{Yl!|Z$R@KEJl?AE#L8-<0 zrA5iW_()TRX$FQJev3c~fv&OgFUkZ)N@9*nesXDUYF>$_i>(q+MlU5Z#md>m$;{Ni z+04Mw$iU3P(9pu!($vDu#Le8u(8R*j&=h6{HoY$9ZkDFzZf+(jluEv%wCQeR{ zW~P>oE{1MK<|Z(`o_WP3iFwJXFncqB_Coc#;?-;AT$Gwvl3x^(pPvIu0Rb8LCHch} z`2`Bj!KQkK3ciWSnRy@)Py|8z>ylcOS(cjOR+OKs01jcROe`)iFtGrpA9E7}bEwaa zj2vAJ49(1dq2UG$0wt*46mmjMALtl;Q1U=ZE-)cr8U!)ni66*;XP?wOV4f)gW)6mg zcpe4@CM{1F$B>F!N5c2|F*yp{+w0QgwpewF+lyY_MhB&hSMG@`{1CY`v!HCtqWp!X z)5;2_Zrr50pp%X7k*US>GqX35SI+(yx`ud?R+M1*_OVCHVe3aY%(|_cxu;*(_MTF&b^1kLn@dwn2I`- z=IuOj_-UJ2{bLS;G%h(t-fsSk1w2;`-R^dNoF}kQ^#PMYa7)0VHKJvHI_e|2! zKYT0FCL9U9vh+(;#%uANEhpJST*^Wm=X&j5?Y*nPV2jJQD@wnZ<+|*=E#y9HAK(7eAlzp>5mIDKa9$ zMv>23dJ7xPME*}vk2v?h($z9CDP}?M{IsV_D$cK-Qa&+7m?=|$DN~y1vdR=OPmSD3 z1#{D1sMrL`#(qklu}#2|lTS)~(HgIf$&p>Pp$F97`~L;9 z+as;@{y%ppk~N)F+453XSzT*IcV9~MGUt~{%?q!X%X&>d_Gwn@M=5WM#~bJTC znqL^rrJcsOp;6;Oq5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8KW+g=7RhMR$W{Yl!|Z$R@KEJl?AE#L8-<0 zrA5iW_()TRX$FQJev3c~fv&OgFUkZ)N@9*nesXDUYF>$_i>(q+MlU5Z#md>m$;{Ni z+04Mw$iU3P(9pu!($vDu#Le8u(8R*j&=h6{HoY$9ZkDFzZssONCZ>jluEv%wCQeR{ zW~P>oE{1MK<|Z(`o_WP3iFwJXFncqB_CocV;ni#9T$Gwvl3x^(pPvIu0Rb8LCHch} z`2`Bj!KQkK3ciWSnRy@)Py|8z>ylcOS(cjOR+OKs01jcROe`)iFtGrpA9E7}bEwaa zj2vAJ49(1dq2UG$0wt*46mmjMALtl;Q1U=ZE-)cr8U!)ni66*;XP?wOV4f)gW)9<9 zo*Nh#n0P&1978H@9hrXKo5@k+c=~U}Z{1ARFAOiOb`cL05z=>*-E~u5;oJHhf4RT0 zmvr%!n!S4Dd)?d9^|%X{R?O1Y727|s#jQ6jFS%a(fpPBKpZjjky!riJ#-Y8s%+(HZ zH<-*CLTkS9*)aMpV2fe0eK_%GqZU`)?j`NXk0x92F^fJ3K4^GcZuR16lX97O*$?o#k{IHi%b4k_53?a=ci&Sqey1i)2d&j`6 zUAkWGQ=dw*K9?+e5HtO0i7HR~lcMhJs@6$vjg=~0xuS0lAD4U_bNNt(!CKBu3r*i$ z?TKRQ4hue5D8K)6%k1VwMYi|TuYWeJ`F3pGbMd_O&+VCb7>pY@RhUih9RwA*p00i_ I>zopr018_jGynhq diff --git a/EasyModbusClientExample/Resources/small.png b/EasyModbusClientExample/Resources/small.png deleted file mode 100644 index 48cf80f374d3cc801c7a15b9344f7015bf0759e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8359 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 V_dwA5Z@B - - - - - From 5da24cd0582b098c94d65465459de078c3ad253e Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:38:16 +0800 Subject: [PATCH 08/12] Delete EasyModbusServerSimulator directory --- ...syModbusServerSimulator.OpenCover.Settings | 1 - .../EasyModbusServerSimulator.csproj | 171 ---- ...asyModbusServerSimulator.csproj.sdsettings | 2 - EasyModbusServerSimulator/Info.Designer.cs | 119 --- EasyModbusServerSimulator/Info.cs | 27 - EasyModbusServerSimulator/Info.resx | 400 --------- .../MainForm.Designer.cs | 788 ------------------ EasyModbusServerSimulator/MainForm.cs | 668 --------------- EasyModbusServerSimulator/MainForm.resx | 503 ----------- .../PLCLoggerCompact.ico | Bin 16446 -> 0 bytes EasyModbusServerSimulator/Program.cs | 47 -- .../Properties/AssemblyInfo.cs | 27 - .../Properties/Resources.Designer.cs | 133 --- .../Properties/Resources.resx | 707 ---------------- .../PropertyForm.Designer.cs | 94 --- EasyModbusServerSimulator/PropertyForm.cs | 50 -- EasyModbusServerSimulator/PropertyForm.resx | 434 ---------- .../Resources/PLCLoggerCompact.jpg | Bin 2612 -> 0 bytes .../Resources/button2.Image.png | Bin 742 -> 0 bytes .../Resources/configure-2.png | Bin 2951 -> 0 bytes .../Resources/pictureBox1.Image.png | Bin 7223 -> 0 bytes EasyModbusServerSimulator/Resources/red.png | Bin 2857 -> 0 bytes EasyModbusServerSimulator/Resources/small.png | Bin 8359 -> 0 bytes EasyModbusServerSimulator/Settings.cs | 72 -- EasyModbusServerSimulator/app.config | 3 - .../oie_ITkzMZD7tnyn.ico | Bin 19550 -> 0 bytes 26 files changed, 4246 deletions(-) delete mode 100644 EasyModbusServerSimulator/EasyModbusServerSimulator.OpenCover.Settings delete mode 100644 EasyModbusServerSimulator/EasyModbusServerSimulator.csproj delete mode 100644 EasyModbusServerSimulator/EasyModbusServerSimulator.csproj.sdsettings delete mode 100644 EasyModbusServerSimulator/Info.Designer.cs delete mode 100644 EasyModbusServerSimulator/Info.cs delete mode 100644 EasyModbusServerSimulator/Info.resx delete mode 100644 EasyModbusServerSimulator/MainForm.Designer.cs delete mode 100644 EasyModbusServerSimulator/MainForm.cs delete mode 100644 EasyModbusServerSimulator/MainForm.resx delete mode 100644 EasyModbusServerSimulator/PLCLoggerCompact.ico delete mode 100644 EasyModbusServerSimulator/Program.cs delete mode 100644 EasyModbusServerSimulator/Properties/AssemblyInfo.cs delete mode 100644 EasyModbusServerSimulator/Properties/Resources.Designer.cs delete mode 100644 EasyModbusServerSimulator/Properties/Resources.resx delete mode 100644 EasyModbusServerSimulator/PropertyForm.Designer.cs delete mode 100644 EasyModbusServerSimulator/PropertyForm.cs delete mode 100644 EasyModbusServerSimulator/PropertyForm.resx delete mode 100644 EasyModbusServerSimulator/Resources/PLCLoggerCompact.jpg delete mode 100644 EasyModbusServerSimulator/Resources/button2.Image.png delete mode 100644 EasyModbusServerSimulator/Resources/configure-2.png delete mode 100644 EasyModbusServerSimulator/Resources/pictureBox1.Image.png delete mode 100644 EasyModbusServerSimulator/Resources/red.png delete mode 100644 EasyModbusServerSimulator/Resources/small.png delete mode 100644 EasyModbusServerSimulator/Settings.cs delete mode 100644 EasyModbusServerSimulator/app.config delete mode 100644 EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico 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 cb476486e3701e3c7bd80ffb81665f044dd8a8d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16446 zcmeHO+i}A%3{#ircR$lDGFtz-L$~QB+QbD?^Df8OebACD*^rNMs93Zh5Oi`mrSyd3 zdQEtJNf(@-Q%V;Y-ljJg`~T41aZQFz2RC9Q*8BDe=L7aSciQ>>nxniYHew}aHm(Kz zvo&J2oIf((YrGP3hEeZBHB5MlngeRJ&UN?gMzM38LzdzDK6gofZbAISF8uvb{Ns$o zzv^E!2V7!F|Ehng|4tOWyHV|PoWn-n_qj{@bBQBr4vp}Of91au#fjV@^A@7{SW`WxDcyu0&k4IlK;XFSzv7r94DCV me?0sCS2E`JKaa!W|7Ys=KU)Ob3vAECqn$H=n%;@^*1iCv(WdhN 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 - CAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy - 0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWG - h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz - 9PX29/j5+v/aAAwDAQACEQMRAD8A/ns0jw0nifxL4xjmuPFFzdJ4o03TNNstL8V+LdOhSOTwb4QuUtbP - TdH1mztEaa9vZHISMM8khJyTXLOpClB1JtKCV23skurHhsNiMbiaeDwkJVcXVnGEIRTlKc5PljGKWrlJ - tJJatux9Cap8Ffgn8KURfjb45+IVx4leDzn+G/wz+Ifiu98SaYJUgeyXxH4g1TW7rw9oU1ys43Q7biaM - YypPy18pWz/G4x8uQ06cnGVnKqpKHycWvPvbZ2P66rfR68PvDbK6GL8euI6uA4ixKi4ZTltOniMbHmXw - V5zbp0KnvQ0lFq0rrm1t5VrFp8EIBKyeFv2jvDNrIzQ2ep678Utf1i3E8jBbZprWCDw488Bz83kys5HI - AAqcPmmeztzTy2pJauNNyb5V2bnv6o+ez7g3wIwWElVWE4+yvCzTjTxuNjgauG5/szlRo4WjUnTfanWc - ndct+tG5+HmgRQWd7a61r+p6fqEbSWl7p/xH8eyxNsK+ZBPG/iKOe1vIN6+ZFIoZSe45r6HA4+GNjK0X - CrB2lFrVX212afdH4fxfwVmnB9ag8XOhiMtxdN1MPiKMuanVgrX0kozp1IcyVWlUhGdOTs1s35/tm/4Q - T7H/AGhrW3/hY/8AYv2v+3da/tf+zP8AhdP9j/ZP7c+3/wBtbP7K/wBHz9o3eR8mdvFd3X5fofIdT0zw - B46uPh1rXxR8TaZCjeIoNZitfDF7LGsqaLrV94G8A20OtxxtkSXmmW0ksluMHEwVv4cHw8+wtTHYenhF - /usql6tm1JwinJxVrbtK+q0T7n7F4L8WYLgLPsXxjywqcR4TAzhl0ZUo1lDGYhqjDFck04yeFjKVWmrX - dX2bTVrn2f8ABf4M2tnbwalrMbat471SL+0NS1XVnGoXlvdXn7+Wzinm3kXCs/7+cfPPMXbdtKqv4Vxj - xi8NFqi/Z5NCTjGEfdXL/M0t7+e3rc/3m+jb9Grhrwg4awviDx5Qhm3jNmdJYjG47FfvqlCpWUZyo0Of - mUHFv97WV61SblH2nsY06cPfNR+HeoyW80F7aRXNowYzQ3UCy27qAQTJHKrRsMeor4TC8cZXOcXRnarf - Tlevytqf1Xi814cz3Cyy7NKFDFYKouWVKrCFSEk9GnCacXdabHwn8Vfhha+BdZs9c8MRG30DW7ybTtX0 - qNpjaabqSWlze297aISyRw3Rt3QoeI2IC8NgfvnAvENfMKiweMfNV9neEn8TStdSfWytZu+l79z/ABV+ - n59FrI/CfLMN4j+HdOWG4Hx2LjSrYK8pwwmJlGUoTpSm5SjQrJT9zm92pFRXuuKPlj/mT/8Aurf/AL3q - v1Dr8v0P8tjp9D+zjU/Hz3UQmt4fGmkTzRlVbMcHgvwHM5Ab5QVVMgngda48xjKeArQhfndKaVt7tPY+ - k4OxGGwvFuWYnG/7nDH4eVT/AAKrFyveyta976H6/fDpoF1YXMkiLApR/NLDYU+8GVgSrbh0xnNfxlx6 - qs8q9hSi3VknZLc/6zuJa0cZk9Opgvfp1aalDl1TjJJxa8mmn6H0L4w17Sb7QZU09oxLHF+927Q0gC/f - /wAa/B+E8jzTBZ3GeOUvZSlpe9l5H5Zw/lePwuaRli1LkctOy8j86fjZPFH4PKSuqyXevWi2yGRVaSSO - G8lYohOZMRRv0zjafev7d4ChL+3aPL8MaM7+nLb87H4T+0jxWXYf6LeLw2LcVjK2bZdGgnu5xquc+X0p - Kd7dGfnX/wAyf/3Vv/3vVfunX5fof86x1/hn/kMeP/8AsbbH/wBQLwRQ+gj6j+HHxd/4R/TLbw/4mkvT - b2S+TYa1aRy3TLaK4S0tNRtYzLds1pDhFmjVwyAbguCT+S8R8CTq15YzL4xqxk7uD3V9+Xy62P8AYr6I - n0/+F+H+EsH4Z+OU61OOXUvZYXM+WVVOhDSlQxEIJzvTVqcKqv7kYqa05l7Dc/GTwnY27TDxLLdDZlLe - 1sdQmnl3ZUKIxaqEOeokZBjqQOa+LjwPmNefKsDNSvu1yped2/yP7ozr6Z30U8oyv+1JcVZdivcclSw0 - a1Wu2ouSj7P2ceWUmuVOTSUmrtLU+YfHfje78b6nDcGGWw0ixR103TZHVpfMnwZr6/ETPD9udAIwqM6R - ICAzFmY/sPDHDVPIqUqtV8+NqJJvpFfyr56t9dOx/ir9L76WGY/SV4jwtDLsPUwHAGVc31TDzadWVSoo - qrXruPuupLlUYpe7CCtHVycvmr/mT/8Aurf/AL3qvrevy/Q/jg0NL8J+FtZ8Q+P7zWPDWgard/8ACVaf - F9q1LRtOvrnyk8BeCikXn3VtLL5aFjhc4GTRd2QXZF4g074N+FUV9f0HwJppdd8cMnhzSJbqVNwUtFZ2 - +nzXcqgnqqEfkaV2Lmfc5e18Q/s73k6W8Nj4GWSTIU3Pg2KyhGAT89zeaJb28fTjc4yeKLsd33PSYvAf - w8njjmg8GeDJoZUV4pYvDuhyRyIwyrxulmVdGByCDg0XYXZwf9k6V/wr7+x/7N0/+yP+Fp/ZP7K+x2/9 - m/Zf+F87fs32Hy/s32fbxs27cdqrr8v0DqWdd8Wr4K0z4oa2FR7tfFmn2mmwyEbJdQufAXglIAy5UukQ - DSuo5KIfrSfQTPiqWXU/E2o3d/qF3Ne6hdO001xM255JD/DjhUQDhVUBVAAAApJXM5zVNFOfS7uA/NGT - 16D0z/hRYI1YM9z+BnjzUNG1628I6jO8mi6xI0NlHO3Gn6m4LQ/Z2c/JDfOPLaMcGVlYYO7cF3TPdf8A - mT/+6t/+96p9fl+hR5n8ZopJPDnjJ0R3WD4p6FLMyqSIoz8MvD0IdyOFQyzKuT/EwHeh9BHi3gnTzNcI - 5GcsD+ox3pxRwYydk0j33UPBWnXNnbzwQSxyFGN08zxNCzHlTCqxK0eOc7i2fateXQ8aON5XyxvdHn2l - 6PaWfjfwpDbRmeceJNHkwqk7Ug1C3nlkwBnbFFGXJ6AAms5Kx62FqzqNN7HvP/Mn/wDdW/8A3vVT1+X6 - HpmomgWHihPihoWpKWtNQ8TWcTMuPMgkHgPwO8FzCWBAmt5lV1zxkc8ZofQR4MfCuqfD26dNSspri1jc - /Z9Vt4nbT5ot4CSO6b/s0hyMxyEMD03DBNRaPLxdGrO9vhOytfFX9qW7WMCvLLIhEUUMbyOxCg4SNAWY - 4z0Fac2h5H1Oammk2zrPAXgC4stUbxTrsYjvQkkel2DbWe0WZdkt5cEFgtzJGSqJ1RSS3zHC4ydz6DC0 - XTheXxE//Mn/APdW/wD3vVHX5fodho6Z4c0/V/EHj25urjXopF8UafCF0zxV4n0S3KL4E8FuC1po2sWF - o8pMhzIULkYBJAAB0QXOZ8Xa38NfBkptdU1vxncaiFDNpmmePfHl3eIDtx5wbxTDb27FW3ASSISOR2yr - i5jjLX4ofCi4nSGWb4oWKOSDc3XjHxm0EfGRvFn43u7jBPHyxt78UXHc9p0zw34V1myg1HStZ8UX9jcr - uhubb4i+PJInAOGGR4lyrowwynDKRggGi4XOQ+wQf8K//szzL37N/wALQ+x+Z/aWo/2h5P8Awvbyd/8A - a32r+1fteznz/O8/d82/dzVdfl+gdSLxV4tk8GaN8T9VtmVdQn8Yabp2mFhkLe3fgHwXtlCkFWa2gjkl - APB2YNJ9BPY+MbS3uNauriW4llnuriR5pJ5XaSWaeRi7vI7Es7yM3JPOTSSuZVJqmr9BbnRLy3J/dsQC - eo+vfHtRawo1oyPWPgj4u1Dw54stNCuJJP7H8QzrZSW8jMYoNSlASxuoVwwSaWYLC2MB1cbvurgNU09j - 6I/5k/8A7q3/AO96p9fl+hR5p8ZYZZfDfjSSONnS2+KWhTTsoyIom+Gfh23Ej+ime4RfqwofQR4z4HsD - LPG5XqwPQ+o9B2pxR5+NnZWR9B6h4R066sbeaO0MEgjf7TM85kSVjypWMxoIdg68tnNauOh4ixlpci3R - 5zpml2tv448K29nD506+ItJlO0ZKxW19BcTyAZ4WKGJmJ7AVnJWPYwk6k2nLY90/5k//ALq3/wC96qev - y/Q9Q1odCsPEo+J+h6khez1DxNaQSFceZE3/AAgXgdoriEsCFmt5VV0JBG5RnIofQR4LJ4V1P4eXbpf2 - c11Zo5+zatBE7WM0O8BHkZd/2aY7gGjkIIboWGCaizzMXQqTv/Kdda+KTqcDWUKPLLIhEUUMbSOzBc4W - NFZjx6CtObQ8j6nKM00m2dl4B8Az6fqUnifXIwl+Uki0yxbazWUco2y3U5GQt1Knyqo+4hOfmOFxbufQ - Yai6cLz+Ik/5k/8A7q3/AO96o6/L9DrJ9R/4Qv8AtzXt/wDwnn9qfbrP+3P+Eb/4W1/Z39of2HpH2bP/ - AAi//Ek+0f2J9k3+TzjG/wCfdRrbp+AakH/FH/8AVW//ADPVGvl+AB/xR/8A1Vv/AMz1Rr5fgAf8Uf8A - 9Vb/APM9Ua+X4AX/APih/wDhBv8AmO/8Iv8A25/1PX/CRf8ACQ/8Jz/4W/8AaH/Ca/8AAs/9MaNb+Ya3 - 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 48d8d884fb80eea3ae142a5f6ef32afdf33ba900..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2612 zcmbVN2~<;88onVwLO>KXLZKyq>_Sr&6~vm#s%13d7KM=vDk369(E_sMRY0i=rY82VibM#Aia;X*CX9q622>Iai)kRqyYtfabk3ROoSFIGz3;qp-+%w}fB*O0 z|H2n=7|i)HWL*fr;c(zD*aP4o2n0qroMHTKcoV$AOpT54CInLg!7zzt=4M19iAW%j zW|2td7MKytEN9QMurz!df*7_Nc45PUNFW+K{x^dUfE5vZ0lvWFoPd!P4sV5nZGZv* z&IHTWknrz@Gr}92m|`iB%rS@BIavC5yb+eHiLo)}or(Pi##SbC9T%@LofjTWa5^-9 z$+2@K#DxJ>E#yrCmGjbFNm*v31=cnn*}Ay8xqEo}EL*<9*KcKDP;f}-+I3%U-m-NY zWBZPX-Fss8#_o&TfB4AP$tkHv)3S4ppUD08R&X|GX`8Zfd38F zAISa*mlcM~2;;z*V8DelO2H=H%GktlvFY43;e_Zz^PH9(BhC*vS5nntws7et6?s>Z zfV9BbN8&PWfc7i0{|;Ez|Ap)iVE@1+0v322MjqY@(16xeEmI#-x#{NBOJ*zWv_TmT z0(7yaUiN7r=k49wWtFLi>ErgCPt>KQ%dbY~h{=)Z?g35VfmU1d<~q#Rbw#a*V3raB zV;KaT&s9CBZLtM1E}|tSPBRv&KZoF_6^ommsj1Px1%c{fZ)XBS_odHX?CNtk|DS( zhu|PZ|ClkhEVI~Rgj^*|ShW>7#khY*w4SvV-8;_DS@OcZ4eN7dy0kD($IEx4i-yCP*rq5Kx(3vrPc)X>)c8r_tjMPFL?Iy^wF-$ zxKUB3{7zDf!;vHT=%2rfSBO-zHH)lu*E-b&5L9oKvh_YYHxhd6&GgwciIk!W6btDs zOjSMvtrUIXFq=4r96+C+;9KeXRKHvcdBfWwF`0fjGHN0+&4=Bm3GA?3F3D(&*|A`S zaO3*ULZP6b`sL6Oxp(G)j7yjz?qRWZLcp&>Bz_Q_8b#;PHS1TmK=4_j;(e9AP)VB_ z+No_8pxw(;dMG;t%tGEBf)Xd|vXgb>RVs7|(y_3x^{g2ihurNAXMMxJaweTBQI%ue zbqa!r~0lkknXEyVUX zvW;$WSWw-)euX~Z8qWsP$?#pVo=mlcV7MCsUHp_CO2KPaB7z_czGW#!Zr==nFr0eN zUoGDLXmJrUwlgt4pz>&AW3ycgvp_V%d6R1HExYZch9FXMhEGsTCn$gF|=4b(VO-^2q*U~eVYsqS|X6d)?oAUR+ zuodKNPPn^yol8YRgV4D)L6JG)#((F*55Ka|szB;Ubo2Of%YK*n`GW}$AG=f}2C)zQ z2dW9WxhZIPjMfJNp{I(6UiOX`kBzXuBk8`=U+2A&W@JLJ+nxi#jU|k+O!74M$Yg(@X*_S4JWZpm)kBT@dnP=Q_MebqZQZXtPSZeBl<^=H>+6|2;XNP zbMlu82*fWS(45knLXc~$`viiLLMaoq@It2NHcNi3-dUt2bd?n*s8)^RjZ|%ih;gbm zlfoEqROvp`utY;rdF=Ti>DPOA+&mtX?tR_(gqusM!+F|XmCSFPHpcz5?1%o2{@c>B zj{M-8jkgQ$FPhw$T<@U`#iwRV3j#k5n(TJx=53bCN3wEj6Oa5ETq3^$Eb+r4@Px~crW|FV;axJ_Y z_xmMHh!O(2#ZO;xCRg+4$ztb^_{4s5>r(f@vX4T-6C%Rn%G_>tMUD0`RqMpl!G(%m z2=-L8LNK$hmWyyt({>dPW)DN4II4BhQ8mHiDbmfkbT90JPOnhI3lCDX&R#ZU{>aC?= z=a&DBHtp2B6;tp1RGy)~W>uhFX%v2s=0FeDnjau9hFr7Tm?DZQ|BY?w5AukYgVU>- zgOZ1=zI(~Cydu%zb2GFYKQ-Q2=5=q`)3@m>=a+kI*mkk9^243Y7p7giSG8U&myB*8 zDLKo4rSf7^*$EoWEXvYY5HT~Ybwp{L+k diff --git a/EasyModbusServerSimulator/Resources/button2.Image.png b/EasyModbusServerSimulator/Resources/button2.Image.png deleted file mode 100644 index 9946594e1e68de75ca13827fb52442efd19b3aca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 742 zcma*k{V&u30LSsK%R>(56T`})wA7l6jxtZD-6 z*MrBCB&9r5WZXOydFZ(N9(jH`PffpkTK_@spI^VdLr;b9{o+W1Bz6b_)H7%*pen|6 z4YV&YRf?S%OxHqNjZGDny0A8c-*Zq`V6_j^by(@eVkfpWSo(s^pO|gJ{Cns|vG5Ty z3ak%dp)E5r6S@&>jA3mMlpI?cEO$dUj9-n|7{^*amcL@L9kXxT+}yCGhPDQCZ@FA9 zR+Wv7jacrAii)bNti-k!x*rOKA|oRM^Y1YK0V{pjnT?E$#KveuL_|zX43<6x2M0?e zl7N7Kq@*OdT#lXT!otGl=4Po>inRf3Q zV`GDrp18O;9*T*mzhDHwR z1ty<>dX6b6)K4*4f~hi+B#Hm-@IU$Q1!06N(`-|Lp|_(k+vzmZ($*vTnlRb$kzq)f zyD`VkgmIM1cixjAig(;szgt3|k#Ig#Fy>|=ex z+RlmP!hCh%*qM~HUXcllWn%BbxM;~ecl`W#JS|z2>d#;>nXYsT8(wHc)Wq^?I-M3y z&Xq+IHE_ZY6r}Zg z_Y_c_gjdS#n-tUKUZ1Z)pf5Kl%Pf~jo7n4+-6f_MogBDteAY!`%NGsS2IbrhWm+E* zhS$-vl>U15b__k+>&iiIB5bUI`lFMymZz6>%jiWCmd}bx&+O1hg1TK_sk&qN%|p%4 s9C7x|ArzO|#GDeD@@jxkdBZ{!GPv8JS5@xh8j=;;L3}r7>(dCqU!4bXH2?qr diff --git a/EasyModbusServerSimulator/Resources/configure-2.png b/EasyModbusServerSimulator/Resources/configure-2.png deleted file mode 100644 index 016ea7731d11cb5379eaafe55ecbda1aa3b1b514..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2951 zcmZXWcTf|`7RF-(3{83$1VJnzA@qa*N)rJ=I>rKoP9Ts35Tq(4AXVv2IyQnduMiQD zb|EzB5s(_`AckIF)O+X6o3}G(znL@VH{Z9r|7?`;OK+|b-FOv>Fa9ImA-Z~Nx^hE?RniAN7w7WOQ+3E?N`&s^QseF#eP@hZdNwE_g+uy zs+m<|QR+iavkjhB_1SNM)SAq<6xKGW^RgNt1lF)e{Z)^mw3kM4G2ygI9gWIS9vy57He|A6w$NVTCYjxEU~mzy94U@C@Mf0zkM zGLbHV7}C%zGjA*|uN?*ffj|tI+?|<{l40Roe*30i@mCN2D85rSj}e$Ofxx$fzY}U` z-x2QB)_xmQ%Z~*Uu0{P(p%K!}Aq?0Pjmai2Xg_bf6e2!{RYTRmqE9-b8z*z&g4D)^ zg-qH{np;ThMkKq0_{?s=Tv35exOn1^xw1G>_0OrZWbQA#mX_uS?7hCq6ZQVoux@rm z!>(J+>+^j|ZW-a8=fenZy&81}-|V!4(LQ^HuS!Sa@c1n8vGh2Cv9T4wLDNA}=+foc zq!?j}^*y!0jj`3hp;wE$?Rm|qpoP`NMtL6b5=#i60=GrPO&A!^s`RPTEp_*xb|=k6 z140@n#e~^RcQ!}jyV7K7vk{58a>6;q)}=}_yV%uaxu&mxT@lr50Ve`$wtg_c8MgD5KlO?|5V8*?2wnHFm1wTdG=~2iIe7+=sKvY}iIiu102TLlI z;~nH~(sak=Qz4R#R6!d8K+b7QewjFq*z2J2Sl(4|+uK}r)3)DqVdj>GB}z_a9e zJg=mrWm|`E7?~Sq!U#HF`TDAaJ4uTZKaOZ4%vI0ePE5uW<*6sMeq$+tLaQ&gJMpcxXm z2R(!Mt2^}=;7#pOX;UC)C?(VLR zMpmPV&Ppn3qNsNA=|~BduC`{gi8X&uryAx;RqLwi9d$ll8RCZe?JDO%x!?e=u>s3q z)Iv%ratMH9VB=~vvo&Ao@D>mW4-NBmF<2-Pe_J1qdxRccAyFP+mt!5WAnpk?#Pyxrg=HKsfeF*@n-`( zVF_&SL*R#^fRKSL(EEoUr98(9%R0+2EP;DY5+qkP>*sb2QQE`UpOkNkVUa&l~7Vlz)?NWJ{@LPIWm zt(3|J%4|nWd^{PFPe^QhD>*h2dwgLFzX_bBTV_D87T$hOH zZzngZpHGe7iewSh_lSzL)il`|it{%khkBW=_;KBbyjOC~(BDg%I&dIEzK+xcP;a!@ zJ3Tvpt;|Gov7*8Z8LdyU2LwNB=l5xz6A?8NnI8TgpF0Q4@_Q^Tn%s6+t5}N^OtAtM zdgmTiXiTgTT&9f9zqnV+T~3j{TmI;l3?CZ@=Z#w2dfNlrKt193nx za4jy+{^&Xgata+?*Cxg;%{g;#lSW*r#^*olRyx{(F6A#(5AiQwwr9*#Pe9s%Zjo$S(0|Qw1^WpHMiU(vNj#JteE5U8IzAzB8;a~pb%u@V#f7a8FKaSHc(!W9J6`HeH=k_FIee_O5 z%J&KKP1~Wk$LoxOQgG&(evQEHO!l6GLCw(>gA(g7M~+QG&**rW2urxMh&(|vkqPNh z$3uVcby~Na8eGUQZ2CgMWu)*+6@bZZ5AtM2e@sKO<`KmU8tTFyBRntFi+Y+kIWe8B z8zny|ZZL_F>OtOemX%N}_XK96sQkjAdG{XJpqbU{T?h{p&KzT#s_ zdLRow2#P3zUtC${xOlYYzi;TOt9mi`+S|?Ts@d@xuY>6EcbANS!bJ97>-$@;HJ{`59hn<)n1(q;^&FS`FShUx~N5&5IT|9@{!5P

4g`1;V#dFlPZ*sMVi*uoE% z^ID^llgVfPIPX~WfL*nvNyK*!Ip$ z9whKZL`*N=1(rWga0YTnKDuTQo+iaF#eZW?!EnIs5|6&L|L(~CA%{4Mm$f~>#>jW; zxrMi{I>@<1xHhQwxXsY~;4}N|2lmwwhdW#m|Aw_@bt0f=s?OhoPnxJP^sb zv-C5<#3rLeB2Q~dnnjDVJ+TmLSGV{f^pg?ITZB|x&^FKhV_d@IVOLmwc>w)0CyCd# z!lSSbws;4SJ$(Z}ArKXitSktsY$mG&lU0U6l|c|C7z84lSaIcF;MXMV4@C!LAs`48 z1cjJEsX-NX!{43k%e(c#|?J=}a4I-u|?l7S1# z!2{<2aK__3VPNoYFBcyN6vo{hfv&Lu7%C$RhBs94|Lge2?ElXs z50j&({3jx3`4cfZ!28S56yuFWIRG@VemJ}>TFe-Wadkl97pG_Fe+R&Y|4!UDH!=7( kmV=K2))sA#k)h|JXZ%fqixQt9=?Fki`=%E0n$4sC0Ez^DIRF3v diff --git a/EasyModbusServerSimulator/Resources/pictureBox1.Image.png b/EasyModbusServerSimulator/Resources/pictureBox1.Image.png deleted file mode 100644 index 836cfa7c78a91777f347893ad524d80b879dcaed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7223 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 buXt9*rs{UuW4c%ZuD3XQTgH|GYlQP3TBhC) diff --git a/EasyModbusServerSimulator/Resources/small.png b/EasyModbusServerSimulator/Resources/small.png deleted file mode 100644 index 48cf80f374d3cc801c7a15b9344f7015bf0759e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8359 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 V_dwA5Z@B - - diff --git a/EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico b/EasyModbusServerSimulator/oie_ITkzMZD7tnyn.ico deleted file mode 100644 index c14eb7a7f58023c3175e727547f4b8c45ed0fd01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19550 zcmeHO3wRXO6`l|=_#!6Rnb{4|r5Z(f_`)jH_6rDFEhrxfMGIu}P~@vxpq7e=ZYs!2 zCDI}qNwP_(4`M+P>kA>ls63L)ZiMno7v@|7Yfs$!2%iY!*s2lkaBE z+{d}+{P)~@&pk6MNeTEHKTN{^{?e6WBuSAZ=`5u2NHdU_&#T}nNvi2bytRrj5kxenj}e2 z=x)EF{i;c+eWCBF;=HtUkr(T|VzR0Lvzx*1_qZ=9@u>MFxymTeLyGg9?uu!uQZ&`& zSedV=wAG4yITLj+VO=ERJw4XG*>2##oyV%GU+-#4Pv4dnO~2sV-|5t{GBS3ihN_SG z=7bJDq_LsOqs{Yql23*$-sTQoN?Uu~Sn+hZ z-gVgdbf&A0Q51iPs%mWhMQrY3cQ&H+>m^QB!DN4f)ilWuxdB4k5M^{9G{-`3wAn#YaFm# z!}VX39}Rbbr!QB&C02QCc)kz)X-B&)49kJxFYx@ig~Lo>vJ`l<@Y&&b+ZCx#)cYgq z?Qy%S`mi485o~u#zb(^!IciafN4a0u;VK_Rm%y{wBhQLeEE}G?$bmqTUobhj zCWW-a5tztwMS1HqVD)r*`i_WeHpXEN@k6RdS|P?I!?mSl!mzt{%^W?xANd_k*UBkk zzAN{{DpxR`?R;YQhk##y;P(aW`+d-RxK`kKTh@@Gf}v+teuX@)AA2w^QzfbDnD##Z zx0JvWYv{sQB?*sbY#eFdz^)GIOWLx@rLH&q5%@EYAr--Yx(ayuEnMGoI{g#k>CeU{ zxg_~KX=fSxkw<+fRvyve8NICnr^kTP0j#x%EVN(n3x`uy>_Lb;@bdP8eNIB%4~Z-2 zT8zOcv&{a#uD2}vFGZc7g6Cx}*Pi3;rSYV3o)}=rm@7XTE8j!mDa(N=(B;{7{*{R- zDRs$`wDZ{ZJd;Ab9AX1Z=LeU;2U!VO%aPw<4>J2V_Px){w*C!HXZ?k24~%a@-d-!8 zYcW$Z^5?>y6NCHc?sI8Q$|=MXbLdr^Gp>w<-=Xk?{P$50=unQd9X9kIOE1`<_8#|q zS>Bl`%i6gpr_cV1Bvp3MmGK8-+;e2i>(EzP+B+wqZ2@@hL*jbNeT-xCs;bss4UEr* zonC?GXPA%jClALO0Xe6em>Or#8@Wz}mN<0ogb8{gWGsYyb3)WeK-rz9UIwPyK|cun zu>WiG(dI=Y;`f8k1eI{hAE}xQq$TKR&M*+WQ*{7n^7l*=(eX|@XCxp!1 z&MJdHZ^P7EIbmR@xfn|)u(yXTxwp7n^+QAPpdX5QWv2dG741E!9?!*VxEBTGhkXRE zH5i*OWw|O$42?G6r|(c7mPt1YO0t!4z_iN3bw%aW6s&QvU$DX3OpN?bNmAV*V++94 zI9~#X-`ab9Y_j@2QzrT6_WVdR?HuX3$aRddZjDB^NPHrd6=$m>xRz3W#!4d9jZ|jN zIb$8uLf9M6I@oLdql0;19u^`0fWy&nfha4_RmT|ec$ASM&%Emi{rWXz0JqCIcAN{K zH=+Gsk+^QI?O4C#6Y4KRowm%(7m_-b#PeK#NH{>}5`_wd(XZ^1`%NW<3 z1mO4x?Gy2aZp?RoGjv`REE#mDK>j1}jk1BqN<6O!t^*8aT38^CqSXu^^5_TGUoz`M zr?d7a$nQ@-KDbTiXPth9;TKU3_(|sh^AlXIx6ZEJPcNbi32pa1~;i$Aex1d@m7o(KeUug+G9CeF`#F ziSlUg;OzkKugR-(($+Fg6D_Y;>T#`vZStK7Y%})rC;Nu{w9g7t4)d%D`?w6Y$1~w` zD1QhE>!9{F?wE5rY|g9)Y=4D3%vJO34tbuYOkG`jzGDUL7Di@&E7{Onqvn(z)~}ORz;~D0-nG#kRPdCyvnS1*T(x$oI4-vE?>w#i}G_G zbBzN1AaKQ5llwqmu)|U7;`tBxIl%EXloh9@Ztcr_&|f3{9r?!lHQ-r9Jo$bj8o7Ax zMBCj=q}k?3<5`j|XA9fJd+fo{$Q`K;-yOp?zJg9$g-?{4N?$SXOJKlQKbmxc0+g82i#-qz2h zw@t=zg7xgqGw@h!+1YF1_5tqsz+kOaZ@pMk*)RA10sUWEn&H~oiaPtSUd)B<9~Vj{ z#sGoiN8kgWK5&A)&Jo2E-%wd|9kH1BU(oSpVqw|MR@@7L^BkllNLA1uSTVljUl7WU zSKwXd(uwD6p^eg3i5c4cjQ)VjwewW8g|9$gOxsLej2#DSaU}8d;X4&;uE+ciDOmpC zXZSuUbS;41AcQ}twE~+z;rRjk8XDY|&xj?IQN~+FO}Ps^5YIH$R*a2*FL31h(gq}s z%iiQ<|H;8Tjuf8eH&15#1Ag<=U^(Lb%-9@shTozU3V$e?KKOlrIfvvT*2jDv104TM z4B>wn=MFrNC2!bgr+2j$p1?bh$M!rgF^)hwo|pMelj(C7XDipllXoay=2_d=qsE0Q z50}U9yh=U%E{J}Ue6Hm`yohnxE81|awZuCHQvb zj_<`TG{>EoI=|nQwz1U3{9Z<#Isd!bzG%v+i*CDo($1l0tbW&;<2>)sN1qMfH3PJG zuW~ba!~PIUHqP-isJ{_e3BZ4y*~W-JiT8Mux++V!`tX$}3OwWW4Nthfm=C?`p-+go zQ}|YhVGK3KLGk~MSh$?EZ3EmdZ=B;b4^CQYWfE}s{*@EX}_Wzb@@K!FGx6t z)%CXCOYcSN3*R;3#JD~ec8y?%n3|+Kt z+4Te8M4aK7BD_Da&R#fU`4{q=G2tIL9NHOXJL8+FXMx$v79YF=^xwgHChlB=wT5`$ zX?^dwfp}v7JZyWrKn>XN%#OJpm?rYc|c8R$6{f5tx7gMI^j7RF;g;@$(9jCXJN-l8PbI14$tcdz7o#K$c?3>`t! zHU=Tx2i$m`LB6&hIzA6fSHq9&{j}3sn>kn5r=R;3V)cQG?QOe4^LHIKEExlf%i0l6 z2FSY#awC?>c=5q+8M!vT1{>;DtblPGtotRFU2qS$i*ZLG3;M`KALB7zEf~+w@xAjn zS+2hhwh159IGdHA>|>+YH!0BENxQc!5+7x|JV5pS#G5~>FI$pMfsub);@l( ztj|3n=*v^D2ad*jEP*BXWjAP`CB=}W{h`I-zL1G)n(O94wn_{D-VH>z$xq_MOhfgS{U5a>am z2Z0_0dJy>bBcS7I<3GJg;{R4WCbZMllDA1}k=%LKto+vn-JIgCc3b()yY+%3LF;;-1VQiDGln;LjkeAEPW|DG{%*a^-6S

pp%hb z)0)sW%%VSP%9%?VGV6qBwneujwveVS_}4Ojw$GxoT28ztNzkp*a6x+!XHGP5&|AF) zQbD3l%=Ol}y^>E%GU=9_WYR6nZ6;BYOK-gW zbUl%DW0v0JPHIge4ZK^ElA4l9<7$(<5;z$&be6n=Zj>-gR=zP97R^Q?KhE@j0V3Rn AOaK4? From 6aba36d2a843e065fa788d7f18a4c8cad3367ef8 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:38:29 +0800 Subject: [PATCH 09/12] Delete EasyModbus_NET5 directory --- EasyModbus_NET5/EasyModbus.StoreLogData.cs | 120 ----- EasyModbus_NET5/EasyModbus_V5.0.csproj | 20 - EasyModbus_NET5/Exceptions/Exceptions.cs | 211 -------- .../EasyModbus.ModbusClient.Core.cs | 328 ----------- .../EasyModbus.ModbusClient.Helpers.cs | 508 ------------------ .../EasyModbus.ModbusClient.Protocol.cs | 189 ------- 6 files changed, 1376 deletions(-) delete mode 100644 EasyModbus_NET5/EasyModbus.StoreLogData.cs delete mode 100644 EasyModbus_NET5/EasyModbus_V5.0.csproj delete mode 100644 EasyModbus_NET5/Exceptions/Exceptions.cs delete mode 100644 EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Core.cs delete mode 100644 EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Helpers.cs delete mode 100644 EasyModbus_NET5/ModbusClient/EasyModbus.ModbusClient.Protocol.cs 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]; - - } - - - } - - - } - - - - - } From f186297d97acd487a1c5b003e238f05b977bdb3f Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:38:41 +0800 Subject: [PATCH 10/12] Delete EasyModbus_Net60 directory --- EasyModbus_Net60/AdvancedModbusClient.cs | 32 - EasyModbus_Net60/EasyModbus_Net60.csproj | 15 - EasyModbus_Net60/Exceptions/Exceptions.cs | 211 -- EasyModbus_Net60/ModbusClient.cs | 2851 --------------------- EasyModbus_Net60/ModbusServer.cs | 2266 ---------------- EasyModbus_Net60/StoreLogData.cs | 120 - 6 files changed, 5495 deletions(-) delete mode 100644 EasyModbus_Net60/AdvancedModbusClient.cs delete mode 100644 EasyModbus_Net60/EasyModbus_Net60.csproj delete mode 100644 EasyModbus_Net60/Exceptions/Exceptions.cs delete mode 100644 EasyModbus_Net60/ModbusClient.cs delete mode 100644 EasyModbus_Net60/ModbusServer.cs delete mode 100644 EasyModbus_Net60/StoreLogData.cs 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; - } - } - } -} From 209d468c498d8ba996c34b4966274f60a775caa6 Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:40:23 +0800 Subject: [PATCH 11/12] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) 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 From 3f404dfa019e8e869c6702fe9579a0ac4842dcbc Mon Sep 17 00:00:00 2001 From: lijinshang <58713540+lijinshang@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:44:48 +0800 Subject: [PATCH 12/12] Add files via upload --- EasyModbus/bin/Release/EasyModbus.dll | Bin 0 -> 71680 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 EasyModbus/bin/Release/EasyModbus.dll diff --git a/EasyModbus/bin/Release/EasyModbus.dll b/EasyModbus/bin/Release/EasyModbus.dll new file mode 100644 index 0000000000000000000000000000000000000000..f1c2e3d7cd21131b26ab669105748422a2d2cb0b GIT binary patch literal 71680 zcmeHw31C#!)&G5O-n@A;S!X7hNkSll2u6}13HzcFLJ*KmKnx&4NCt?8Oq@xS7^9(D zw~7^)T3hN?YqhJkYVBgH*4ocj+hVn?R;^aM{kv-Sel7lg=iK|=yqQcOAoi=@M_|so z=iL3=bI(0@dvDqLYlTM$Vc_@HTS7d9C;iQ1cwjIH@4~7t6^i@)Pmg^_Tl)0aHQPH< zvF>DITe5XWtgW@HE723%5|1T&yJ8((u>~tu$95#z`SPS2hc=RP%_!H}|&N zxxFHeiREdNg(%j9FeUY?b#TYvo`)xV*saTQ6M@Rle}nJ`o&G#x-g_x1{ZBs?N+kSs zBHb0_K)SCJBeMTCYa&0JHWEB0gyjln0bk_8C-ua4_5gpp2<3$z*Hx9<4hHh(Ny${Q z4FoP5%E%QB;pzIDhtf|<#yb-T$Yn*DnFo;};pV%dvGX?KEB>f#y6}qIzAMC28->V> z$w5X0#_0X!DCERrbk6`g5Gy>{BaX)tX$JNFQSc6!c|K1ynkCQ^LcaO>g+#S{)d*4( zFnv>gGVuWM5M@O1z)s{>nVDZ$=0{ZIhaf}q%Z|tSjUXPx2lq|pARc5M`HjiUuT!DAfzXq1bPsruydL`t+ym&KhF-QC z-BlZa#5-=k%N=mJ^T-_?fS@`-3tjFaa>oY8Bjq4Fe+l*spoj=P5TQqOAWDyNmM=X< zVkL7QN91ZWR6y@XB%^jh^@pKAlBim@C;2|WBE1@X4OD{?s77Le#78IqKzB6~4J674 zKyCwx3V>=zWuO|O5=j1xf{?2kEg67tGY1T=y)CO3y&HK{A$hb+1CL~V-wt0=kh{PD z*lXzh1U-o=Vi&vhernJ}%tfH~OpJ9AsAUt!xCqqn2{f#e1{01=6ZV@x%oOA$keC2~ z#vpz3XXp?5dsoS8iEN8U(H3tRIAr4_ zjsx#zU&c81onvKLM(d(mg{Ve|ED3oB8#aLvBY?h+9%;<{9krzF(|GZQ^g^h7ohWky7d}gWv*U4sm+&9J@Eu$*zIb{=5yM$Hs2SW^E@(}`D1`g-A8;nknS789?!dvDWlNex1#1~ z(O?AJq*hK$12?0Q#B@ArOI@_Y3{WEbJvCZ1@UnM8B=E8@>n7>_Bxkjw^au-FF7B&V znu+LW2n|gLUW>XDgcnh@@MN!80*a6N+ch0!lk$=uCjpv;;1}r88}!Hxf$G^n@=Si@ zSMZoMK4L}o>>VGqqJU*Sa+mwyj#ST)`B1u$AF?HbWxL_h#z&CWE#sp|^p=1pIwkCo zK>!(^0kaya){&PZTCTZouUr_NopS9$y*cZ$s+=Gopb^Nkj9LgmWP@Ndq>58M{|WUz>EBgvjOcc~X^s(~ z_O3n|j)2_*%rZ1b)GXh#H_st)Q&LOj+tO`Cs!8;~T%U4HBwoT+5U?nbCag9S^9py5 zFu6yVXn;JQ;(fXd)ESR-8DKAtpbVFy%rJjZ=6M-qsAN8jcJrZvNu$6Ahcynj3LKKd zt*~LsAtc`Bm)~}kIXo=S;338}#Y5P(s{D>Xn=H^K3pDeyJcFOZ74jIs?4&sWa}56nap zAjA!Q-4v(eS%@^N7l5cIkVOEGg?N;0P|uAmtX?Ri2|kO`-E#{kZeG)ILb1>CSvSbc z_KexG`4-O2cTGpbvn0~U!w`LVV%ii;Pld*R?>r1=)u&KyZfdVh&GY2P-a@njhG8QT z_SV!{(RKUsgI=Qr3h;#TprMm{Pixrpn?Z9=>od^3cosmXwm|(xCV$sIW=qi6ypPH; z3U&Px>=F!%uuGuq4Bc&+quY^Tgx+d+dJsm#FnuhLy76XWG5JNo{~2`|IwqS{#Xr>V&DfmT99 zO6{7C8qKO650O+M_v?}U+UB~k2P*H$Rd2oZmTqw&2QYBL*5u0T{e(m;JL$|!sA$Rt zR5tv@7+7W4>J{+Jw&5cKRCct^Sb7|=A>`^!Em|0w4#lBzB)*DTO_cV~4sppJga>|X z53PY*zzzv|Do@ZO6ZOcR=zgTXC-zs+_v@Q$L6m(A^Xam6`y$n-omssSMGRmpC)%F< z8rXz!K=(uy!qK7=N#5QA;{j$jO5;H}YHQ`p;M1sWk;YSjBs#}1bAH(IFx8A`%K$y( z45`3hJJVk_rA^IujzdA})~dwS)NBb76H#58{MiLlUN1Ls%D%c zjmxlURl>X+!`)ta#iX=7g@y^5x%w502@=Ah5oA-BDGgxx$*{mNdO8VG5J^fr2I+`R zMT>Cj#Ym}9q-cQv-Pm$ifkWXqqLutQai1OKTc6;`E);yc)zTwVA z>J=&%DHvP7RqhFUgI?LX+!05f{Ok^>E<5g|0#{y`;YJ23sKQyP33p*P?7;M!m_qBA zq;Ke{_Y*DgEwD(ptTB7aTlQtkhb>6tUFC0)`ooqeCI%F7vt-()+SQp|_RWlrr_+iw zbT$>ZKBP*XY%tLqzeN2QYJ|L?Mz~5IqZ;FtIZ>uP`yS|}%+$9cCfA$wNAA==NU5)e z5Du5RNI|m(!qES;l2Hv417Zd-H&Sbf?hjg)g(>K|pg(a22opF%TN0=0>?a2mmPQPC zER9T8BAz9YdeBO=AgRPUfF4+hT4Ft10~pB-<)s!+Hh`Q_E(+q5E96g{i2(V?Djaxw z0>C3s?Rq^JNRN*es=`BKFyQX0Y8ZSLe3kyWy6cc3O)d%4jXJ=B%uD|T>6ljscaxU^O?`rtKt{~695J8CjCqWOn4cRGvph%4I}p^B=j#;nGecrl zJ~qbVT44ge;^G?)`K z_a-w1QqAzr}`wx%>{=aGd&48;;Cs zT17Z&!^!0fWy3v!q3@^-r)0ym!ZczVZWpYJ!?WR>n1^h`IWZ5}hI3-Ri*2|EVAEmR zm9-A{n|GBBS2b|(MYvP|HniN(9q}Su`Ttb|?h#A`9>aPKmMFx`mFYz|eN>sTUar3# zU2=;YU2?n=HLThEDk$hMvn^N?*lC*~pAdUWcG*XvH<^}4e4Sg$Lxol#o6vyouoUfUUM z2^Q_e(w&W0w`1w#p4Y@VPm4CRdeW1c%^84Y9+F+JczC;X6JGmsf+6 z(6dp)y#JB&aCCfld{rLb`*59X8}B;VcG#!jE`U^g(O!THxD2r|^1LS>(mi_K4Wq-m z;=J3Cqma%~x2pWCV{TOilHk}~XJoF3z1{UT9QQD1J_L=Tj=AB)Et~*GtvV+Ac8|Gn z4r@tg9X;xHber_(Q8zx-nCo2MkW-5z-X?wTVcTC$%tN-noS27fe>pJ^$^N2qX*kJB ze|IVysorHHkuCI0PFv`oLv0}#Oz(DEsB)++bkz1ade(nAB-{FrKI{J-s3^1^)4jSWV#rpjjo&G$EBoru?dk{7|FdMhoD;I#@ZVO#^o zWVzu5C64O#O7B4+d&5sJ5Z%55E*T*KT*LFxV?&L6L|dN8r%5=i!xTiq>NaNB7xdN6 z3i|#%7cvjLqBPoS;nEH8#mcIpA%;{{v8lIyB<7Gz+UudCQbhw!WOOviX;`+36 z&obyuU$hK*(>E=H-t<+=pf`QjGU&B0TL!)MZOfoHecdwXb=|iF5}=n{;F(9SyudTx z+8YU5HM4>i+Q0)=vUW#@-+oTC?fS)K3igah)aWRd*6vrAdEWX|ow zLX%p`dV-w*M{FsJb4VaXwUkwuaXS+7u5L#b;f@t|72Mk_%5iT~N@iJxWZE}3NoJi3 zfmxEN2MdS4x+%R5esvRt3l;IzP10q!yjiS{lO3iMNULsx9xP7Z_+uT3W5noa#qJJ# zcvt>La(nZ6?3qkJwp61L-`~6wk%rvg>|`RHvQo)q-r!_SrJ61rq97s8)M+yoIJb2d z%C*>&af$PA<-y&j<-ssjKmrrX-9z^FPA4LmhFZ&TZfo4>jCYKS%9&RI!2}6xIwBjKc zaYiM*J15(SW0GWRUJya@A~KX)Pq>Y^ypgEJbfWym4Wz4Ha*&aB)==qEjd%rZE+ft_ zjkv%tMqGXWt$NkIF|b+lVt@#07$w_h%V#BgsJ;aVl+l$2qu+IJ|fUI(F!*Hwtl8UiBTAT|-~Kfk7KhoMFU~ zB9YSz_EA!wC7F7#V0a@=dL7(|L*YV&(um_ShH=7!$NIyR0>_9eat-uU9cjcBxjXPX zZN$N7q`ouKmv9`+h?B`>8*%BT3kNX(1cRLE@J3v4gqrHms0ExQAxMWyU=;BQ7)UAsTV^e&t+c!|ltm z;qHVDhgWJkHk`jE<|{OU{@g~KAHzLXbqXOF4L?$=c4zX7tH$ic>xc0!+2rl8=I$6D zRR-N1D@s&wh=euM4Xx|;x+b~;TH6q_=l<`_M zd0Gpv@SKdi3gjbfsHYbTj>;IsNC#su@b57Ooma2%(SNUc5!+_sQB~i;FM*EqO>9+p zlwy`$DPQLy-^i9PU&dD8Wy3RUP;lw=%9z#LX(DD;g;he*M#2)D%k;Edrl;jHJuR2% zX}L^K%Vm1f-9s`ju(aoxp4J#P8gXfa-b);`l)-5!gA=b`<9F!70|T85fn^J_Gp(v3 zOeEP+95k`am{&6if|;kx(tHF62J^@)&6mML3ZpoAkW;K#QAHcRg_lhQacVi2UCJJA zyOaq-?NSI7+ocy`VtpTGLg-9l<|sgWaWVT6Y7j4YL!Q~TDU&4MizrA@M22z?ZEoAN zXe1gxov5@;o!7x-q@85}xHP_%+cs6N@+=(2HZ2YnOWRbgGamGXBJ_GOX`5!zwV2Bn~2!7P;9)&i$9##ZV% z($-?1;cTto@V1upI=HQc!i7T8)?yJ2hn216FzL`NZpYRNyKJrW>(0V%fqbWJExdvZ z>^ow%mP{_&)=D>BxD*;MSjw3WZ)=r~u;(4RJh)|4Ettt7OIxet2sEs+wMuffZOPkj z+mYE?^cu69q^)(RZ$QHc;*NW0wpM1`L$kFq;~tW&W$;^?*uqo<#Wds9RBp5LoJ`?m!v~9W9vBgE}aeXdZj=oWH zCzy>F2HNNF)!Es-Ft%I<6@R-UU`D6U!D87?*Q;su{$ptAfL{HE4IAv^8i@`V4C>Pb z%QHS4A?23B(HeE)Yz~J~8APII;v6Ck|M3I7Z`UI(&RO2i4O8A~vuu+7@@cYYwewsh zubtv5@5?8QtZ*;;^lH3aHt^y^{`LZP48{59)8`iG9oV`!)+rkpjqgiErx$}?VOOpb z<(9z22;LiSi0KHAH^v83oy-eogb5_`i?A8auj}^l>$>wzkCoVgP>C*pIz5UMus}yK z_$ycJ0D-o0n7|GYs31&W2M8#$K~ZVkWDj9| zt%djC!8kDR4r%!uBR}(m^PTp$#qj!7^rMpz$n|Y8aF4z%MpS$Y3k@~&TUgogz|KI= zaPh$R`BV)0xEVV@SU?0>4!UbYe|jo`R0bO1qhHibP70*HOr=*ZL*+cFbBR8W==}r} zN#N3n7pJd8kW>nkl0*;S1lgwRDRKNAFny2AOlD&oYBu~H_s5V2-pm!`FXyO2c@n)S zNWhHI=eQE*abcTK?%ESg`Cf$cLE?{QMR%XdGs~*kA4%*4G4dh3pF&pm0jVvN!6S(a zfW3ScUqZ)z+B{;!(0ZGx?}HP0zQhmk7%%h2Tr%KGJO={a*-npZIuLUe9LzCaq8|Y! zaKdO84R$oV#HP6L&^`!mNr}_HD&3^h?t(9Z1oc29&kSkR7b0>5Z%m-ZOAG)hs42x; zM4!bPAO`_1R6 zfS?7&50X#f5;$cktvZ#TCvho=D)0Bg8TP&$@YR}T^<_X_40@?P=;FGl5Xa1=Z5{eM zRn+a2_0jQhz#DI-Pi)Bd@qYu)(WqNU>@PJC&6Bts>GVQ{=y^UKV)8>ePYM#xpme(K zqYG7L^-=)etg8^a1h4#O-s3C?zU6fVq8AWn&-K@76a8{xIjE1Fb59VG3hnV)D_LEsW6G}AQuD}c~h#kJW+&K+HLt^G2v0WEp`6>&KTAMPU{6~ zLLtGe$JK}=P%9KrHr>zAbi&;M6;2ayDJfUwCXumgn6Hh~==wAuuAfUw0TumglPo4^hb+HC?mK#1D}c7U+eCa@!| zC##r0813D95=xNtBvGL!&0KmiJ09!F5yXpeew~^5LAg+VL`8lW!-wkS?0B5taPd&z zvys-s`Fj5bJnMYW&rFcE!HYuvsSg&Of*^Wo5yWo*06RU-b=!f(jPu6_SCF%80GgQI z!is)j=*i_U4F;fTh_Z$rtdRzwmkqtDeYXeI8aR`X6qdjP1KZNh?c|hW0ToP-O|sN0 z-Ul#1*by)$IKxEhcT~V7MA1`kkQ-{1+q4jY)zf#Vc`*R1Fv_b@3sH*0EfsW-b#iJAuG2 zJJ#{6Ia}|CVPMp5kx%~6UhU}$A&b3c5r&L)6a>aNJrf9zrBTW;@qPq&`M3!$AB!+& zs4(`GmEUCAI*dp+%YyM8hDA>a5QO@z%b-=(Y zrfNK5iixtcv!^1U-oKEFQN`w2vIRXt@24)2{Z$cZSyIhqWEo0*4pNe-izQ-Q4@scT zralKL3DoV>=O874x|;eNq>BK4gBL`ICa!bbXhYZ^u1`ZMo*z$K(e-MmA8?tpK?)@? z2Z;5mb`xdoe$2I_5LefO6EaHm^@#7DpmDtYW*_DCGyr|j2Ct8Gr@t0a@^oM720RC- z`3@%^ZuSc)NvRF>V4Z?>G1kN_PBP?GEcLo7xFB zs|-u+6!y9z;=_Y3Or1N(?A&J;i*75|x|-fkrUHGOl1+xhk4f|~mYQMp@I`l{>uO<3 z?e+NaiIfO9JpeU>6XwwYG&^`kDzg?Jh@oe6N+Rfw@~(qF!kZ9&tgb}L*rW`aa9%%9 zO|cOOpFj&D5WX0PM|L1|Zw`b{r%@n$J1s{ba2(~p_hn?}Sg@+T8Rc8QZqGmsd-c;p z@263o&(H=Zih1x>BC;Hd3aznJHHl&3giU z#hxq9f5IFs#djatMO#u0xwMr$RZwPN;A=9v0>H$nK;Kl#ppv6%P%r zBopkUK<-w|Q>`d>Sck@xRgpWcxqa&b-B1-X};Mn2R`fV~5gSY@-vQF|9v)=ytw-r_zHnHf0%i2Aa_(E6elmAt_!e~{N75qujm@<=W0rAD zgS%thfQ*Y5|*P*87)&(EmOz6cx?r zr*ILOG+X#??IsHmsUKD4#~B>5W*vjFMVjX|u`0j8CPm9IA*7{TU|{3Ba@{inWS|<% zcRmwTU`6OEpB1Hxd_xP_MhWvq*1YyyTo$a^q6$f0i*1x1L1WDNptprD5t?*~(DX-O{C%pChf&PfmO-? zs^KSIXCMu#pZ#q=nQHAC`IL#*EX3D&5k`GPj!UZ6YYvbym5!!#^pxq?b9WlMF?@(O z@k3`2Rbak7MgtWW!}Ahq5a=Epn)eJgjp-oK1WuJwsLGnPp7Jx4((*sERzZg6X69tJb!vFl|*~ z4p9~4#j1k5a;SCD_}gBP<+U zE%1+Nc+A96MAv7wS%)^?%SUMf+dn8)VJkZxN{Ek zN60{EH_Bw!UY}_Ltb(o@n28Rn_iqPuEwbtTOQ`^?#J1Kx~oBsXd7dg*u4@jq7M3J-{!aH?Y3I zHc3?=$Zn{i%rU=gL&G-@zhl1xqrUv?^8rWw1N5vBb!;BXb9U@^b}WAeN(YM{!jm8?&a14DYXWR4}f zbRLb%=+SICR0Y^cQ;ld#z9m&2dh^q&Hy8N-=Lcy6gS2trLE6Z@*FgrcyDu9<25G#D zgY0r1q`m*XLE1iFdII|F8R*BCW%b$b0*AeRxMQ@kVF!=|tpU&yHt!WkXXJY9h1gDh zp)&82Y|1@ZcaP$SGrvDSBc~}iGn#Y8F0Jlp0_I@G@}nKQ?!XZvLn038{63>{q$7EG zRsMg%T;Hz3sGL)L>f|-kB;VBBc#IsS{WLwc8K=DDbs%*c$R4UOXFtU5{SFM(UQE!v z2cDpNN7lW)L%KH>x1DLXnX7xh14FgmzXL5(8YB%+s$qqI!Zhg9ZqAcwdP0gyXa?+Z|jiH=AxSMC;gAbkCm?UQK4|RQREP6D(2f z;|H9~XX}K@;a2;xI$kl{*dO-Fm9emiJ=C1*cX-PpUJzx{inuq5b)}3&Jn}44o;aDn zp3X`hc~&UTQS6Dgt*NDdyjn=D{oA^3G?REC4=eGKN{jw%5uE6<2q@VxDp{=7Q>Kz% ztS!hFGkRIxD!eBW-nM06zvC}}f#_KXEU(V305a^-z5QOn11#QChVq4Hs)~d}*KrAC zx~R3}Eicqbr&`7*FWlZ^&JVX%cc6v*>re}|RwoDjnS-FDm+NqtiA)7q!mKrVyaJJ? z57B3)ir6srKrNw{?;bb}3BOZ0!#A})Q z*G3=~b@0(u%?GS4gi> z?B%z$frrV0!3}WAhn!FZl(kd@{z~Q|s{wYY^?E<8*E3-_9q@LS^{6Ph*X#Xq zda=;!rxLjPzH5ule}Jy9w&-L!s^_y2fu5f>BBX{+uq9#d-%-DZohJ;i+}-bIq2Heg z+KpNLelP3@=npXTFwX(d=_)=4Kn`Bx_wdmr(6G_gKty`uhKDzGB%y3QFC!eps(^Ka z-C|EarJJ@Zpre>d3ENba4;>?r!AEwWVD{&TPcp{tRU_LYphDsFRC*DSN|$4oKx&)( zNSW&RLcZ==9s}Lb@R+T{4#TE_oq8}ehQi1y<{zM3N zKn*_sRA_kQVZlPfc!m!q720-opwQk8M55&&)4}2vxgY2R8rD__P)D>Q? z4+J0z9ok|OJ>x_GJg5rF!*wJ89!_t}Iuigds_9;HG+b)yA1>}|@{~@##Y=#H0%sq^ zj}86lVEJ%{KFW$6?V&?EQgu%09P&ndfm!Jvy27u9)u+6o`vAkLYk^;l&=(Z?3Qc)D z2b;rW)${tkk+A@Xdt79Pt4;V*3XkY6yuH4EJQ%qaKRRavvE_BU@MN!mjuRN`f{{Q? zrQUxg%2Cy3VwPdM%GQ184(Kr)n%&ay6G@JE?vReCaR;M4+s?3!gAgr+o>^Q(%0O()^y#;`ubpLKX zcz_NS+#kLu1;4ubi+b>IZR6V>`Kb?~*Y6JxQZTn2uL3~!=?;!Af}(1&G><5Kki}G_ zulFY@c@6ivZb3TH)LtmKfa#&Po&{bGn7E}auYWt~M1;S}PRGM`7pIdEy+}{qfvFzR z0v?{}4M|U($dLDt3q-|nY13`W6z3i?6^`4H9h3O}=^$|eZCL#PP5YpLcOHzVkKs8E0fm_N*?If*i5KX+z$^{6%aNE@xN``EZ=w?l{+|I7F0j*o8Q#*!4uARhoi}yT}#Ipy-n{0{=&QbBM{^n-}C0pU&YdWiD#W#(n^7 z2U2-}u~OytMHc9C)L|C<9_AaZ`4H;?alXQ~p~DS`euYgA3b9LEq_A>@J<9PmE9@JL zeNtghGNz;ZP`sznLWt87VVxRDgEf#;~+;@o|a!8r`CE^9fWPX<`Oy+mFc$xin zat@b^pE7o}!hX)!5{3Og^x0xDvy}3?T>Or)=NP+EyusMz=*Y9g`^29ZtBDe}Tl`go zQL5jerLGk37ykgyqJfLOnrN-K1hBT?GQhLTt_19h>;~Lcel6hL1?2nn;_CtLWmuw< z`-}pDZx!DJc!5Q*BSMr{D+uo9xT^w`!k^(b#ckU4fHwgm$MO#WzEE)s;JuMM0AnWQ z{$n47e_xp3Gx}YCcj})2T;}-<;J-Yd1Dsg+AmE1zz67{}W1XK*aj)UB&DJTe>BV0K z>@2?wusT5S>&1@&-plZe0&-KyO)j}9{#8npg*w4o0|Z~KAh@0>_cP_UWfcB$)YKF= zGJHJz4Y+^B@CV^1;eH_eG++tGqH>zzvtg?BhC(XUio!WK*frj>52bw|^c-MM`3rzy zi+m-|mq#c}H1HbevPEPo+@$>i6q(xM(qAL|>!rU3++Fe~z}eBi!}pUV#J9_t=WgDv zET`6#JeTc7`FtD0-!qK(i05&J z_cJ_^;nfVk$zjf9cu7eKQkYswa7l3#P}cDoeKg#6>SF=V^Na_)%X2*7TY4R!Y|V=` ziuE=BZf{VWYt@@UaZR+uoTA+zW&*ATG|lt1YrSg+*J&36wlUlRXww@CPBhmJ&aODo z9LusjR@}pK@=sr*IbGyy3(N@m!6H{WuW>pAcWAGHw-;4BiJIOWI?c>>KkcI1?v*ig zFL9aG7KYLjEebmy9ZwVO3cFuF9T(yDD(u_9JmOh}U8!%tMW6h!0)LlT9|7hS3lvuG zX+;?>RMQuf2p4l^JYk)a?i16B;1<=JCx%oGLU zN8=e2_hMWr5ck4zK}cXb%mVQ^>=)8=K{I6*iABc~_5pET^a8ZTZ4NeQhQuoh3zuDC zmWY`XWyo;ZHD;;Usj$+5513J5)kwe6g1u&$=vLU9)}1B{rCRCtru7MPl-RDYkCuMU z94)@$U=NvN#BUV#<lcZ~8N1B#m=6Q{lf=Y})-%AS!zxB9R(|9hjNm6JtRhkj>=cE?%7wN> ztWenT7-W}-7KMGkaGvi}u~}iiE^G$Yp|F(|r}~zPa~1Y{@d{vl3j0m*YGChC*p7hE zmWitrb^&%Nmx=2Y_IO2$Z@Kue!oFMa5wTp{sjv@3Hu_eGPbuu9k&lWM;sJ#{iBhi= z4=d~^DD_J5gu)ui&k?7IXBF01UJUF#S4&RZs7FG9tfE~Y8$2N6x2E>2Qdb!4frRxFYj($vISakqn&>Su`J zYbcdnqOahGVx9P>!u}Z9?prT@^nU5r3BL{Ezpf?hGC}QrrkJ~jF`O@Z7}x@Z%`i%V zEmPQO@Y^U(SJ*l5+bGUb*q7mVme{JW=iqmiNGR<0@Y^KLSD4>h3T#ke>%0$(&Eg7$ zrQo+&>`~a);nyl|R@h7MYZZ4WY#jWyh)*c&B=~I+pI6v!__c{IE9`FgwTZ_S_Fj~w zT|A|*+fdGS@tnfG>Umhi#Y+nNj;9pZFBNvb-sRgWV%JG7eH+*|(W0;`^&a1Lajn8W z0<1%PLt)fnXN#v5HYaj{?`-jk#8@WI5&w0)O!F+ypzjRD7}$W5reSd&lPhO_AT`3b4l&sZ_`=a(4->1bt8N1A)e*0NrJVkz&S=4VoD+&~LeTmTS6{QOMruLxk zUNKr>q^0f^;}u3)>RvHPVc#$Oitj!#U17g2d=%Kp3M1X~IdO`@NcVhBtW+53p3jRG zg^}+0yl7Pz>7M&Vhr&qr+%J*}BmMG#xIkf~Umg&bD2(*rgW`P(BR%+FhVJ=-xIy`m z?)ie!J-b-W9ui++zYkdL);E0*iOQ#$OX8S7F`A^^!JhJcQ9Ld&YXJJ}%i<}8U4=Bi zES_U*PuWYMo5feetJ05i_=@~k(TsSHWyE_t zBi<7k@t(+t_sxuWPiDmXc1FB!XT*CdBi?s1;(ae8-uE)%?aPSwePMowxyyWcP82#= zv3O2I9jwXw12L8{$(J8xxg~e{e90_s5KQ ze{%fxS-yN&_IvBVv( z5|JlDh)0F7TLs2HW3p9z4o2Ly9E?hxmk}@D@uOBLbTEons%pcq7GQ4$Uhv|hZR>HDmedv_aIW>ZII-8k7(59Tq6oNM8WTp_bDY7KbVGYP5mK0EVin;v1 z05^2;L9FF^#59iOuEjN6qcb>s2iN^oOwDMGhhmMyt@zC0-R`%Lqn(a)FT~Qb&hI<) zVD$y-?LyKGnIo6&@LFwXEZKs~U9Cwkd)LH`45fQ$tbZrP-3rYiD%)+`Qa1s5u=+*( z*#PLp`pr?_Y;N3$tq&cmbi^y-n}HQa;uZ0Y*5L$RPM^)U!_^6&KrWgfsEc{r)1{oa z>EA4(Fg4tp8d#p+jlMTSd+1^#*O&B$CZzV*1O4C;qal4M>JQt}U+<{IW9 zL0ud;r0hEcbA^;GbvBoo-om7DE#ApG{s6p!PA;Lm(rype!Wfo^w{rOlcuYyV4;G6! zqi3XfH*1pR%sqm-8V8RA-7jd}A_$1RGQa@dQ$(wb^$ce*Y-G5Y;b{!lF>D1a#eO7( zKbP02Zid?wr)f;l{^1`d`n1nsS?*lzz4_x1hJ3Ho^n!D6dT4tzA@+&+73YhawJR$w z1YGWakGNgCy6_5ww8LD3uTA~Ie*?ptF;k@!c8NC3es+mw%<*;!n$7JJG;iA_K8D%i zE^#B^7g2_L;GSrH7O=PQVZgPRLG2R#n1%OoI(_1k(MQF7VvPSO@u>Do|1+T97X2Y$ z47TNy8l`g&LjF|j{;vHZx)U(3;3B|gjof#Iuh#ZxCl|nQ z*1IZh(RPVBT$h`XOQSZq_yKL7AWIr`)CJ%c{i~W^zpvs6%BA4@obt;IHGP-(O2DU= z>(nlq*ywp)dnj6pTw;2gr&Zq>+J!Wq3|-+V5qrx%DE~cZkspR88jW1eMr{L1`>L#+b~)s2mpBpAialB)da^b}Z`S_+ncs(gagz6W<`2PQL9mG_OT2yJ>U^Qi(oQKk z(>qIhE7az-#4B1i;Okm1;4ifc0RO<0KQX0PC*KmCe9QC;yfKjyz1~TfFz74 zX4uMbkl`+dw=uk(;Uf$mW%vq1QNU$mIFI3GhOG>DF}$7OqYPhR_$otD$Z;9YW4M{& zAVaN~eJcpgW5|XATD?LvVl957co2KfhE}eP*BZ5z+8J86cByuqb~kjy>)KMiTfa)b zPv58eJo%pSo<*K+&tsk!Jg9PeoXd`906c&FY8c%G*l z@Gege;9L4mjE|d6L588F5ud7 zqWr#a9^jgaX23rbF9y6QK=kidECc*_WEJ3R9J0BbVtv+6aDRltoE$j=aE?J~CKx`? zu)s@{^BKO%a6ZFNF}#z*JmaA-G6k9bO(m4(x3x0??XqowduVxNNn~kddA3{I5b{AT z+o>g;aBnW_2E3!V7cf+K0pLl67rWr4?7q~pU=z{_1p|;c>A_D2w7^pXbd!DRfmz@# z@z?^?p%Z)vITg^tNhJ&P0HBT&XMWJ9Gi@#Z%9Dus$1Q#{215n2f(G0jR2h_zC;FgZ_Aaek( z0w-|#0#FxMqxLw(0jT42StH!<2h_#2s4+$%KwVsi8f)TuKpmSLr@(z9ppNZ`#c!E>AUH|&{7Yr8 zSZ>|?h zJ5oJ(tVt~H>Y36Yni{6hpE9kvxqj;Wg)^p2Z>pcsJh^dlQ{()`X_M#AoLoP3#;nOx zr!JT=W9pPy3#Uz=Hlu0QGca5rp>5F#HMM@3+ty$Z<@Sddh_(jv!+j-GJjU%%*ivR&Tnd*y0Cu!)Ty#0)9HCS zic~*c67bx#X?0I)Pe)s0GTGXb;kwq6C0*YCsv5L%M$Iqo$-^z+?C0W z^H9IVJGwjLJ5YDTOLQ%W_q29&rcM%Vt(|SXo$zm3)g-pXdp0$$Zd$xptnN$o#CJ?u zyh0$IExoBVO)Hh_^aZwS)tb}Ad99tj@lBgVXQJ(#mB~a~Je67%Z;N-F7jIwC+S4jh z@h<5|N-7gq_au_>rHO5fG$rH6-NvW{GDn-TgY&nsc1mF}$_nKsQIK@6$Smj(x(p0~$x5&(;i6HXMTyRK@NX5k z4Mrui!w=_8ZL%_v?6H$iW#N?cs(7k9k%}*fceeJ~;S^(Yd7;C^lO&elKPA7gw~NK2 zDbXIUU(k_i-O>pk$|$!_cASP`C!&gai$KNQQ9XvPW`lD zBe}e?V+|iE?UNm+e){k^rM;+^ecZcgzza4<(=4ie01?*oS$VK7G$ z4xC!L?GGHzY3>6DOSk=j!#Qm_G?+bzuZrVNKs+@xz?zP>b8?XFc#ag)MS6f_k*p96(#UkQ6+v43c3Xz%-@nkZQWY_9A zjZPTZ;z%r&YTXtWO^F@dt;u-v&Nf!QG*T_@IxlffT#i-BO`W3gJdD+(uf$^XBPc<3 zqgLm|lRb{AU6WXl=%qlbdNE$@h_iSuYVB$ViBn1Sb+w(*+R>wEYZ9v=#FS`iZ2}fR z2b@SVmB90qc+c|I9WovXKO@8?2Wd>D;ybo<_Bp{8B7PUe;m&F!lrhF8^2`X3P1|Zm zfMEhgt!?e>XqR@t!Xzb%&KX~WN(rjKiY`2p9k3cY-~u1F&=YZb<75ZfCJQ;G^}tlN zI?&m{z^)Xcbz(3PlAm$0vNZ{eiax)!w|y0I6I*P@vffUZTCJ%b3_bB}I9)q$Fsc`#8Yj_ z4wm?|=YsgwR`6^Y1SFnJlVt@tp;Z{fcd{#$_P5i79ogR7)-%+jDbd}R?AW$Frx!X? zS6@1g>I9T0^4ZeS2@5XmyCy;1T(%0k+PUkn2*H-^+9q9FI}@!Wi@ns{mE$}{m9~I5 zv9a3-)8ahzJht;#JXC=By<4}&lVq8Tg&kdxYB*M++u3HTv?Gbo+|`yK(@8*1yQP`w z3a6?wX)SCjGz9q!?f>%16m?$Z8X9CN>L%JroW#<^`HR3zv8=UcI~RFrylWerDZY56 z5cFxHHInXVYVGXYf}s!9Y;AXt#x~M;YudV{a&_pKSjf<%i;|c>@PI6OlC52-R<^_z zw_`Tav9%+fWLpi~k-b`~B{D5V8v)7H#?DUB+?wi>T47Q5g zdAx^28mx%7?odo27wSh3>Y$4;$Kn3V4msyRL-g(t9o>y`3b43KbVC8+0hviaH@3os z8m)%7$uv?cy5n6ucf?~!qC=8ZL)q<&!c0;HTHLiYk=((;Z~NM`5w(X+a@ zn;75@0hQ*SC1Io@b)8QBG&N%y;z6^)bTCLK&B;-vG_3=qWEz##OyjG`p6^NHjmd4j zG^b5dsBIFxEjGN+Puc-2@~K-tc7+B7{q1GH(w%<^pS9J4jsi;AO4 z)^5{!+PZD0vhJeayD)az^>W(LZl@~E5=ZUKRAKowcj4UrD^qx$g7fomaM3zLZ*($$Q0pU#vV z>u8ljHY?kLSV*HXri5KNiP2(%bhWXsn_p>>a>ugu9}3>;jBJiBa~g?0I8H<`-CYvSc9MTjTva`D-FWLiD<;usFNKCiq$Knmb2la0Gtsmpip482Hum(|)nF$|fz@)ckWCm{1RR-Ili=1B zWG=4QayCYHk&q9}ZdC>3^wvhGFwzdN%L@Jp$v=_Ux)n?ltGi*ni{_mG#4RJbhnmSS?eN)l<9 zWs7-5ugr`3u`{dU+c`Et2q*Z&kdzvrja3^$EPHf<}t&K9T6&w73h5gZ+GY#a<9#JFu(Li{{pyA2ZN~m)3MYJ)Vb8W5yPUniV%W*-fIA7lB>ZB)y6}VW zfkJ*4VE3~f^sR`M#M2$S4*Rc7xcf&t`HS&vL`ZCAAO@5fc8Oy`3zFYTj@!c&aZ2uT zG;wZm+~s|Hd|L(1oz8q~!p`k7>^r-8 zq-}U7@|10*javb(5ub@mvhLKib z9h%->kwVNEu|oI6(wwyJ!Ej#LUf`A z6txcOr;Vo;=t6Fp z-8D;yPHuwiG~wTNgr;t~5GCy3jx?gynL?76LJJVrsik5_i&BgsH9Jj`x^$|dehqRU zF3Rpa0zS?m$su)|otImh-GkF=)S#6+k*KFwBxABuWe!BPlFH~WCM)@8AM;q*Wx@xHyF;$Iq!*3?O;3O$*W-?`Y-ErzV)jB{&0; zL*plDP%>9ZddQrSeV?R-Od-;OM_}9z)407B{gF)8xE!%Brm{>2y&8x9hARt6x0@qJ zuuM3g3Imc$QJ;e+Bm|w{KnGeUlP@HaM~pM2nVgZ65ixkV?8ZacGqhN_ghm#RhLt1_ zN{4N54Stjg(lDgklKn*^y}RZ9eMOUMf-D=h{l?|83bVr0Q<&^AA#-d>*M(CpwJlq> zeJ9o}08=TQB;A{K=O_N0K5t1dW)a?#O0#r>r%$BIMioC;W1X zhAH&muH5r7Ih&(7l3OxphDcSib+A2yCY%bn1OIG491BFqR#bwXnWkQP{*3wb;O^W- zIC5FrR(=dG^qY*=`cVsaqPUXNa-vUu_3#r_)J@V>nVh+#CpRLRw!z%CnW!V{c@lKs zGQd9dFNT*U&1SaD2IErj*@}PACgq=e&kKQ{KGOKbM<-5t{@K1Kg%Q&<3wlPwH5Dxw zB(#u#ZuvZ+Mf5LE=%K+c%K!PrnrDnC9)nZFWANHsEwqS&Ev0{iEhTIv{UdB8VQc6g zVQY{{p$|7E=ntoegB@NR)*pP@8w1?O@Hwy0*%M{(;5H%`shQzoZ%o%J%S@CkH29L~ z(?jcm^N^w*h#8@Eg;r?ry_KBCt0=r~QJl~^14*Aol_`+%e&z9LI*0nLFQ)5OaPSQz zVflO>YqWQ?*DJKqUc6C2&&R{?X`{&vAFIIUvn&om!9Wbia0PgvjzmG>P*j_YU=w}i@Ry9Iw5XOyZAduFOWY~M z8_FSP)Y`#$Xa`h&v^Nm*gm#Sw0}wwZg1e3GM35K+kz|h~ z^2E@YkTX2i;W4^!v-$)%V;s$u|(HPgM&9BiO`uOVp?Uf?vDwkg@sS~ zL3qQ|JM~J+@MeS##59YYVc~^P!xwT;S>Q8+#i28U9aiYH(O$?i`hjMJ*7<#!N{NcU zo&Hhrw-eS${|M_OtegH3)=gLs{UfZ0u$}aeu$|n6cAZF^YKKp-J=7b-1wk}QCFQ7v zda1kh$zY8rII88d9HA|y7AW=QS3(X$r&*!CP<|+XG(;WmK!F75=$hW3FF@Wz^9I`y zt`}ZDtH_6za1nv4U@{Qe5xo+8;82oQ=<~@i66KUtAC?qOgwvIHi1H3yD07k|)rlp7 z@gY$ILubVog=|tTu)J?nqZ?so8y&yEgyBWX5a4*7dDSj*QTZ7+e z_?-^F4&C%22K`L@D4iC=3=QtKOh-;J4ExpHQV?1_!T3_6u|~0P<$ejf50P8H>XrhD#Z)WVnWz zW|4NO3~fZK<&U;}q;0L>0$@;^zyKKwFb2q20b_uSk$x4>v-t|6c%z{lDV5PyfU$tW z3K%O0F7QEA5r`F@g@MQe+4HHw#L){Oc!Z7CEq+i)6x70a0m$L3(K-T9IsGw%l7b5| zADl5^_A%^c*u!uq)P+WUgF8uK3}R%0>))92 z$2S|M|K+bU{yc5!pXUDaUnjnG@=5#uF?-H`&-(k{W>)|5SI7UlX5#<*-J}zKU-#SJ z)V_Y~_@5p3i=R(8=BKZXdv$E=mD@JA-rn}nJGN}S>*L!#7H_|^^HZPR@!3SzXFhTE zIiKvf=kD!0ANpe7m-{dH(pN9K_-g|Xf91madwL%@{|gVEm;Bu4Q}>Q&c$VC@+W{xzAq`zZfNa0pAd}+}j1%Ejqrpd4TyVv+764g*9npVr1 z=FpTL=P+`!f#6guHcmzY6ZrNpEpgI3Rc@6)sfgv-kcSM{ z&1LCB&2a}0ap;e7KSDdP*cA>TFS`zM$$+-VXferNxTidGPmwcAJ{g)jomS@lGNmyM z)6ePn)#FF}IEn8(Qwzwgwl37M(^b=4c}~J4w-f*9Z$8Ig3SMmEn8dNn-D|;I%%sJz zNHiH`fU3sdM3k8BKig@@)~9U>S`JBK+lN|6{w?JERxo$uPB)d;<{gz@w$Q=KJ)Lib zuS7bubs-mL-0hnyK9yi9^EWeIHkY$`Jd@)z^5mcDv;`%mg`I=NQ&k@R5yShG;QPpl N!v{I)^S_q^{~x;1TBra3 literal 0 HcmV?d00001