/// <summary> /// Sends a Write Multiple Coils (0x10) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="startAddress">Address of the 1st register: 0x0000 .. 0xFFFF</param> /// <param name="registers">Register values to write</param> /// <param name="offset">Offset in register of the 1st register to write</param> /// <param name="count">Number of registers to write</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 WriteMultipleRegisters(byte deviceAddress, ushort startAddress, ushort[] registers, int offset, int count, int timeout = 2000) { if (offset < 0 || offset >= registers.Length) { throw new ArgumentException("offset"); } if (offset + count > registers.Length) { throw new ArgumentException("count"); } object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.WriteMultipleRegisters, (short)(5 + 2 * count), this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, startAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, (ushort)count); this.buffer[dataPos + 4] = (byte)(2 * count); for (var i = 0; i < count; i++) { ModbusUtils.InsertUShort(this.buffer, dataPos + 5 + 2 * i, registers[offset + i]); } this.SendReceive(deviceAddress, ModbusFunctionCode.WriteMultipleRegisters, timeout, telegramLength, 4, telegramContext, ref dataPos); }
/// <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 Read Discrete Inputs (0x02) 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="inputCount">>Number of coils to read: 1 .. 2000</param> /// <param name="timeout">Timeout for response in milli seconds.</param> /// <returns>Returns a byte array which contains the inputs. The inputs are written as single bits into the array starting with coil 1 at the lsb.</returns> /// <remarks> /// Look at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf for more details. /// </remarks> public virtual byte[] ReadDiscreteInputs(byte deviceAddress, ushort startAddress, ushort inputCount, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.ReadDiscreteInputs, 4, this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, startAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, inputCount); var desiredDataLength = (short)(1 + inputCount / 8); if (inputCount % 8 != 0) { ++desiredDataLength; } var dataLength = this.SendReceive(deviceAddress, ModbusFunctionCode.ReadDiscreteInputs, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var coils = new byte[dataLength - 1]; Array.Copy(this.buffer, dataPos + 1, coils, 0, dataLength - 1); return(coils); }
/// <summary> /// Sends a Write Single Register (0x06) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="address">Address of the register: 0x0000 .. 0xFFFF</param> /// <param name="value">Register value to write</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 WriteSingleRegister(byte deviceAddress, ushort address, ushort value, int timeout = 2000) { object telegramContext = null; [email protected](deviceAddress, (byte)ModbusFunctionCode.WriteSingleRegister, 4, this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, address); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, value); this.SendReceive(deviceAddress, ModbusFunctionCode.WriteSingleRegister, timeout, telegramLength, 4, telegramContext, ref dataPos); }
/// <summary> /// Sends a Write Multiple Coils (0x0F) telegram to a device and waits for the response /// </summary> /// <param name="deviceAddress">Address of the modbus device.</param> /// <param name="startAddress">Address of the 1st coil: 0x0000 .. 0xFFFF</param> /// <param name="coilCount">Number of coils to write.</param> /// <param name="coils">Byte array with bit coded coil values.</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 WriteMultipleCoils(byte deviceAddress, ushort startAddress, ushort coilCount, byte[] coils, int timeout = 2000) { object telegramContext = null; var byteCnt = (byte)(coilCount / 8); if ((coilCount % 8) > 0) { byteCnt++; } [email protected](deviceAddress, (byte)ModbusFunctionCode.WriteMultipleCoils, (short)(5 + byteCnt), this.buffer, out var telegramLength, out var dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(this.buffer, dataPos, startAddress); ModbusUtils.InsertUShort(this.buffer, dataPos + 2, coilCount); this.buffer[dataPos + 4] = byteCnt; Array.Copy(coils, 0, this.buffer, dataPos + 5, byteCnt); this.SendReceive(deviceAddress, ModbusFunctionCode.WriteMultipleCoils, timeout, telegramLength, 4, telegramContext, ref dataPos); }