Hi
I have seen many people having the same issue - but none of the solutions proposed worked for me. The closest it got was this topic: UDP freezes, possible cure found(???) - Networking, Protocols, and Devices - Arduino Forum
The problem is overall that the Ethernet lib freezes when sending a UDP packet.
The analysis I got so far:
- The code gets stuck in the while loop in EthernetClass::socketSendUDP (bottom of socket.cpp file)
- The loop is getting the value of the SnIR register (chipW5100.readSnIR) and waiting for either SEND_OK or TIMEOUT from the w5500, but it only gets 0.
I have 3 w5500 modules and the 3 modules give the same results: sometimes it hangs, sometimes it returns timeout, but it never stops if the Eternet cable is unplugged. And when sending a packet to a server, I can see the packet is sent right away (this part always works), and then sometimes the endPacket returns (SEND_OK) after 5-6 seconds, sometimes right away, and sometimes it never returns. And strangely if it returns right away (i.e. working), then it works fine for the next 20-30 times, and then it goes back to freezing.
But the actual UDP packet is always sent right away, as said this always works.
See below an example code and the output result.
#include <Ethernet.h>
#define PORT 9023
uint8_t mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAF};
EthernetUDP myUdp;
void setup() {
IPAddress myLocalIP(192, 168, 87, 230);
IPAddress serverIP(192, 168, 87, 187);
Serial.begin(9600);
Serial.println("##############");
Ethernet.begin(mac, myLocalIP);
Serial.print("Hardware: ");
switch (Ethernet.hardwareStatus()) {
case EthernetW5100: Serial.println("W5100"); break;
case EthernetW5200: Serial.println("W5200"); break;
case EthernetW5500: Serial.println("W5500"); break;
default: Serial.println("No Hardware!");
}
Serial.print("Link Status: ");
switch (Ethernet.linkStatus()) {
case LinkON: Serial.println("ON"); linkOn = true; break;
case LinkOFF: Serial.println("OFF"); linkOn = false; break;
default: Serial.println("Unknown!");
}
if (!myUdp.begin(PORT))
Serial.println("### UDP begin ERROR");
if (!myUdp.beginPacket(serverIP, PORT))
Serial.println("### UDP beginPacket ERROR");
size_t len = myUdp.write("testing");
Serial.print(len); Serial.println(" bytes written.");
Serial.println("Calling endPacket() NOW");
if (!myUdp.endPacket())
Serial.println("### FAIL");
else
Serial.println("SUCCESS");
}
void loop() {
}
When the Ethernet cable is disconnected it never ends:
##############
Hardware: W5500
Link Status: OFF
7 bytes written.
Calling endPacket() NOW
When connected it ends "most of the times", with a variable delay before the SUCCESS (as written above):
##############
Hardware: W5500
Link Status: ON
7 bytes written.
Calling endPacket() NOW
SUCCESS