/// <summary> /// Sends a Read Write Multiple Coils (0x17) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="writeStartAddress">Address of the 1st write register: 0x0000 .. 0xFFFF</param> /// <param name="writeRegisters">Register values to write</param> /// <param name="readStartAddress">Address of the 1st read register: 0x0000 .. 0xFFFF</param> /// <param name="readCount">Number of registers to read</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <returns>Returns a unsigned short array with the register values.</returns> /// <remarks> /// The write operation is performed before the read operation. /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual ushort[] ReadWriteMultipleRegisters(byte deviceAddress, ushort writeStartAddress, ushort[] writeRegisters, ushort readStartAddress, ushort readCount, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.ReadWriteMultipleRegisters, (short)(9 + 2 * writeRegisters.Length), this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, readStartAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, readCount); ModbusUtils.InsertUShort(this.buffer, dataPos + 4, writeStartAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 6, (ushort)writeRegisters.Length); this.buffer[dataPos + 8] = (byte)(2 * writeRegisters.Length); for (var i = 0; i < writeRegisters.Length; i++) { ModbusUtils.InsertUShort(this.buffer, dataPos + 9 + 2 * i, writeRegisters[i]); } this.SendReceive(deviceAddress, ModbusFunctionCode.ReadWriteMultipleRegisters, timeout, telegramLength, (short)(1 + 2 * readCount), telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var readRegisters = new ushort[readCount]; for (var n = 0; n < readRegisters.Length; ++n) { readRegisters[n] = ModbusUtils.ExtractUShort(this.buffer, dataPos + 1 + 2 * n); } return(readRegisters); }
/// <summary> /// Sends a Diagnostics (0x08) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="subFunction">Sub function code.</param> /// <param name="data">Data</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <returns>Returns a unsigned short array with diagnostic data.</returns> /// <remarks> /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual ushort[] Diagnostics(byte deviceAddress, ushort subFunction, ushort[] data, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.Diagnostics, (short)(2 + 2 * data.Length), this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, subFunction); for (var n = 0; n < data.Length; ++n) { ModbusUtils.InsertUShort(this.buffer, dataPos + 2 + 2 * n, data[n]); } var dataLength = this.SendReceive(deviceAddress, ModbusFunctionCode.Diagnostics, timeout, telegramLength, (short)(2 + 2 * data.Length), telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } data = new ushort[(dataLength - 2) / 2]; for (var n = 0; n < data.Length; ++n) { data[n] = ModbusUtils.ExtractUShort(this.buffer, dataPos + 2 + 2 * n); } return(data); }
/// <summary> /// Sends a Read Input Registers (0x04) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="startAddress">Start address: 0x0000 .. 0xFFFF</param> /// <param name="registerCount">Number of the registers to read.</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <returns>Returns an array of 16 bit register values.</returns> /// <remarks> /// A register is a 16 bit unsigned value. /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual ushort[] ReadInputRegisters(byte deviceAddress, ushort startAddress, ushort registerCount, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.ReadInputRegisters, 4, this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, startAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, registerCount); var desiredDataLength = (short)(1 + 2 * registerCount); var dataLength = this.SendReceive(deviceAddress, ModbusFunctionCode.ReadInputRegisters, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var registers = new ushort[(dataLength - 1) / 2]; for (var n = 0; n < registers.Length; ++n) { registers[n] = ModbusUtils.ExtractUShort(this.buffer, dataPos + 1 + 2 * n); } return(registers); }
/// <summary> /// Sends a Get Comm Event Counter (0x0B) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="status">Receives the status word of the device.</param> /// <param name="eventCount">Receives the event counter of the device.</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <remarks> /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual void GetCommEventCounter(byte deviceAddress, out ushort status, out ushort eventCount, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.GetCommEventCounter, 0, this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); this.SendReceive(deviceAddress, ModbusFunctionCode.GetCommEventCounter, timeout, telegramLength, 4, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { status = 0; eventCount = 0; return; } status = ModbusUtils.ExtractUShort(this.buffer, dataPos); eventCount = ModbusUtils.ExtractUShort(this.buffer, dataPos + 2); }
/// <summary> /// Sends a Get Comm Event Log (0x0C) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="status">Receives the status word of the device.</param> /// <param name="eventCount">Receives the event counter of the device.</param> /// <param name="messageCount">Receives the event message count.</param> /// <param name="events">Receives 0 - 64 bytes, with each byte corresponding to the status of one MODBUS send or receive operation for the remote device. /// Byte 0 is the most recent.</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <remarks> /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual void GetCommEventLog(byte deviceAddress, out ushort status, out ushort eventCount, out ushort messageCount, out byte[] events, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.GetCommEventLog, 0, this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); this.SendReceive(deviceAddress, ModbusFunctionCode.GetCommEventLog, timeout, telegramLength, -1, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { status = 0; eventCount = 0; messageCount = 0; events = null; return; } var byteCnt = this.buffer[dataPos]; status = ModbusUtils.ExtractUShort(this.buffer, dataPos + 1); eventCount = ModbusUtils.ExtractUShort(this.buffer, dataPos + 3); messageCount = ModbusUtils.ExtractUShort(this.buffer, dataPos + 5); events = new byte[byteCnt - 6]; Array.Copy(this.buffer, dataPos + 7, events, 0, events.Length); }