I'm using a wiz811mj ethernet module (basically the same functionality as the ethernet shield) and the UDPsendReceiveString sketch that comes with the ethernet library, with an Arduino uno.
I'm sending this a stream of packets 530 bytes long.
A correct report looks like this - Received packet of size 530 From 2.0.0.1, port 6454 Contents: Art-Net
At higher speeds (40-60 pps) the reported size quickly rises like so - Received packet of size 12128 From 0.0.0.0, port 0 Contents:
Until the device freezes (within seconds usually)
At lower speeds (like 20 pps) the errors will be fewer but still present, and the device will still crash, though less frequently.
All I need is to read and parse one current packet (ideally the most recent, though not essential), ignore any that the arduino does not have time to deal with, then read and parse the next (most recent) packet when the arduino is ready (ie main loop cycles round)
I don't know if it's the w5100 buffer that is filling up and freezing, or the arduino memory.
It is not always possible for me to control the speed of (duration between) the incoming packets, so the system must be able to ignore packets it can't process in time.
I've tried calling EthernetUdp.flush() at the end of every loop, which I presumed would clear the w5100 buffer after the packet had been read but the only effect is to make crashes much more frequent.
Would an arduino mega help? or an ethernet controller based on the w5200 for example? It'd be nice not to have to spend more money but I'm happy to if it works.
I'm sending packets 530 bytes in size, about 40 packets per second, with the following code -
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(2, 0, 0, 101);
unsigned int localPort = 6454; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[1024]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(57600);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,1024);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
The correct response is (with my packets)- Received packet of size 530 From 2.0.0.1, port 6454 Contents: Art-Net
Wheras most of the responses end up being something like- Received packet of size 702 From 0.0.0.0, port 0 Contents:
or- Received packet of size 20012 From 0.1.0.0, port 2 Contents: É
And often the packet size value will rise to just under 32000 before crashing.
I've tried flushing the buffer after each read with EthernetUdp.flush() which in theory would fix my problem (I don't care about lost packets). But it just seems to make the crashes more frequent
Test out your setup by trying the Webserver and Webclient examples. This is a simpler setup that doesn't use UDP or processing but you can switch back later if you don't like TCP. Its just a matter of fault finding at this stage and determining if your module is working, correctly wired, etc.