Failed `ModbusClientTCP.syncRequest` takes a minute to return
mcuadros opened this issue · comments
Do not use to discuss topics!
Describe the bug
Failed ModbusClientTCP.syncRequest
takes a minute to return.
Expected behavior
Return immediately when the error happends.
To Reproduce
Steps to reproduce the behavior:
Example code
// =================================================================================================
// eModbus: Copyright 2020 by Michael Harwerth, Bert Melis and the contributors to ModbusClient
// MIT license - see license.md for details
// =================================================================================================
// Example code to show the usage of the eModbus library.
// Please refer to root/Readme.md for a full description.
// Includes: <Arduino.h> for Serial etc., WiFi.h for WiFi support
#include <Arduino.h>
#include <WiFi.h>
// Include the header for the ModbusClient TCP style
#include "ModbusClientTCP.h"
#ifndef MY_SSID
#define MY_SSID "xxx"
#endif
#ifndef MY_PASS
#define MY_PASS "xxx"
#endif
char ssid[] = MY_SSID; // SSID and ...
char pass[] = MY_PASS; // password for the WiFi network used
// Create a ModbusTCP client instance
// Setup() - initialization happens here
void setup() {
// Init Serial monitor
Serial.begin(115200);
while (!Serial) {}
Serial.println("__ OK __");
WiFi.persistent(false);
WiFi.disconnect(true);
Serial.println("WiFi: Entering boot sequence");
WiFi.mode(WIFI_STA);
WiFi.setAutoConnect(true);
WiFi.setSleep(false);
WiFi.begin(ssid, pass);
Serial.printf("WiFi(%s): Attempting connection", ssid);
WiFi.hostname(("server.local"));
WiFi.mode(WIFI_STA);
WiFi.begin("xxxx", "xxxxx");
int secs = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.printf("\nWiFi(%s): Connected with IP address, %s\n",
ssid, WiFi.localIP().toString().c_str());
WiFiClient theClient; // Set up a client
ModbusClientTCP MB(theClient);
MB.setTimeout(2000, 200);
MB.begin(1);
MB.setTarget(IPAddress(192, 168, 0, 10), 400); // random IP without serversz
auto response = MB.syncRequest((uint32_t)millis(), 20, READ_HOLD_REGISTER, 1, 2);
for (auto& byte : response) {
Serial.printf("%02X ", byte);
}
Serial.println("");
response = MB.syncRequest((uint32_t)millis(), 20, READ_HOLD_REGISTER, 1, 2);
for (auto& byte : response) {
Serial.printf("%02X ", byte);
}
Serial.println("");
}
// loop() - nothing done here today!
void loop() {
}
Additional context
Add any other context about the problem here.
Your comments are a tad sparse, I must say. 😉
I took from the PR that you are thinking with synchronous TCP requests connection errors are not reported back as soon as possible, right?
If so, your fix will not change a bit on that. Part of the sync request handling is that a special onError
handler is deployed that will catch and return the error.
The time to determine the error is defined by the timeout value you gave the ModbusClientTCP
when defining it or with the respective timeout call. I would suggest reducing that time to get a quicker error response.
I had a look at the code again and can confirm there is a sync request handling missing indeed if the IP connection has failed. I will add a fix later.
@mcuadros Thanks for the hint! 👍🏻
I must say that the PR I sent fixes the problem since I get the error straight when it happens, instead of blocking for the whole minute.
I am not using any callback since I want to be in full sync, so even if I use it, the error arrives there, but the main loop remains blocked.
It's true that maybe caused by my PR, when I use setTarget
, the connection stuck, and I can't connect again even is a valid server.
Thanks for the quick replay.
(Yes yesterday was late, sorry about my short comments)
@mcuadros I pushed a fix to the master
branch a minute ago - can you give that a try?
@mcuadros Ping?
@mcuadros Senor? I am awaiting your feedback...
Seems to be solved.