Arduino Due and Ethernet Shield R3 -- Please help!

I've been trying to get this working for a couple weeks, reading everything I can find, and trying things I think up on my own. All with no success so far. My code works without modification on the Mega but not on the Due.

My hardware is simple: Mega plus Ethernet Shield and a Due plus Ethernet Shield (no jumpers or other connections).
Arduino code is 1.5.2 (I've also tried 1.5.3, .4,and .5 with same results).

My code is simple too.

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

byte mac[] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6 };
IPAddress localIP_Address(10, 1, 2, 3);
IPAddress localIP_Gateway(10, 1, 2, 1);
IPAddress localIP_SubnetMask(255, 255, 0, 0);
IPAddress localIP_DNSServer(8, 8, 8, 8);

void setup() 
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  
  // start the Ethernet connection:
  Serial.println("Trying to get an IP address using DHCP");
  if (Ethernet.begin(mac) == 0) 
  {
    Serial.println("Failed to configure Ethernet using DHCP");

    // initialize the ethernet device without using DHCP:
    Ethernet.begin(mac, localIP_Address, localIP_Gateway, localIP_SubnetMask);

  }
  Serial.println("Success!");

  // Show me the IP Address.
  Serial.println(String(Ethernet.localIP()[0])+"."+String(Ethernet.localIP()[1])+"."+String(Ethernet.localIP()[2])+"."+String(Ethernet.localIP()[3]));

}

void loop() 
{

}

I compile and download to the Mega and it works. I see the DHCP Assigned address and no failure message.
Then I change the board type and serial port to the Due and move the ethernet cable.
It compiles and downloads, but "hangs" at the "Trying to get an IP address using DHCP" prompt.

Other folks seem to have the Ethernet Shield working on the Due, so perhaps it's me. A little nudge in the right direction would much appreciated.

Thanks,

Kevin

Hi Kevin,

It's been a few months since I've used this code... However, it worked fine back then:


Init:

#include <Arduino.h>
#include <include/twi.h>
//#include <Wire.h>
#include <SPI.h>    // Required for Ethernet
#include <Ethernet.h>

// printing to the ethernet output
#define ETH_STR_BUFF 200
String Eth_Str = "";
char Outs[ETH_STR_BUFF] = "";

const int SERVER_PORT = 6789;
//unsigned char mac[] = {0xde, 0xad, 0xbe, 0xef, 0xfd, 0xec};
//unsigned char ip[]  = {129, 0, 0, 178};

// ETHERNET
const char Use_DHCP = 0;  //set to 0 to use a fixed IP address, specified below.

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// Otherwise, make one up...
// Fake MAC addresses should have a 2, 6, A, or E as the 2nd digit, in the first 
// group of numbers.  The rest of the digits can be random.
//  The last digit is a function of dio pin-state (see below, and setup()).
// NER LAN expects acs like: {0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, where the last
//  group can be 0x00 to 0x0f.
byte mac[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00};

#define pin_mac0 22
#define pin_mac1 23
#define pin_mac2 24
#define pin_mac3 25

//When this gadget is on an 192.168 net, start at this address (like 192.168.0.100)
// Modified in Setup()
// Use this IP address if DHCP fails, or is disabled. 
#define PRIVATE_IP_OFFSET 50  
byte ip[] = {192, 168, 0, PRIVATE_IP_OFFSET};

// If all pin_mac's are left floating, then id will = 15, and it is assumed that we're in
//  "development mode" on NER's LAN.
#define DEVELOPMENT_IP {129, 0, 0, 180}

byte subnet[] = {255, 255, 255, 0};

//This board:
EthernetServer server = EthernetServer(6789);
//Who's talking to us:
EthernetClient client;

Setup:

// ------------------------------------ ------------------------------------
//  SETUP
// ------------------------------------ ------------------------------------
void setup() {
//these pins assign this pcb it's id, all high = default 
  pinMode(pin_mac0, INPUT_PULLUP);
  pinMode(pin_mac1, INPUT_PULLUP);
  pinMode(pin_mac2, INPUT_PULLUP);
  pinMode(pin_mac3, INPUT_PULLUP);
  
  
  // Init GP DIO as all inputs
  for (i = 0; i <=2; i++){
    for (j = 0; j <=7; j++) {
      pinMode(Port_pins[i][j], INPUT_PULLUP);  
    }
  }
  
  // Init Output String
  i = Eth_Str.reserve(ETH_STR_BUFF);
  if (i < 1) {
    Serial.println(" ERROR! Not eneough memory (Eth_Str).");
    while(true){}
  }    
  //---------------------
  //ETHERNET -----------
  if (digitalRead(pin_mac0)==HIGH) {id+=1;}
  if (digitalRead(pin_mac1)==HIGH) {id+=2;}
  if (digitalRead(pin_mac2)==HIGH) {id+=4;}
  if (digitalRead(pin_mac3)==HIGH) {id+=8;}
  if (Debug_Serial) {
    Serial.print("My ID# (from Pins ");
    Serial.print(pin_mac3);
    Serial.print("..");
    Serial.print(pin_mac0);
    Serial.print("): ");
    Serial.println(id,DEC);
  }
  if (id > 15) {
    if (Debug_Serial) {
      Serial.print("Board id is mangled (got: ");
      Serial.print(id, DEC);
      Serial.println(").  Seting board id to 15.");
    }
    id = 15;
  }
  mac[5] = id;
  if (Debug_Serial) {
    Serial.print("Assigning MAC to: ");
    Serial.print(mac[0],HEX);
    for (i=1;i<6;i++){
      Serial.print(" : ");
      Serial.print(mac[i],HEX);
    }
    Serial.println(" ");
  }

  if (Use_DHCP == 1) {
    DBG_PRINTLN("Waiting for response from DHCP server...");
    dhcp_ok = Ethernet.begin(mac);
    if ((dhcp_ok == 1)&&(Debug_Serial)) {
      Serial.println("Network address received from DHCP server.");
    } else {
      Serial.println("Tried, and failed to configure Ethernet using DHCP.");
    }  
  }
  if ((Use_DHCP == 0) || (dhcp_ok == 0)) {
    DBG_PRINTLN("Using fixed network settings.");
    if (id <15) {
      ip[3] = PRIVATE_IP_OFFSET+id;  // last ip is an indication if location/id
    } else {
      ip = DEVELOPMENT_IP;
    }
    Ethernet.begin(mac, ip);  
  }

  // print the local IP address:
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Port: ");
  Serial.println(SERVER_PORT, DEC);
  // End ETHERNET Setup
  delay(1000);  // 1 second.

  server.begin();

Main:

// ------------------------------------ ------------------------------------
//  MAIN LOOP
// ------------------------------------ ------------------------------------

void loop() {
  while(1) {
    client = server.available();
    if(!client) {
      continue;
    }
    while(client.connected()) {
      toggle_led();
      service_client();
    }
  }
}

Ethernet service:

//******************************************************
// If an Ethernet client is talking to us, process its input
//******************************************************
void service_client(){
  int i;
  Error_Code = 0;
  Numeric_Error = 0;
  
  if(!client.available())
    return;

  if(fetch_input() < 1) {
    //DBG_PRINTLN("Client was detected, but no commands were found.");
    return;
  }
  if (Error_Code > 0) {
    DBG_PRINT("service_client: Warning, data lost. Error Code: ");
    DBG_PRINTLN(Error_Code);
    return;
  }
  //Start processing the input commands
  Cmd = Params[0][0];
  //upcase cmd for ease of use...
  if ((Cmd >= 97) && (Cmd <=122)) {
    Cmd = Cmd - 32;
  }
  DBG_PRINTLN(Cmd);
  Eth_Str = "{'cmd': '";
  Eth_Str += Params[0];
  switch (Cmd) {
    //case 'A' :  Get_Onboard_ADC();
    //            break;
    case 'C' :  Conf_DIO();  //set each port to either input or output.
                break;
    case 'D' :  Update_Onboard_DAC();
                break;
    case 'F' :  Fetch_I2C_Values();   //read-only, start reading from current location
                break;
    case 'I' :  Read_Onboard_DIO();
                break;
    case 'O' :  Set_Onboard_DIO();
                break;
    case 'Q' :  I2CBus_SoftwareReset();
                break;
    case 'R' :  Read_I2C_Values();   //Transmitt with no Stop bit, restart & read from starting register
                break;
    case 'S' :  Scan_I2C_Bus();      // Scan from <beg> <end> for known interface chips.
                break;
    case 'T' :  Send_I2C_Command();  //Transmitt data to chip at address
                break;
    case 'V' :  Version();
                break;
    case 'W' :  WaitFor_mS();
                break;
    case 'Z' :  Z_Reset_Processor();
                break;
    
    default  :  Error_Code = 1;
                Eth_Str += "', 'err': " ;
                Eth_Str += Error_Code;
                Eth_Str += ", }\n";
                DBG_PRINTLN("service_client(): Invalid input command.  Received: ");
                DBG_PRINT(Cmd);
                DBG_PRINT(" (in decimal: ");
                DBG_PRINT(Cmd, DEC);
                DBG_PRINTLN(").");
  }
  for (i = 0; i<Eth_Str.length(); i++) {
    Outs[i] = Eth_Str[i];
  }
  Outs[i] = 0;
  server.print(Outs);
  
  if (I2C_Reset_Request == 1) {
    I2CBus_SoftwareReset();
    I2C_Reset_Request = 0;
  }
}

Thanks, Chriskner. Your code fails here on the same line as mine. Maybe I have an issue with my copy of the ethernet library, but that should have come with the arduino version correctly. As expected, I must have a local problem that doesn't exist in the wild!

Thanks again,

Kevin

Hello Kevin,
Could you try the code in the following thread? (Reply # 7)
http://forum.arduino.cc/index.php?PHPSESSID=dktfpqt6piohbcludo9i71l242&topic=189348.msg1402905#msg1402905

It worked for me. You could use it to verify your system. Regards!

I've run those recommended and the problem still exists. None of those sketches get past the Ethernet.begin line.

I hung an o-scope on the MOSI and SCK pins with no adapter installed (just the Arduino). The clock is present, but the MOSI signal never changes. I loaded a simple sketch with just the SPI code from the Arduino extended SPI page http://arduino.cc/en/Reference/DueExtendedSPI in order to eliminate all of the adapter and other driver issues. I still see no changes on the MOSI pin.

So it looks like something going on with the SPI Library in v1.5.5 . Although I haven't gotten into the SPI library yet (that's next) I ran the same code on my Mega and I see data on both MOSI and Clock. But of note, the SPI.transfer method takes different parameters when compiling with the Mega versus when compiling for the Due. So those differences give me a direction to proceed.

It's still puzzling that others have not experienced this problem.

If anyone has experience and knowledge of the SPI library for the Due, can you please confirm that there are no additional settings required in sketches in order to get the library functional.

Kevin

You are definitely connected to the 6 pin SPI / ICSP header? Definitely to the right pins?
The SCLK is clocking? But MOSI is doing what (hi-Z? pulled up, pulled down?). What
does the relevant CS pin do? Its either pin 10 or 4.

Kevin,

The SPI pins on the DUE are low-current pins (and therefor more fragile).

Are you sure that they still work? Does the SAM chip seem hot?

I have never done this, but as a test, is it convenient to set MISO or MOSI as DIO, measure its output, while toggling the pin directly from code?

As I understand it, the SPI pins on the header go directly to the SAM chip.

See the navigable PDF here (look in 'BOOKMARKS', click on the net names, zoom in - if needed):
http://forum.arduino.cc/index.php?topic=146574.msg1101238

Regards,

Chris

Thanks all for the suggestions. I had not allowed myself yet to go the CPU failure route yet, although it did cross my mind. The CPU is barely above body temperature, but that doesn't prove anything by itself. Excess heat would certainly suggest a CPU issue, but a cold CPU doesn't rule it out. But at this point, a blown CPU pin is the most logical conclusion. So I ordered another Due.

Meanwhile I have confirmed via the reference design that the SPI pins do indeed route directly to the CPU on the Due, unlike the Mega and other boards. And I am scoping the correct header pins confirmed from the reference design traces and schematics.

One thing I did find interesting... Line 86 in SPI.cpp is commented out. It looks important too! "SPI_Write(spi, ch, _data);" But I un-commented it and saw no difference. Frankly I'm not sure it's the correct file used in the compile. It's in the \libraries\spi\arch\sam\ folder. Also, I haven't traced the other code that is not commented, but it doesn't seem like it writes anything anywhere.

I also just bought a SAM-ICE debugger so I can see inside the CPU an see if it reveals something more. It'll be here next week!

If nothing else, I'm learning a ton about this new toy! I'll share what I learn.

Kevin

Don't comment out that line, that function is inlined just below(*), you'll end up sending
every byte twice!!

(*) well a version of it tailored to the Arduino. SPI_Write() is in libsam

Go back to basics and write a very simple sketch that uses SPI at a low clock speed and
look at the SPI pins again.

Have you looked at the CS pin yet? There's an issue with that that needs ruling out.

Mark,

clarification please.... You said don't comment out that line is SPI.cpp. Did you mean that I should to leave it active or leave it commented and not in use. your context suggests that it correctly commented out.

I maybe wasn't clear -- I didn't comment it out myself. It was commented out already in the file I specified.

...also, I am using a simple SPI-only script and comparing my readings between a Due and Mega (with no shield and with the appropriate code changes) and I clearly see the differences on the O-scope. My new Due arrives Thursday so I expect my next new knowledge to come then!

thx again.

Kevin,

I had the same problem. I used the example code, but not work on my DUE.

The link led on Ethernet Shield did not blink, the vendor told me it is the 3.3V problem.

Did you find the way to solve this problem? Can you share information with me?

Thank you!

Huang

UPDATE:
The RJ45 socket on my Ethernet board is broken. After fix the RJ45 socket, everything is fine.
3.3V is okay for Ethernet board !!

Hi Huang,

I never got my ethernet shield to work, but I think our problems are different.

I can't get any communication with either a standard ethernet shield or a clone from Seeedstudio.com. It's still the same problem as I described earlier. But I solved the problem differently. I designed a new shield that allows connection of a Roving Networks RN-XV Wifly module. I don't get wired ethernet this way, but I got my application working using TCP and UDP as intended.

Unfortunately, I gave up on the Due Ethernet shield connectivity! But actually, my new shield allows me to add up to three seperate wifly's and should also allow Zigbee's and other modules so I actually have more potential with my new shield than I would have with the standard shield.

Maybe I'll sell my shield one day if there is any interest!

I would still like to get the ethernet shield to work, but it's now off my critical path so I'm not sure how much more effort I'll put into it moving forward.

Kevin

I wonder if you tried programming the Due through both the programming and native USB ports?

I found that my Due won't work with the Ethernet port when programmed through the Programming port, but would when through the Native port. The native port however does not want to support the serial console it seems.

Hi Kevin,
While playing with my Due board, I also tried interfacing my hand built Ethernet shield based on Wiznet W5100 chip, but failed on first try.
Then only I realised that Due ISP 6 pins header is not having the required SS or CS pin for Ethernet shield to work, so I routed the D10 pin to this header instead of RST pin previously connected. I believe that this might be the case your are facing right now, not having your shield working. Although, the library for this is tested myself and works great. So, try out and let know. :smiley: