Ethernet Oddities

I’ve been battling Ethernet problems for months, and I’m finally at the point where I really need to get them resolved. I’m running an Ethernet shield on a Due, connected by an Ethernet cable directly to a PC - no router, hubs, etc… When it works, it works fine. But, on power-up, there is perhaps a 1 in 4 chance it will work at the start. However, in most cases, if I simply wait, it will eventually connect and work fine. It may take a minute, it may take an hour. Or, it may never connect.

I can see by watching the LEDs on the shield that it is seeing packets, but what I see is a repeating sequence that is, I assume, the shield announcing it’s presence, and waiting to hear back from the PC. Eventually, they will connect and work just fine, and the LEDs make it immediately obvious when they are finally in the process of establishing a connection. When it doesn’t work, even ping does not work.

This occurs regardless of the code I run, including all the Ethernet example programs. I am using a hard-coded IP address (PC I/F is set to 10.9.9.1, and Arduino is set to 10.9.9.10). One odd thing: If I display Ethernet.localIP during start-up, it invariably shows the WRONG address! right now, it shows 255.0.255.255. I’ve seen many other values, but it is generally all 255s and 0s.

I’ve tried multiple PCs, cables (both straight and cross-over), Arduino, Ethernet shields, and applications, and ALL behave exactly the same.

Any ideas?

Regards,
Ry L.

Is your PC connected to a router when it is also connected to the Due?

ieee488: Is your PC connected to a router when it is also connected to the Due?

Not usually. The machines I do most of my work on are not on any network. I do some testing on my laptop, which is generally on one of my wireless networks.

Regards, Ray L.

I have been playing with the ethernet library, and cannot figure out how the Due uses the slave select on the ethernet shield.

I added the "#pragma message" precompiler messages to the different types of processors, and the boards I have tested display one of these messages on compile, except the Due. It doesn't display any of these messages. I'm not sure how the Due enables and disables the w5100 slave select. Any ideas?

#if defined(ARDUINO_ARCH_AVR)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#pragma message ("Mega")
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#elif defined(__AVR_ATmega32U4__)
#pragma message ("32U4")
  inline static void initSS()    { DDRB  |=  _BV(6); };
  inline static void setSS()     { PORTB &= ~_BV(6); };
  inline static void resetSS()   { PORTB |=  _BV(6); }; 
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
#pragma message ("AT90")
  inline static void initSS()    { DDRB  |=  _BV(0); };
  inline static void setSS()     { PORTB &= ~_BV(0); };
  inline static void resetSS()   { PORTB |=  _BV(0); }; 
#else
#pragma message ("Default")
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif
#endif // ARDUINO_ARCH_AVR

I'm running an Ethernet shield on a Due, connected by an Ethernet cable directly to a PC - no router, hubs, etc..

Have you made any provisions on the pc to make a direct connection to the Due? Try your setup thru a router first to see if that works, then make the move to a direct connection.

Try this test. If the IP shows anything but 192.168.0.2, then you have a SPI problem. It may be related to the way the ethernet library handles the w5100 slave select with the Due.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,2);

void setup() {
  Serial.begin(9600);

  // disable SD card if one in the slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // disable w5100 SPI
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);


  Serial.println("Starting w5100");
  Ethernet.begin(mac,ip);

  Serial.println(Ethernet.localIP());
}

void loop() {
}

SurferTim: I have been playing with the ethernet library, and cannot figure out how the Due uses the slave select on the ethernet shield.

I added the "#pragma message" precompiler messages to the different types of processors, and the boards I have tested display one of these messages on compile, except the Due. It doesn't display any of these messages. I'm not sure how the Due enables and disables the w5100 slave select. Any ideas?

#if defined(ARDUINO_ARCH_AVR)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#pragma message ("Mega")
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#elif defined(__AVR_ATmega32U4__)
#pragma message ("32U4")
  inline static void initSS()    { DDRB  |=  _BV(6); };
  inline static void setSS()     { PORTB &= ~_BV(6); };
  inline static void resetSS()   { PORTB |=  _BV(6); }; 
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
#pragma message ("AT90")
  inline static void initSS()    { DDRB  |=  _BV(0); };
  inline static void setSS()     { PORTB &= ~_BV(0); };
  inline static void resetSS()   { PORTB |=  _BV(0); }; 
#else
#pragma message ("Default")
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif
#endif // ARDUINO_ARCH_AVR

No idea, but I have only the one device on the SPI I/F, and even with the CS set HIGH, or LOW, the behavior is the same. I am thinking this is a Due-specific problem. A little while ago, I rounded up a Mega2560, and the same shield, and code, seems to work perfectly on that. Perhaps a timing problem in the library, due to the much faster processor?

Regards, Ray L.

zoomkat:
Have you made any provisions on the pc to make a direct connection to the Due? Try your setup thru a router first to see if that works, then make the move to a direct connection.

I don’t think it’s a PC problem since the same shield, software, and cable work perfectly with a Mega2560.

Regards,
Ray L.

SurferTim:
Try this test. If the IP shows anything but 192.168.0.2, then you have a SPI problem. It may be related to the way the ethernet library handles the w5100 slave select with the Due.

#include <SPI.h>

#include <Ethernet.h>

byte mac = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,2);

void setup() {
  Serial.begin(9600);

// disable SD card if one in the slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

// disable w5100 SPI
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

Serial.println(“Starting w5100”);
  Ethernet.begin(mac,ip);

Serial.println(Ethernet.localIP());
}

void loop() {
}

That code is, effectively, identical to what I’ve been playing with today, and it almost never returns the correct IP address, when run on a Due. On a Mega2560, with all else the same, it is always correct.

Regards,
Ray L.

RayLivingston: I don't think it's a PC problem since the same shield, software, and cable work perfectly with a Mega2560.

Regards, Ray L.

Yes, the Mega 2560 has an inline function for the slave selects.

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#pragma message ("Mega")
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };

The Uno does also, but I don't see anything for the Due.

If the test code from reply #5 fails, you probably have a slave select problem. Are you willing to try an experiment? I have a mod to the ethernet library that allows the slave select to be changed. Want to try that? If so, I'll try to find it for you.

edit: Here is a link to the four files you must change. Rename or backup your old files before replacing them with these, just in case of a problem. http://forum.arduino.cc/index.php?topic=217423.msg1962182#msg1962182

SurferTim: Yes, the Mega 2560 has an inline function for the slave selects.

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#pragma message ("Mega")
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };

The Uno does also, but I don't see anything for the Due.

If the test code from reply #5 fails, you probably have a slave select problem. Are you willing to try an experiment? I have a mod to the ethernet library that allows the slave select to be changed. Want to try that? If so, I'll try to find it for you.

edit: Here is a link to the four files you must change. Rename or backup your old files before replacing them with these, just in case of a problem. http://forum.arduino.cc/index.php?topic=217423.msg1962182#msg1962182

Yes, if you can find it, I'll give it a try. I'm also going to ask on the Due forum. I can't be the first person to use Ethernet on a Due....

Regards, Ray L.

SurferTim: Yes, the Mega 2560 has an inline function for the slave selects.

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#pragma message ("Mega")
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };

The Uno does also, but I don't see anything for the Due.

If the test code from reply #5 fails, you probably have a slave select problem. Are you willing to try an experiment? I have a mod to the ethernet library that allows the slave select to be changed. Want to try that? If so, I'll try to find it for you.

edit: Here is a link to the four files you must change. Rename or backup your old files before replacing them with these, just in case of a problem. http://forum.arduino.cc/index.php?topic=217423.msg1962182#msg1962182

Tim,

See my response to your post on the Due forum. I think you may be barking up the wrong tree...

Regards, Ray L.

Maybe barking up the right tree. Read my response on the Due forum.

edit: Maybe wrong tree. Checked the new v1.6.3 ethernet library, and it does use the new Due SPI code. Guess you are on your own there.

edit2:...unless you are willing to experiment with the library mods. It could be the new way the Due handles the SPI bus that causes your problem. The mods are not irreversible if you rename your original files first.

Well, I found my problem. Why this is not documented, and accounted for in the library, is a frickin' mystery to me! If you look at the schematic for the Due, SS0/PWM10 (Ethernet CS) and SS1/PWM4 (SD CS) are both connected to TWO pins on the SAM. Adding the following two lines to the intialization makes it work perfectly first time, every time:

pinMode(87,INPUT_PULLUP); pinMode(77,INPUT_PULLUP);

Regards, Ray L

I don't buy it on this thread either. If you had run my test code in reply #5, that did the same thing.

void setup() {
  Serial.begin(9600);

  // disable SD card if one in the slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // disable w5100 SPI
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

If two SAM pins are connected to each of D4 and D10, this would have solved your problem way back then.

SurferTim: I don't buy it on this thread either. If you had run my test code in reply #5, that did the same thing.

void setup() {
  Serial.begin(9600);

  // disable SD card if one in the slot   pinMode(4,OUTPUT);   digitalWrite(4,HIGH);

  // disable w5100 SPI   pinMode(10,OUTPUT);   digitalWrite(10,HIGH);



If two SAM pins are connected to each of D4 and D10, this would have solved your problem way back then.

For the record, I DID run your code, and it made absolutely NO difference whatsoever. I had also already tried that myself before you suggested it.

I think you've missed the while point of what I reported. On the Due board:

1) Arduino pin D10 (ETH_CS) is connected to BOTH pin 102 and pin 111 of the SAM chip.

2) Arduino pin D4 (SD_CS) is connected to BOTH pin 112 and pin 137 of the SAM chip.

pinMode(10, OUTPUT) sets SAM pin 11 as an output, but does NOTHING to pin 102.

pinMode(4, OUTPUT) sets SAM pin 112 as an output, but does NOTHING to pin 137.

SAM pins 102 and 137 are apparently, somehow, being initialized as outputs, which means both ETH_CS and SD_CS have TWO output drivers trying to drive them.

As a result of the above, there are "driver fights" going on with both ETH_CS and SD_CS. The two output drivers on each line are fighting each other, preventing both ETH_CS and SD_CS being controlled properly by the Ethernet and SD libraries.

The two pinMode lines I added eliminate the fighting by configuring SAM pins 102 and 137 as inputs, so they are no longer fighting with the other two pins to control ETH_CS and SD_CS. As I said this has COMPLETELY eliminated the problem, and the Ethernet now works perfectly for the first time.

Regards, Ray L.

As difficult as it is to believe, I believe you. You have a Due to play with. I don't.

I can't believe some fool designer would do that. And apparently some fool programmer came along and set both to OUTPUT.

Since you found the problem, I marked the other post as solved and posted my displeasure about that design there also.

But besides that fault, how does the rest of the Due perform? Is the performance what you expected? I'm still on the fence now about purchasing one, just like I was about the wifi shield. I was donated a wifi shield by PaulS (thanks, Paul!) and found it was not even close to the performance I was expecting. I don't want the Due to join it in my junk drawer.

I'm very happy with the Due. I bought several for only $14 each, and they've been great. Performance averages 5-10X the Mega2560 I was using before, and it has enough memory that I don't have to even think about it. My application is now creeping up on 250K of object code, and it's a real-time control application running three DC servos with PIDs running, in floating point, on the Due, along with several Serial connections to other devices, and Ethernet which is used as both a console port and web server, for controlling the application. This is the first problem I've had in almost 6 months of use. Everything else has been rock-solid.

Regards, Ray L.

$14? May I ask where? :)

That is the performance increase I was hoping for. Thanks for your help also. I bumped your karma. Nice work!

Tim,

Look on E-Bay. Prices vary, but under $20 was pretty common when I bought the ones I have.

Regards,
Ray L.