Ethernet startup problems

Hi people!

I've got a very wierd behaviour with an official Ethernet shield: when I powerup the boards (Duemilanove + Ethernet shield) using external power (12V, but I've tried with 9V with the same results), the shield never wakes up working. It does one of these:

  1. The LINK LED start flashing quickly (about 4 Hz), the 100M, FULLD and RX LEDs are always on, and the shield doesn't work. It never recovers. I see the TX LED flash when sending data, but no activity on the network.

  2. The LEDs (100M, FULLD, LINK) go on and off, just as if the board is alwas reseting itself. It never recovers.

1 is the most common by far. Sometimes, it goes from #1 to the other after a few seconds.

In both cases, a manual reset (on the reset button) seems to cure the problem.

I have no idea why this is happening, I've searched the forums and the Net, but found nothing on this. Is there somewhere I can read about the Ethernet shield's behaviour on error? Do you have any ideas or sugestions? I can post code is needs be (it's a bit long, and only opens a couple of Client and a Server).

Thanks!

Óscar Sarabando

An additional info: when connecting the USB cable to the board, it always powers up well! Strange…

Óscar

Hmmmm, I thought it was just me. :)

Exactly the same problem, it refuses to start up cleanly on external power, but works fine after pressing the reset button.

I'm posting the code, should someone want to take a look.

Environment: I have a simple telemetrics system, based on a router and an Ethernet I/O module. I poll the module via Internet. What I'm trying to do is to replace the ("stupid") I/O module with an Arduino. This Arduino (in practice, an Arduclema with an ATMEGA168, although I have tested with a ATMEGA328-based Duemilanove with the same results) will be playing the role of smart I/O module; not only responding to requests, but automatically sending data with a set frequency. It also has a small command line, to change some configuration.

The code was based on the standard examples. If you find something in the code that can make this erroneous startup behavior, please let me know!

(OOooops, the code is too long to post here... I'll break it up).

Thanks!

/*
 * Wayward Soul - Módulo de Telemetria
 *
 * Um módulo Ethernet para a telemetria, 
 * com capacidade para fazer reboots a quente ao router, caso se perca a ligação à Internet.
 * Responde com dados das entradas analógicas, ou com as entradas do 6017.
 * Pode ser configurado para enviar os valores analógicos para um servidor com uma determinada cadência.
 * Cadencia: 10 min = cerca de 540KB por mes
 * Tem uma linha de comandos simples, em telnet, que permite configurar, ler valores, sacar logs, mudar estado, etc.
 * Guarda logs da abertura e fecho da porta do quadro, das percas e restabelecimentos de ligação à Internet, etc.
 * Guarda dados quando nao tem ligacao a Internet, depois envia-os a pedido.
 */

#include <Ethernet.h>
#include <PString.h>


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 50 };
byte netmask[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 1, 1 };

Server server(2023);

byte router[] = { 192, 168, 1, 1 }; // Router
Client client(router, 23);
byte cas[] = { 213, 228, 166, 27 }; // Servidor da RNM 213.228.166.27
Client clienteAutosend(cas, 22020);
byte cl[] = { 213, 228, 166, 27 }; // Servidor da Progresso 85.10.128.150, progresso.pt ; Formula9: 213.228.166.27
Client clienteLink(cl, 80);

long rollovers = 0;
boolean rebootActivated = true;
int i;
char comandoBuffer[29];
int posicao = 0;
PString comando(comandoBuffer, sizeof(comandoBuffer));

boolean autosend = false;

boolean linkUp = true;
int falhas = 0;
unsigned long linkContador = 0;
unsigned long cadenciaLink = 180000;
unsigned long oldmillisLink = 0;




void setup()
{
  //clearBuffer();
  oldmillisLink = millis();
  linkContador = 0;
  falhas = 0;

  Serial.begin(9600);

  Serial.println("Wayward Soul - Modulo de Telemetria");
  Serial.println("V0.8 - 2009 - Oscar Sarabando");
  Serial.println();
  
  //delay(3000);
  
  Ethernet.begin(mac, ip, gateway, netmask);
  server.begin();
  //clienteLink = Client(cl, 80);

  if (rebootActivated)
  {
    Serial.println("A esperar 20 segs...");
    Serial.println();

    for(i=20 ; i>0 ; i--)
    {
      Serial.print(i);
      Serial.print("...");
      delay(1000);
    }
    Serial.println();
  
    // ===========  Fazer Reboot ao Router por causa do modem ZTE MF636DB
    rebootRouter();
  }
  
  Serial.println("Inicializada!");  
}





void loop()
{
  // ======================== Verificar ligação Internet do Router =========================
  // Fazer reboot ao Router se não tiver ligação Internet há mais de X minutos
  // Testa a ligação ao servidor da Progresso, com uma página de teste mínima
  // Se não conseguimos ligação X vezes, fazer reboot ao router por telnet
  
 
    // Handle rollover do contador
    if ( millis() < oldmillisLink )
    {
      oldmillisLink = millis();
      //linkContador = 0;
      rollovers++;
    }
    
    // Verify event happened
    linkContador += (millis() - oldmillisLink);
    oldmillisLink = millis();
    
    if (linkContador > cadenciaLink)
    {
      linkContador = 0;
      Serial.println("------------");
      Serial.println(millis());
      Serial.println(rollovers);
      Serial.println("A testar o link...");
      
      // Tentar ligar ao servidor
      boolean linkTest = false;
      
      if (clienteLink.connect()) 
      {
        Serial.println("Link bom!");
        linkTest = true;
        linkUp = true;
        falhas = 0;
        //clienteLink.println("GET /telemetria/telem.html HTTP/1.0");
        //clienteLink.println();
        clienteLink.stop();
      } 
      else 
      {
        falhas++;
        linkTest = false;
        Serial.print("************* Falha ");
        Serial.print(falhas);
        Serial.println(" no link!");
        linkUp = false;
      }
      
      
      // Se falhou 4 vezes, faz reboot ao router
      if (!linkTest && (falhas > 3))
      {
        Serial.println("************* Quarta falha! Rebooting.");
        rebootRouter();
        linkUp = true;
        falhas = 0;
      }
      
      
      // AUTO SEND
      if (autosend)
      {
        if (clienteAutosend.connect()) 
        {
          Serial.println("Ligado ao servidor.");
          clienteAutosend.println(millis());
          Serial.println("Enviado!");
          clienteAutosend.stop();
        } 
        else 
        {
          Serial.println("*************** Autosend falhou!");
        }
      }
    }  

 
  // ======================== LER as Analogicas do 6017 para RAM (every X secs) =========================
 
  

  
  // ======================== LOGS na EPROM (reboots por power loss e reboots ao router) =========================

  
  
  // ======================== PEDIDO: LOGS =========================


  
  
  // ======================== PEDIDO: Entradas Analógicas por Ethernet WEBSERVER =========================
  /*
  Client clientWeb = server.available();
  if (clientWeb) 
  {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    while (clientWeb.connected()) {
      if (clientWeb.available()) {
        char c = clientWeb.read();
        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        if (c == '\n' && current_line_is_blank) {
          // send a standard http response header
          clientWeb.println("HTTP/1.1 200 OK");
          clientWeb.println("Content-Type: text/html");
          clientWeb.println();
          
          // output the value of each analog input pin
          for (int i = 0; i < 6; i++) {
            clientWeb.print("Entrada analogica ");
            clientWeb.print(i);
            clientWeb.print(" : ");
            clientWeb.print(analogRead(i));
            clientWeb.println("
");
          }
          break;
        }
        if (c == '\n') {
          // we're starting a new line
          current_line_is_blank = true;
        } else if (c != '\r') {
          // we've gotten a character on the current line
          current_line_is_blank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    clientWeb.stop();
  }
  */
  // ======================== TELNET: Comandos por TELNET =========================
  //    ATENÇÃO!!!!!! Enquanto a sessão TELNET está activa, o microcontrolador não continua o loop!
  //       Não faz mais nada, nem recebe outro cliente!
  Client cliente = server.available();
  if (cliente)
  {
    boolean current_line_is_blank = true;
    while (cliente.connected()) 
    {
      if (cliente.available()) {
        char c = cliente.read();
        Serial.print(c);
        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        if (c == '\n' && current_line_is_blank) 
        {
          // send a standard http response header
          Serial.println("EXIT!!!");
          Serial.println();
          break;
          // output the value of each analog input pin
          /*
          for (int i = 0; i < 6; i++) {
            cliente.print("Entrada analogica ");
          }
          */
        }
        if (c == '\n') 
        {
          boolean comandoBom = false;
          // we're starting a new line, so end command string
          current_line_is_blank = true;
          //comandoBuffer[posicao] = '\0';
          //comando.println();
          posicao = 0;
          
          // Respond
          
          //Serial.print("** Comando desconhecido **");
          Serial.print("Comando : ");
          Serial.println(comando);
          //cliente.print("Comando : ");
          //cliente.println(comando);
          

          // Ligar autosend
          if (comando == "autosend on")
          {
            autosend = true;
            cliente.println("Autosend ligado.");
          }
          
          // Desligar autosend
          if (comando == "autosend off")
          {
            autosend = false;
            cliente.println("Autosend desligado.");
          }
          
          
          // Modificar cadencia
          
          // Modificar servidor de destino (???????)
          
          // Modificar porta de destino (???????)
          
          
          // Reboot Router
          if (comando == "reboot router")
          {
            int t = 0;
            t = rebootRouter();
            if (t == 0)
            {
              cliente.println("Reboot realizado.");
            }
            else
            {
              cliente.println("Erro a fazer reboot!");
            }
          }
          
          
          // Enviar dados das entradas analógicas
          if (comando == "analog")
          {
            for (int i=0; i<6 ; i++)
            {
              cliente.println( analogRead(i) );
            }
          }
          
          
          // Enviar dados de timing/rollovers
          if (comando == "millis")
          {
            cliente.println( millis() );
            cliente.println( rollovers );
          }
          

          cliente.println();

          comando.begin();
        } 
        else if (c != '\r') 
        {
          // we've gotten a character on the current line
          if (posicao < 28)
          {
            //comandoBuffer[posicao] = c;
            comando.print(c);
            posicao++;
          }
          else
          {
            comandoBuffer[0] = '*';
            comandoBuffer[1] = '*';
            comandoBuffer[2] = '\0';
          }
           
          current_line_is_blank = false;
        }
      }
    }
    cliente.stop();
    delay(1);
  }
  
  
}



void clearBuffer()
{
  for (int i=0 ; i<29 ; i++)
  {
    comandoBuffer[i] = 0;
  }
}



int rebootRouter()
{
            Serial.println("A ligar ao router...");

            if (client.connect()) 
            {
              Serial.println("Ligado.");
    
              delay(1000);
              client.println("dea710");    
    
              Serial.println("Rebooting router...");   
              delay(1000);
              client.println("sys reboot");
              Serial.println("Done!");
              client.stop();
              return 0;
            } 
            else 
            {
              Serial.println("Ligacao falhou!");
              return 1;
            }
}

I solved the problem! ;D

I used this thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1258355934/1#1

Although they were using LadyAda's shield, I used the official shield because that's what I can get easily here in Portugal. ;)

The trick is to bend the reset pin of the shield (so that it does not connect to the Arduino header) and connect a digital output to the reset pin of the shield.

Then, just reset the shield programmatically whenever you think you need to. I do it everytime I boot, and everytime I loose connection to the Internet.

Hope this helps someone!

Have fun!

Óscar