Udp write problem

I’m trying to get WakeupOnLan working from the Arduino Mega + Ethernet card (I’ve attached my test code)
The problem that I’m hitting is that in attempting to write 16 copies of the mac address (6 bytes) to the Udp buffer, it occasionally returns 2048 for the size written (I’ve reduced the number of mac frames from the normal 16 to 3, so that it succeeds sometimes - I can see it succeed/fail on the network monitor that I have running on another PC) If 2048 occurs, then the packet is not sent.
I’ve looked at the library code for Udp::write() and it seems that the 2048 is the TX buffer free size which is returned if the requested write length exceeds the W5100 TX buffer free size.
So I’ve only written 3 *6 bytes and yet it thinks that the following 6 bytes will cause the buffer to overflow !! I even tried a Udp.flush() beforehand, but the problem remains
I’m sure this is something silly, that someone will point out the glaring mistake, and I’ll kick myself !!
All suggestions will be appreciated !

WakeOnLan.cpp (1.41 KB)

WakeOnLan.h (412 Bytes)

WakeOnLanExample.ino (789 Bytes)

According to socket.cpp:

  if (len > W5100.getTXFreeSize(s))
  {
    ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size.
  }
  else
  {
    ret = len;
  }

the return value always must be less or equal to the supplied parameter len. The only reason I see to return a bigger value is if during the if call to getTXFreeSize() it returned something very small (for whatever reason), but that problem resolved before calling getTXFreeSize() again in the next line.

Try to fix that by replacing above code with:

  uint16_t free_size =  W5100.getTXFreeSize(s);
  if (len > free_size)
  {
    ret = free_size; // check size not to exceed MAX size.
  }
  else
  {
    ret = len;
  }

This way the call is made just once and if there was a problem you at least get the correct value back.

BTW: in your code you have the comment that the return value of the write is OK if it is 1. The only OK value is 6 because that’s the number of bytes you wrote. Every other value means an error.

Hi Pylon, Don't disagree with either of your observations ! (the comment was a victim of "copy and paste" !!) I still can't understand why this problem is occuring - the write sequence involves 17 * 6 bytes = 102 bytes which is a LOT less than the size of the TX buffer (2048 bytes), so why is there ANY failure (via the return value) to Udp.write() ??

is a LOT less than the size of the TX buffer

The UDP buffer is being built on the Arduino, not on the Ethernet hardware. That buffer is nowhere near 2048 bytes, which is all the memory on many Arduinos.

PaulS: The UDP buffer is being built on the Arduino, not on the Ethernet hardware. That buffer is nowhere near 2048 bytes, which is all the memory on many Arduinos.

Hi Paul, So what reason could the call to W5100.getTXFreeSize(s) result in the return of 2048 ?? Surely W5100 functionality resides on the the Ethernet shield (where the W5100 chip is) , or have I got this completely wrong ?

DougButtimer: Hi Paul, So what reason could the call to W5100.getTXFreeSize(s) result in the return of 2048 ?? Surely W5100 functionality resides on the the Ethernet shield (where the W5100 chip is) , or have I got this completely wrong ?

You have that right. What you are assuming, apparently, is that there is some relationship between that value and the UDP packet size. You really should be looking at the UDP library code to see the buffer size.

PaulS:
You have that right. What you are assuming, apparently, is that there is some relationship between that value and the UDP packet size. You really should be looking at the UDP library code to see the buffer size.

According to W5100.h
public:
static const uint16_t SSIZE = 2048; // Max Tx buffer size

With due respect, I think that we’re getting sidetracked away from the problem !!
The facts are that on successive calls to Udp.write() to add a 6 byte mac to the buffer, return values are 6, 6, 2048, 6,6, 2048 … (for example). Anytime, a 2048 is returned from ANY of the 16 mac copies, the packet is not sent. We are not talking vast amounts of data here ! And this IS library code - I can’t believe that I’m the first one to hit this !!

First of all, I think that I've solved this !

On a hunch, (and because the 2048 only occured sporadically) I decided to reduce the speed of the SPI bus to half speed. This resulted in reliable returns from Udp.write() of 6. Being a suspicious sort of bloke, I set it back to full speed, and, lo and behold, it again ran faultlessly, time and time again !!

So it looks like it was just the act of initialising the SD card interface that was necessary for reliable operation. (this is not a problem to me, as the project that I want to use WOL uses the SD card anyway.

Hope that this info helps someone else !