Skip to content

Commit 29869a2

Browse files
Fixed RTU slave timing issues causing intermittent responses
1 parent a1f6ab4 commit 29869a2

File tree

1 file changed

+58
-9
lines changed

1 file changed

+58
-9
lines changed

ModbusTerm/Services/ModbusSlaveService.cs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -315,18 +315,41 @@ private bool StartRtuSlave(RtuConnectionParameters? parameters)
315315
// Initialize registers with defined values
316316
InitializeRegisters();
317317

318-
// Create and open serial port with correct parameters
318+
// Create and configure serial port with comprehensive settings for reliable slave operation
319319
_serialPort = new SerialPort
320320
{
321321
PortName = parameters.ComPort, // Use selected COM port
322322
BaudRate = parameters.UseCustomBaudRate ? parameters.CustomBaudRate : parameters.BaudRate,
323323
Parity = parameters.Parity,
324324
DataBits = parameters.DataBits,
325-
StopBits = parameters.StopBits
325+
StopBits = parameters.StopBits,
326+
327+
// Critical settings for reliable Modbus RTU slave communication
328+
Handshake = Handshake.None,
329+
RtsEnable = false,
330+
DtrEnable = false,
331+
332+
// Buffer settings - important for preventing data loss
333+
ReadBufferSize = 4096,
334+
WriteBufferSize = 4096,
335+
336+
// Timeout settings - crucial for proper request/response handling
337+
ReadTimeout = Math.Max(parameters.Timeout, 1000), // Use connection timeout or minimum 1 second
338+
WriteTimeout = Math.Max(parameters.Timeout / 2, 500), // Half of read timeout or minimum 500ms
339+
340+
// Prevent automatic newline handling which can interfere with binary data
341+
NewLine = "\n",
342+
343+
// Ensure immediate processing of incoming data
344+
ReceivedBytesThreshold = 1
326345
};
327346

328347
_serialPort.Open();
329348

349+
// Clear any existing data in the buffers
350+
_serialPort.DiscardInBuffer();
351+
_serialPort.DiscardOutBuffer();
352+
330353
// Create RTU slave network
331354
var factory = new ModbusFactory();
332355
var adapter = new SerialPortAdapter(_serialPort);
@@ -340,23 +363,49 @@ private bool StartRtuSlave(RtuConnectionParameters? parameters)
340363
_cancellationTokenSource = new CancellationTokenSource();
341364
var token = _cancellationTokenSource.Token;
342365

343-
// Listen for Modbus requests in background
344-
Task.Run(() => {
366+
// Set connection status before starting listener
367+
IsConnected = true;
368+
369+
// Listen for Modbus requests in background with improved error handling
370+
Task.Run(async () => {
345371
try {
346372
while (!token.IsCancellationRequested) {
347-
_network.ListenAsync(token).Wait(1000);
373+
try
374+
{
375+
// Use async listening without timeout to ensure proper response handling
376+
await _network.ListenAsync(token);
377+
}
378+
catch (OperationCanceledException)
379+
{
380+
// Expected when cancellation is requested
381+
break;
382+
}
383+
catch (Exception ex) when (!token.IsCancellationRequested)
384+
{
385+
// Log individual request errors but continue listening
386+
RaiseCommunicationEvent(CommunicationEvent.CreateWarningEvent($"RTU slave request error: {ex.Message}"));
387+
388+
// Small delay before continuing to prevent rapid error loops
389+
await Task.Delay(10, token);
390+
}
348391
}
349392
}
350-
catch (OperationCanceledException) { /* Expected when cancellation requested */ }
351-
catch (Exception ex) {
352-
if (!token.IsCancellationRequested) {
393+
catch (OperationCanceledException)
394+
{
395+
// Expected when cancellation requested
396+
}
397+
catch (Exception ex)
398+
{
399+
if (!token.IsCancellationRequested)
400+
{
353401
RaiseCommunicationEvent(CommunicationEvent.CreateErrorEvent($"RTU slave error: {ex.Message}"));
402+
IsConnected = false;
354403
}
355404
}
356405
}, token);
357406

358407
// Report success to UI
359-
RaiseCommunicationEvent(CommunicationEvent.CreateInfoEvent($"Slave started on {parameters.ComPort}"));
408+
RaiseCommunicationEvent(CommunicationEvent.CreateInfoEvent($"RTU slave started on {parameters.ComPort} with ID {_slaveId}"));
360409

361410
return true;
362411
}

0 commit comments

Comments
 (0)