Innovenergy_trunk/csharp/Lib/Protocols/Modbus/Connections/ModbusSerialConnection.cs

84 lines
2.2 KiB
C#

using System.IO.Ports;
using InnovEnergy.Lib.Protocols.Modbus.Protocol;
namespace InnovEnergy.Lib.Protocols.Modbus.Connections;
public class ModbusSerialConnection : ModbusConnection
{
private String PortName { get; }
private Int32 BaudRate { get; }
private Parity Parity { get; }
private Int32 DataBits { get; }
private StopBits StopBits { get; }
private Int32 TimeoutMs { get; }
private Byte[] Buffer { get; } = new Byte[1024];
private SerialPort? _SerialPort;
public ModbusSerialConnection(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, TimeSpan timeout)
{
PortName = portName;
BaudRate = baudRate;
Parity = parity;
DataBits = dataBits;
StopBits = stopBits;
TimeoutMs = (Int32) timeout.TotalMilliseconds;
}
public override IReadOnlyList<Byte> Receive(UInt16 bytesToRead)
{
var bytesReceived = 0;
var serialPort = SerialPort();
do
{
var received = serialPort.Read(Buffer, bytesReceived, Buffer.Length - bytesReceived);
if (received < 0)
throw new NotConnectedException("Serial Connection has been closed");
bytesReceived += received;
}
while (bytesReceived < bytesToRead);
return new ArraySegment<Byte>(Buffer, 0, bytesToRead);
}
public override void Transmit(IEnumerable<Byte> data)
{
var array = data.ToArray();
SerialPort().Write(array, 0, array.Length);
}
public override void Open() => SerialPort();
private SerialPort SerialPort()
{
if (_SerialPort == null)
{
_SerialPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits) { ReadTimeout = TimeoutMs, WriteTimeout = TimeoutMs};
_SerialPort.Open();
}
return _SerialPort;
}
public override void Close()
{
if (_SerialPort != null)
{
try
{
_SerialPort.Close();
_SerialPort?.Dispose();
}
catch (Exception)
{
// ignored
}
}
_SerialPort = null;
}
}