/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.Diagnostics, (short)(2 + 2 * data.Length), _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, subFunction); for (int n = 0; n < data.Length; ++n) { ModbusUtils.InsertUShort(_Buffer, dataPos + 2 + 2 * n, data[n]); } var dataLength = 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 (int n = 0; n < data.Length; ++n) { data[n] = ModbusUtils.ExtractUShort(_Buffer, dataPos + 2 + 2 * n); } return(data); }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.ReadWriteMultipleRegisters, (short)(9 + 2 * writeRegisters.Length), _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, readStartAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, readCount); ModbusUtils.InsertUShort(_Buffer, dataPos + 4, writeStartAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 6, (ushort)writeRegisters.Length); _Buffer[dataPos + 8] = (byte)(2 * writeRegisters.Length); for (int i = 0; i < writeRegisters.Length; i++) { ModbusUtils.InsertUShort(_Buffer, dataPos + 9 + 2 * i, writeRegisters[i]); } 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 (int n = 0; n < readRegisters.Length; ++n) { readRegisters[n] = ModbusUtils.ExtractUShort(_Buffer, dataPos + 1 + 2 * n); } return(readRegisters); }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.ReadInputRegisters, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, registerCount); short desiredDataLength = (short)(1 + 2 * registerCount); var dataLength = SendReceive(deviceAddress, ModbusFunctionCode.ReadInputRegisters, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var registers = new ushort[(dataLength - 1) / 2]; for (int n = 0; n < registers.Length; ++n) { registers[n] = ModbusUtils.ExtractUShort(_Buffer, dataPos + 1 + 2 * n); } return(registers); }
private void ReadInputRegisters(IModbusInterface intf, bool isBroadcast, object telegramContext, ModbusFunctionCode fc, short dataPos, short dataLength) { if (dataLength < 4) { SendErrorResult(intf, isBroadcast, _deviceAddress, telegramContext, fc, ModbusErrorCode.IllegalDataValue); } else { ushort startAddress = ModbusUtils.ExtractUShort(_buffer, dataPos); ushort registerCount = ModbusUtils.ExtractUShort(_buffer, dataPos + 2); ushort[] registers = new ushort[registerCount]; var err = OnReadInputRegisters(isBroadcast, startAddress, registers); if (isBroadcast) { return; } if (err != ModbusErrorCode.NoError) { SendErrorResult(intf, false, _deviceAddress, telegramContext, fc, err); } else { short telegramLength; intf.CreateTelegram(_deviceAddress, (byte)fc, (short)(1 + 2 * registers.Length), _buffer, out telegramLength, out dataPos, true, ref telegramContext); _buffer[dataPos] = (byte)(2 * registers.Length); for (int i = 0; i < registerCount; i++) { ModbusUtils.InsertUShort(_buffer, dataPos + 1 + 2 * i, registers[i]); } intf.SendTelegram(_buffer, telegramLength); } } }
private void WriteSingleRegister(IModbusInterface intf, bool isBroadcast, object telegramContext, ModbusFunctionCode fc, short dataPos, short dataLength) { if (dataLength < 4) { SendErrorResult(intf, isBroadcast, _deviceAddress, telegramContext, fc, ModbusErrorCode.IllegalDataValue); } else { ushort address = ModbusUtils.ExtractUShort(_buffer, dataPos); ushort value = ModbusUtils.ExtractUShort(_buffer, dataPos + 2); var err = OnWriteSingleRegister(isBroadcast, address, value); if (isBroadcast) { return; } if (err != ModbusErrorCode.NoError) { SendErrorResult(intf, false, _deviceAddress, telegramContext, fc, err); } else { short telegramLength; intf.CreateTelegram(_deviceAddress, (byte)fc, 4, _buffer, out telegramLength, out dataPos, true, ref telegramContext); ModbusUtils.InsertUShort(_buffer, dataPos, address); ModbusUtils.InsertUShort(_buffer, dataPos + 2, value); intf.SendTelegram(_buffer, telegramLength); } } }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.ReadDiscreteInputs, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, inputCount); short desiredDataLength = (short)(1 + inputCount / 8); if (inputCount % 8 != 0) { ++desiredDataLength; } var dataLength = SendReceive(deviceAddress, ModbusFunctionCode.ReadDiscreteInputs, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var coils = new byte[dataLength - 1]; Array.Copy(_Buffer, dataPos + 1, coils, 0, dataLength - 1); return(coils); }
private void WriteMultipleCoils(IModbusInterface intf, bool isBroadcast, object telegramContext, ModbusFunctionCode fc, short dataPos, short dataLength) { if (dataLength < 5) { SendErrorResult(intf, isBroadcast, _deviceAddress, telegramContext, fc, ModbusErrorCode.IllegalDataValue); } else { ushort startAddress = ModbusUtils.ExtractUShort(_buffer, dataPos); ushort outputCount = ModbusUtils.ExtractUShort(_buffer, dataPos + 2); byte byteCount = _buffer[dataPos + 4]; byte[] values = new byte[byteCount]; Array.Copy(_buffer, dataPos + 5, values, 0, values.Length); var err = OnWriteMultipleCoils(isBroadcast, startAddress, outputCount, values); if (isBroadcast) { return; } if (err != ModbusErrorCode.NoError) { SendErrorResult(intf, false, _deviceAddress, telegramContext, fc, err); } else { short telegramLength; intf.CreateTelegram(_deviceAddress, (byte)fc, 4, _buffer, out telegramLength, out dataPos, true, ref telegramContext); ModbusUtils.InsertUShort(_buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_buffer, dataPos + 2, outputCount); intf.SendTelegram(_buffer, telegramLength); } } }
/// <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"); } short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.WriteMultipleRegisters, (short)(5 + 2 * count), _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, (ushort)count); _Buffer[dataPos + 4] = (byte)(2 * count); for (int i = 0; i < count; i++) { ModbusUtils.InsertUShort(_Buffer, dataPos + 5 + 2 * i, registers[offset + i]); } SendReceive(deviceAddress, ModbusFunctionCode.WriteMultipleRegisters, timeout, telegramLength, 4, telegramContext, ref dataPos); }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.GetCommEventLog, 0, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); 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 = _Buffer[dataPos]; status = ModbusUtils.ExtractUShort(_Buffer, dataPos + 1); eventCount = ModbusUtils.ExtractUShort(_Buffer, dataPos + 3); messageCount = ModbusUtils.ExtractUShort(_Buffer, dataPos + 5); events = new byte[byteCnt - 6]; Array.Copy(_Buffer, dataPos + 7, events, 0, events.Length); }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.WriteSingleRegister, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, address); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, value); SendReceive(deviceAddress, ModbusFunctionCode.WriteSingleRegister, timeout, telegramLength, 4, telegramContext, ref dataPos); }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.GetCommEventCounter, 0, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); SendReceive(deviceAddress, ModbusFunctionCode.GetCommEventCounter, timeout, telegramLength, 4, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { status = 0; eventCount = 0; return; } status = ModbusUtils.ExtractUShort(_Buffer, dataPos); eventCount = ModbusUtils.ExtractUShort(_Buffer, dataPos + 2); }
/// <summary> /// Sends a Read Coils (0x01) 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="coilCount">>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 coils. The coils 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[] ReadCoils(byte deviceAddress, ushort startAddress, ushort coilCount, int timeout = 2000) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.ReadCoils, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, coilCount); short desiredDataLength = (short)(1 + coilCount / 8); if (coilCount % 8 != 0) { ++desiredDataLength; } var dataLength = SendReceive(deviceAddress, ModbusFunctionCode.ReadCoils, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var coils = new byte[dataLength - 1]; Array.Copy(_Buffer, dataPos + 1, coils, 0, dataLength - 1); // Send data to whom ever interested string displayString = "<-- " + HexEncoding.ToString(_Buffer, 0, dataLength + 4) + "\r\n"; if (NewSerialDataRecieved != null) { NewSerialDataRecieved(this, new ReceivedDataEventArgs(displayString)); } //********************************* return(coils); }
/// <summary> /// Sends a Write Single Coils (0x05) 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 coil: 0x0000 .. 0xFFFF</param> /// <param name="value">0xFF00 for true or 0x0000 for false</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 WriteSingleCoil(byte deviceAddress, ushort address, ushort value, int timeout = 2000) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.WriteSingleCoil, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, address); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, value); SendReceive(deviceAddress, ModbusFunctionCode.WriteSingleCoil, timeout, telegramLength, 4, telegramContext, ref dataPos); // Send data to whom ever interested string displayString = "<-- " + HexEncoding.ToString(_Buffer, 0, telegramLength) + "\r\n"; if (NewSerialDataRecieved != null) { NewSerialDataRecieved(this, new ReceivedDataEventArgs(displayString)); } //********************************* }
private void ReadDiscreteInputs(IModbusInterface intf, bool isBroadcast, object telegramContext, ModbusFunctionCode fc, short dataPos, short dataLength) { if (dataLength < 4) { SendErrorResult(intf, isBroadcast, _deviceAddress, telegramContext, fc, ModbusErrorCode.IllegalDataValue); } else { ushort startAddress = ModbusUtils.ExtractUShort(_buffer, dataPos); ushort inputCount = ModbusUtils.ExtractUShort(_buffer, dataPos + 2); byte[] inputs; if (inputCount % 8 == 0) { inputs = new byte[inputCount / 8]; } else { inputs = new byte[inputCount / 8 + 1]; inputs[inputs.Length - 1] = 0; } var err = OnReadDiscreteInputs(isBroadcast, startAddress, inputCount, inputs); if (isBroadcast) { return; } if (err != ModbusErrorCode.NoError) { SendErrorResult(intf, false, _deviceAddress, telegramContext, fc, err); } else { short telegramLength; intf.CreateTelegram(_deviceAddress, (byte)fc, (short)(1 + inputs.Length), _buffer, out telegramLength, out dataPos, true, ref telegramContext); _buffer[dataPos] = (byte)(inputs.Length); Array.Copy(inputs, 0, _buffer, dataPos + 1, inputs.Length); intf.SendTelegram(_buffer, telegramLength); } } }
/// <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) { short telegramLength; short dataPos; object telegramContext = null; byte byteCnt = (byte)(coilCount / 8); if ((coilCount % 8) > 0) { byteCnt++; } _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.WriteMultipleCoils, (short)(5 + byteCnt), _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, coilCount); _Buffer[dataPos + 4] = byteCnt; Array.Copy(coils, 0, _Buffer, dataPos + 5, byteCnt); SendReceive(deviceAddress, ModbusFunctionCode.WriteMultipleCoils, timeout, telegramLength, 4, telegramContext, ref dataPos); }
/// <summary> /// Sends a Read Holding Registers (0x03) 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[] ReadHoldingRegisters(byte deviceAddress, ushort startAddress, ushort registerCount, int timeout = 2000) { short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.ReadHoldingRegisters, 4, _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, registerCount); short desiredDataLength = (short)(1 + 2 * registerCount); var dataLength = SendReceive(deviceAddress, ModbusFunctionCode.ReadHoldingRegisters, timeout, telegramLength, desiredDataLength, telegramContext, ref dataPos); if (deviceAddress == ModbusConst.BroadcastAddress) { return(null); } var registers = new ushort[(dataLength - 1) / 2]; for (int n = 0; n < registers.Length; ++n) { registers[n] = ModbusUtils.ExtractUShort(_Buffer, dataPos + 1 + 2 * n); } // Send data to whom ever interested string displayString = "<-- " + HexEncoding.ToString(_Buffer, 0, dataLength + 4) + "\r\n"; if (NewSerialDataRecieved != null) { NewSerialDataRecieved(this, new ReceivedDataEventArgs(displayString)); } //* return(registers); }
private void WriteMultipleRegisters(IModbusInterface intf, bool isBroadcast, object telegramContext, ModbusFunctionCode fc, short dataPos, short dataLength) { if (dataLength < 5) { SendErrorResult(intf, isBroadcast, _deviceAddress, telegramContext, fc, ModbusErrorCode.IllegalDataValue); } else { ushort startAddress = ModbusUtils.ExtractUShort(_buffer, dataPos); ushort registerCount = ModbusUtils.ExtractUShort(_buffer, dataPos + 2); //byte byteCount = _Buffer[dataPos + 4]; ushort[] registers = new ushort[registerCount]; for (int i = 0; i < registerCount; i++) { registers[i] = ModbusUtils.ExtractUShort(_buffer, dataPos + 5 + 2 * i); } var err = OnWriteMultipleRegisters(isBroadcast, startAddress, registers); if (isBroadcast) { return; } if (err != ModbusErrorCode.NoError) { SendErrorResult(intf, false, _deviceAddress, telegramContext, fc, err); } else { short telegramLength; intf.CreateTelegram(_deviceAddress, (byte)fc, 4, _buffer, out telegramLength, out dataPos, true, ref telegramContext); ModbusUtils.InsertUShort(_buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_buffer, dataPos + 2, registerCount); intf.SendTelegram(_buffer, telegramLength); } } }
/// <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"); } short telegramLength; short dataPos; object telegramContext = null; _Interface.CreateTelegram(deviceAddress, (byte)ModbusFunctionCode.WriteMultipleRegisters, (short)(5 + 2 * count), _Buffer, out telegramLength, out dataPos, false, ref telegramContext); ModbusUtils.InsertUShort(_Buffer, dataPos, startAddress); ModbusUtils.InsertUShort(_Buffer, dataPos + 2, (ushort)count); _Buffer[dataPos + 4] = (byte)(2 * count); for (int i = 0; i < count; i++) { ModbusUtils.InsertUShort(_Buffer, dataPos + 5 + 2 * i, registers[offset + i]); } SendReceive(deviceAddress, ModbusFunctionCode.WriteMultipleRegisters, timeout, telegramLength, 4, telegramContext, ref dataPos); // Send data to whom ever interested string displayString = "<-- " + HexEncoding.ToString(_Buffer, 0, 8) + "\r\n"; if (NewSerialDataRecieved != null) { NewSerialDataRecieved(this, new ReceivedDataEventArgs(displayString)); } //****** }