using Modbus.Device; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MV485.helper { public class ModbusRtuClient_A { private SerialPort _serialPort; private IModbusSerialMaster _modbusMaster; private readonly string _portName; private readonly int _baudRate; private readonly Parity _parity; private readonly int _dataBits; private readonly StopBits _stopBits; private readonly List _deviceAddresses; private readonly int _pollingIntervalMs; private CancellationTokenSource _cancellationTokenSource; public ModbusRtuClient_A(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, List deviceAddresses, int pollingIntervalMs) { _portName = portName; _baudRate = baudRate; _parity = parity; _dataBits = dataBits; _stopBits = stopBits; _deviceAddresses = deviceAddresses; _pollingIntervalMs = pollingIntervalMs; Console.WriteLine("ModbusRtuClient initialized."); } public void Start() { Console.WriteLine("Starting Modbus RTU client..."); _serialPort = new SerialPort(_portName, _baudRate, _parity, _dataBits, _stopBits); _serialPort.Open(); Console.WriteLine("Serial port opened."); //_modbusMaster = new ModbusFactory().CreateRtuMaster(_serialPort); _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort); Console.WriteLine("Modbus master created."); _cancellationTokenSource = new CancellationTokenSource(); Task.Run(() => PollingLoop(_cancellationTokenSource.Token)); } public void Stop() { Console.WriteLine("Stopping Modbus RTU client..."); _cancellationTokenSource?.Cancel(); _modbusMaster?.Dispose(); _serialPort?.Close(); Console.WriteLine("Modbus RTU client stopped."); } private async Task PollingLoop(CancellationToken token) { Console.WriteLine("Starting polling loop..."); while (!token.IsCancellationRequested) { foreach (var address in _deviceAddresses) { try { Console.WriteLine($"Reading from device {address}..."); ushort[] registers = _modbusMaster.ReadHoldingRegisters(address, 0, 2); Console.WriteLine($"Device {address}: Water Usage = {registers[0]}, Sampling Time = {registers[1]}"); } catch (Exception ex) { Console.WriteLine($"Error reading device {address}: {ex.Message}"); } } Console.WriteLine("Polling cycle completed. Waiting for next cycle..."); await Task.Delay(_pollingIntervalMs, token); } Console.WriteLine("Polling loop terminated."); } //------------------------------------------------------------------------------------------------- } }