/// <summary> /// Reads the specified number of values of type <typeparamref name="TRead"/> from and writes the provided array of type <typeparamref name="TWrite"/> to the holding registers. The write operation is performed before the read. /// </summary> /// <typeparam name="TRead">Determines the type of the returned data.</typeparam> /// <typeparam name="TWrite">Determines the type of the provided data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="readStartingAddress">The holding register start address for the read operation.</param> /// <param name="readCount">The number of elements of type <typeparamref name="TRead"/> to read.</param> /// <param name="writeStartingAddress">The holding register start address for the write operation.</param> /// <param name="dataset">The data of type <typeparamref name="TWrite"/> to write to the server.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param> public async Task <Memory <TRead> > ReadWriteMultipleRegistersAsync <TRead, TWrite>(int unitIdentifier, int readStartingAddress, int readCount, int writeStartingAddress, TWrite[] dataset, CancellationToken cancellationToken = default) where TRead : unmanaged where TWrite : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var readStartingAddress_converted = this.ConvertUshort(readStartingAddress); var readCount_converted = this.ConvertUshort(readCount); var writeStartingAddress_converted = this.ConvertUshort(writeStartingAddress); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset.AsSpan()); } var readQuantity = this.ConvertSize <TRead>(readCount_converted); var byteData = MemoryMarshal.Cast <TWrite, byte>(dataset).ToArray(); var dataset2 = SpanExtensions.Cast <byte, TRead>(await this.ReadWriteMultipleRegistersAsync(unitIdentifier_converted, readStartingAddress_converted, readQuantity, writeStartingAddress_converted, byteData).ConfigureAwait(false)); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset2); } return(dataset2); }
/// <summary> /// Reads the specified number of values of type <typeparamref name="TRead"/> from and writes the provided array of type <typeparamref name="TWrite"/> to the holding registers. The write operation is performed before the read. /// </summary> /// <typeparam name="TRead">Determines the type of the returned data.</typeparam> /// <typeparam name="TWrite">Determines the type of the provided data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="readStartingAddress">The holding register start address for the read operation.</param> /// <param name="readCount">The number of elements of type <typeparamref name="TRead"/> to read.</param> /// <param name="writeStartingAddress">The holding register start address for the write operation.</param> /// <param name="dataset">The data of type <typeparamref name="TWrite"/> to write to the server.</param> public Span <TRead> ReadWriteMultipleRegisters <TRead, TWrite>(int unitIdentifier, int readStartingAddress, int readCount, int writeStartingAddress, TWrite[] dataset) where TRead : unmanaged where TWrite : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var readStartingAddress_converted = this.ConvertUshort(readStartingAddress); var readCount_converted = this.ConvertUshort(readCount); var writeStartingAddress_converted = this.ConvertUshort(writeStartingAddress); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset.AsSpan()); } var readQuantity = this.ConvertSize <TRead>(readCount_converted); var byteData = MemoryMarshal.Cast <TWrite, byte>(dataset).ToArray(); var dataset2 = MemoryMarshal.Cast <byte, TRead>(this.ReadWriteMultipleRegisters(unitIdentifier_converted, readStartingAddress_converted, readQuantity, writeStartingAddress_converted, byteData)); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset2); } return(dataset2); }
public static T SwitchEndianness <T>(T value) where T : unmanaged { Span <T> data = stackalloc T[] { value }; ModbusUtils.SwitchEndianness(data); return(data[0]); }
public static T SwitchEndianness <T>(T value) where T : unmanaged { var data = new T[] { value }; ModbusUtils.SwitchEndianness(data.AsSpan()); return(data[0]); }
/// <summary> /// Writes the provided <paramref name="value"/> to the holding registers. /// </summary> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="registerAddress">The holding register address for the write operation.</param> /// <param name="value">The value to write to the server.</param> public void WriteSingleRegister(byte unitIdentifier, ushort registerAddress, ushort value) { if (this.SwapBytes) { value = ModbusUtils.SwitchEndianness(value); } this.WriteSingleRegister(unitIdentifier, registerAddress, MemoryMarshal.Cast <ushort, byte>(new[] { value }).ToArray()); }
/// <summary> /// Writes the provided array of type <typeparamref name="T"/> to the holding registers. /// </summary> /// <typeparam name="T">Determines the type of the provided data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The holding register start address for the write operation.</param> /// <param name="dataset">The data of type <typeparamref name="T"/> to write to the server.</param> public void WriteMultipleRegisters <T>(byte unitIdentifier, ushort startingAddress, T[] dataset) where T : unmanaged { if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset.AsSpan()); } this.WriteMultipleRegisters(unitIdentifier, startingAddress, MemoryMarshal.Cast <T, byte>(dataset).ToArray()); }
/// <summary> /// Reads the specified number of values of type <typeparamref name="T"/> from the input registers. /// </summary> /// <typeparam name="T">Determines the type of the returned data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The input register start address for the read operation.</param> /// <param name="count">The number of elements of type <typeparamref name="T"/> to read.</param> public Span <T> ReadInputRegisters <T>(byte unitIdentifier, ushort startingAddress, ushort count) where T : unmanaged { var dataset = MemoryMarshal.Cast <byte, T>(this.ReadInputRegisters(unitIdentifier, startingAddress, this.ConvertSize <T>(count))); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset); } return(dataset); }
/// <summary> /// Writes the provided <paramref name="value"/> to the holding registers. /// </summary> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="registerAddress">The holding register address for the write operation.</param> /// <param name="value">The value to write to the server.</param> public void WriteSingleRegister(int unitIdentifier, int registerAddress, ushort value) { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var registerAddress_converted = this.ConvertUshort(registerAddress); if (this.SwapBytes) { value = ModbusUtils.SwitchEndianness(value); } this.WriteSingleRegister(unitIdentifier_converted, registerAddress_converted, MemoryMarshal.Cast <ushort, byte>(new[] { value }).ToArray()); }
/// <summary> /// Writes the provided array of type <typeparamref name="T"/> to the holding registers. /// </summary> /// <typeparam name="T">Determines the type of the provided data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The holding register start address for the write operation.</param> /// <param name="dataset">The data of type <typeparamref name="T"/> to write to the server.</param> public void WriteMultipleRegisters <T>(int unitIdentifier, int startingAddress, T[] dataset) where T : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var startingAddress_converted = this.ConvertUshort(startingAddress); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset.AsSpan()); } this.WriteMultipleRegisters(unitIdentifier_converted, startingAddress_converted, MemoryMarshal.Cast <T, byte>(dataset).ToArray()); }
/// <summary> /// Writes the provided <paramref name="value"/> to the holding registers. /// </summary> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="registerAddress">The holding register address for the write operation.</param> /// <param name="value">The value to write to the server.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param> public async Task WriteSingleRegisterAsync(int unitIdentifier, int registerAddress, ushort value, CancellationToken cancellationToken = default) { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var registerAddress_converted = this.ConvertUshort(registerAddress); if (this.SwapBytes) { value = ModbusUtils.SwitchEndianness(value); } await this.WriteSingleRegisterAsync(unitIdentifier_converted, registerAddress_converted, MemoryMarshal.Cast <ushort, byte>(new[] { value }).ToArray()).ConfigureAwait(false); }
/// <summary> /// Writes the provided array of type <typeparamref name="T"/> to the holding registers. /// </summary> /// <typeparam name="T">Determines the type of the provided data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The holding register start address for the write operation.</param> /// <param name="dataset">The data of type <typeparamref name="T"/> to write to the server.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param> public async Task WriteMultipleRegistersAsync <T>(int unitIdentifier, int startingAddress, T[] dataset, CancellationToken cancellationToken = default) where T : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var startingAddress_converted = this.ConvertUshort(startingAddress); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset.AsSpan()); } await this.WriteMultipleRegistersAsync(unitIdentifier_converted, startingAddress_converted, MemoryMarshal.Cast <T, byte>(dataset).ToArray()).ConfigureAwait(false); }
public static void SetBigEndian <T>(this Span <short> buffer, ushort address, T value) where T : unmanaged { var byteBuffer = MemoryMarshal .AsBytes(buffer) .Slice(address * 2); if (BitConverter.IsLittleEndian) { value = ModbusUtils.SwitchEndianness(value); } Unsafe.WriteUnaligned(ref byteBuffer.GetPinnableReference(), value); }
/// <summary> /// Reads the specified number of values of type <typeparamref name="T"/> from the input registers. /// </summary> /// <typeparam name="T">Determines the type of the returned data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The input register start address for the read operation.</param> /// <param name="count">The number of elements of type <typeparamref name="T"/> to read.</param> public Span <T> ReadInputRegisters <T>(int unitIdentifier, int startingAddress, int count) where T : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var startingAddress_converted = this.ConvertUshort(startingAddress); var count_converted = this.ConvertUshort(count); var dataset = MemoryMarshal.Cast <byte, T>( this.ReadInputRegisters(unitIdentifier_converted, startingAddress_converted, this.ConvertSize <T>(count_converted))); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset); } return(dataset); }
public static T GetBigEndian <T>(this Span <short> buffer, ushort address) where T : unmanaged { var byteBuffer = MemoryMarshal .AsBytes(buffer) .Slice(address * 2); var value = Unsafe.ReadUnaligned <T>(ref byteBuffer.GetPinnableReference()); if (BitConverter.IsLittleEndian) { value = ModbusUtils.SwitchEndianness(value); } return(value); }
/// <summary> /// Reads the specified number of values of type <typeparamref name="T"/> from the holding registers. /// </summary> /// <typeparam name="T">Determines the type of the returned data.</typeparam> /// <param name="unitIdentifier">The unit identifier is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent Modbus end units. Thus, the unit identifier is the address of a remote slave connected on a serial line or on other buses. Use the default values 0x00 or 0xFF when communicating to a Modbus server that is directly connected to a TCP/IP network.</param> /// <param name="startingAddress">The holding register start address for the read operation.</param> /// <param name="count">The number of elements of type <typeparamref name="T"/> to read.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param> public async Task <Memory <T> > ReadHoldingRegistersAsync <T>(int unitIdentifier, int startingAddress, int count, CancellationToken cancellationToken = default) where T : unmanaged { var unitIdentifier_converted = this.ConvertUnitIdentifier(unitIdentifier); var startingAddress_converted = this.ConvertUshort(startingAddress); var count_converted = this.ConvertUshort(count); var dataset = SpanExtensions.Cast <byte, T>(await this.ReadHoldingRegistersAsync(unitIdentifier_converted, startingAddress_converted, this.ConvertSize <T>(count_converted)).ConfigureAwait(false)); if (this.SwapBytes) { ModbusUtils.SwitchEndianness(dataset); } return(dataset); }
public static void SetBigEndian <T>(this Span <short> buffer, int address, T value) where T : unmanaged { if (!(0 <= address && address <= ushort.MaxValue)) { throw new Exception(ErrorMessage.Modbus_InvalidValueUShort); } var byteBuffer = MemoryMarshal .AsBytes(buffer) .Slice(address * 2); if (BitConverter.IsLittleEndian) { value = ModbusUtils.SwitchEndianness(value); } Unsafe.WriteUnaligned(ref byteBuffer.GetPinnableReference(), value); }
public static T GetMidLittleEndian <T>(this Span <short> buffer, int address) where T : unmanaged { if (!(0 <= address && address <= ushort.MaxValue)) { throw new Exception(ErrorMessage.Modbus_InvalidValueUShort); } var byteBuffer = MemoryMarshal .AsBytes(buffer) .Slice(address * 2); var value = Unsafe.ReadUnaligned <T>(ref byteBuffer.GetPinnableReference()); value = ModbusUtils.ConvertBetweenLittleEndianAndMidLittleEndian(value); if (!BitConverter.IsLittleEndian) { value = ModbusUtils.SwitchEndianness(value); } return(value); }
public static void SwitchEndianness <T>(Memory <T> dataset) where T : unmanaged { ModbusUtils.SwitchEndianness(dataset.Span); }