Hi everybody,
I'm using an Arduino Mega 2560 with the ethernet shield (W5100) to talk to a device that talks trough TCP and UDP (udp port 2222 only), I can change the Request Poll Interval (RPI) from 1 to 3200 ms, we usually use 50ms but it fails like an hour later, I try at 1ms just to verify if changing the speed makes it fail faster and it did, at 1ms I'm getting the error approximately 5 minutes later after the communication starts
At the beginning it was just hanging the arduino, then I noticed that it was getting stuck in the udp library function "socketSendUDP" so I made a little modification to the library to let it continue but eventually the ethernet shield will just stop working anyways.
In order to replicate the problem I simplify the arduino code and I removed the TCP portion of it and I made an app that sends UDP packets to an specified IP and UDP Port, and it still happens.
The error that I'm getting from the UDP library is SnIR::RECV (0x04)
this is the arduino code
#include <Ethernet.h>
#include <EthernetUdp.h>
#define UDP_TX_PACKET_MAX_SIZE 200
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int UDPPort = 2222; // local port to listen on
unsigned char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
EthernetUDP Udp;
void setup() {
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
Serial.begin(115200);
Ethernet.init(10);
Ethernet.begin(mac, ip, myDns, gateway, subnet);
Udp.begin(UDPPort);
Serial.print("Adapter address:");
Serial.println(Ethernet.localIP());
}
void loop() {
int packetSize = Udp.parsePacket();
if (packetSize) {
Udp.read(packetBuffer, packetSize);
byte udp_response[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IPAddress remote = Udp.remoteIP();
Udp.beginPacket(remote, 2222);
Udp.write(udp_response, sizeof(udp_response));
int err = Udp.endPacket();
if (err != 1) {
Serial.print("MEM: ");
Serial.print(freeRam());
Serial.print(", err: ");
Serial.println(err);
}
}
}
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
and this is the app to send the UDP packets
UDPTransmitter.zip (7.4 KB)
this is the modification in the UDP library
int EthernetClass::socketSendUDP(uint8_t s)
{
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.execCmdSn(s, Sock_SEND);
/* +2008.01 bj */
int countertimeout = 0;
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) {
if (W5100.readSnIR(s) & SnIR::TIMEOUT) {
/* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
SPI.endTransaction();
//Serial.printf("sendUDP timeout\n");
return SnIR::TIMEOUT;
}
if (W5100.readSnIR(s) & SnIR::RECV) {
/* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::DISCON));
SPI.endTransaction();
//Serial.printf("sendUDP timeout\n");
return SnIR::RECV;
}
SPI.endTransaction();
yield();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
//countertimeout++;
//if(countertimeout > 1000) return W5100.readSnIR(s);
}
/* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK);
SPI.endTransaction();
//Serial.printf("sendUDP ok\n");
/* Sent ok */
return 1;
}
be aware that this happens after several maybe thousand of packets later, it usually takes less than 10 minutes at 1ms RPI
Thanks in advance