I have a simple sketch to receive UDP packets. The packets come in short bursts at about 50ms.
I can successfully receive bursts of 3 packets for extended periods of time with very few misses. If I go to 4 packets it misses the 4th packet every time, so I get the first, second and third and the next packet is first one from the next group.
I initially used a W5100 shield, but then I switched to a W5500 which I understand is faster and has larger buffers. There is no improvement.
This is with packets of around 600 bytes. If I lower the packet size I can get 4.
I totally understand that if the packets come fast the code reading them through the SPI will have a limit. But if my 4 packets can fit in the W5500 Rx buffer there is plenty of time to read them all until the next burst.
It seems as if the buffer cannot hold the frames containing four 600 byte UDP packets, which seems very little compared to the buffer room on the chip. Or that the EthernetUdp API I am using is limiting somehow.
The fragment below shows how I’ve been testing this. The network used for testing is private and isolated to avoid noise like broadcasts etc.
uint16_t readPacket(uint8_t *payloadBuffer){
int packetSize, payloadSize;
while (1) {
packetSize = Udp.parsePacket();
if (packetSize) {
payloadSize = Udp.read(payloadBuffer, packetSize);
break;
}
}
return payloadSize;
}
void loop() {
/* receive a packet into the buffer
*/
uint16_t ps = readPacket(PAYLOAD_BUF);
/* simulate a condition when the program takes too long to process packets coming in rapid
* sequence
*/
// delay(10);
// check if the packet is valid - just by size
if (ps < 127) {
// too small
Serial.print(F("Received payload size too small:"));
Serial.println(ps);
return; //bail out of this packet
}
// error logging
if (last_u != PAYLOAD_BUF[COUNTER_BYTE_OFFSET]) {
Serial.print(F("warning, received/expected: "));
Serial.print(PAYLOAD_BUF[COUNTER_BYTE_OFFSET]);
Serial.print(F("/"));
Serial.println(last_u);
// increment error counter
gec++;
}
// [re]set the next expected packet number
last_u = PAYLOAD_BUF[COUNTER_BYTE_OFFSET] + 1;
if (last_u > MAX_BURST) {
last_u = 1; //roll over
}
}