emelianov / modbus-esp8266

Most complete Modbus library for Arduino. A library that allows your Arduino board to communicate via Modbus protocol, acting as a master, slave or both. Supports network transport (Modbus TCP) and Serial line/RS-485 (Modbus RTU). Supports Modbus TCP Security for ESP8266/ESP32.
Other
525 stars 188 forks source link

ModbusTCP with ESP32 and W5500. Sockets remain open? #125

Closed 770dev closed 3 years ago

770dev commented 3 years ago

Hello,

I tried emelianov/modbus-esp8266@4.0.0-DEV and arduino-libraries/Ethernet@2.0.0 on Visual Studio/PlatformIO to program an ESP32 and a W5500 Ethernet module. If I create an ethernet modbus server, and then try to do singular read/writes from a linux computer (with the command mbpool or modpool), the esp32 only responds to the first 8 queries, and then I get connection refused messages. mbpoll: Connection failed: Connection refused.

Is it possible that the sockets remain open after the execution of the mbpool command? The only way for the esp32 to respond to modbus queries after the 8th query is to reset it.

minimal example code: `

include

include // lib_deps = arduino-libraries/Ethernet@^2.0.0

define SCK 18

define MISO 19

define MOSI 23

define CS 26

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 3, 177);

include // lib_deps += emelianov/modbus-esp8266@^4.0.0-DEV

ModbusEthernet mbTCP;

void setup() { SPI.begin(SCK, MISO, MOSI, -1); Ethernet.init(CS); Ethernet.begin(mac, ip); delay(1000); mbTCP.server(); mbTCP.addHreg(400,0); }

void loop() { mbTCP.task(); delay(50); } `

sample script for the linux computer: for i inseq 1 24; do mbpoll -0 192.168.3.177 -t4 -r400 0; echo $i; sleep 1; done

Is this an issue or am I forgeting something?

thank you.

emelianov commented 3 years ago

In short, you have to use persistent Modbus connection. W5x00 has limited count of supported connections. After multiple incoming connections it will stay in half-close state for a while and board unable to accept new one.

oxullo commented 1 year ago

Sorry if I bump the discussion, but I stumbled upon the same issue. As far as I can see, there's an easy fix, which apparently has been already tried:

https://github.com/emelianov/modbus-esp8266/blob/299666307a052df52f757f3131e292c2513bb57f/src/ModbusTCPTemplate.h#L440

By just un-commenting this line, a client can reconnect more than 4 times (w5100) or 8 times (other w5xxx).

As stated in the official documentation of the Arduino's Ethernet library (https://www.arduino.cc/reference/en/libraries/ethernet/server.accept/), server.accept() shifts the responsibility of the handling the connection's cleanup to the implementation.

As I'm testing only with an ethernet shield, I have no idea of the impact for WiFi or ESPx setups, as I wonder about the reason for commenting it out. That'd include also:

https://github.com/emelianov/modbus-esp8266/blob/299666307a052df52f757f3131e292c2513bb57f/src/ModbusTCPTemplate.h#L549

Thank you!

emelianov commented 1 year ago

As far as I remember ->stop() commented out after reviewing of Ethernet library code. By now I don't remember version but I do remember that it was destructor containing some kind of stop() call equivalent. I've reviewed Arduino Ethernet library code again and can't see any destructor in this implantation. So it's a fact that connections remain open on disconnect. To be fixed.

oxullo commented 1 year ago

If you wish I could PR this fix: https://github.com/emelianov/modbus-esp8266/compare/master...amdx:modbus-esp8266:master A blatant fix, but it works for us, at least under AVR. Worst case, as far I can see from the Ethernet library implementation, calling stop() multiple times is safe.

emelianov commented 1 year ago

merged to master. thanks.