Ethernet Shield Delay When Disconnected

Hi, I am currently using an ethernet shield w5100 and a 433mhz receiver with Arduino Mega, configured with static IP. The mega is connected to a set of relays, which I can control over a LAN or a 433mhz transmitter(virtualwire library). Everything works perfectly in this scenario, the 433 receiver is very responsive to the commands of the transmitter as long as there is an ethernet connection. However, when the ethernet cable is unplugged from the ethernet shield, or when the router loses power, the 433 transmitter receiver becomes erratic. Sometimes it responds to commands to turn the relay on/off, sometimes it doesn't. The result has become intermittent, say for every 3-5 button presses, the receiver then processes the signal to the relay.

I believe this is due to the ethernet shield attempting to re-establish a connection, with some delay commands in place within the libraries. I've searched through the ethernet libraries to comment out the delays for testing, but to no avail. I also read a thread on DHCP which will cause the arduino to to "freeze" for 60 seconds if it is not able to acquire an IP, but I am not using DHCP.

Any insight on this greatly appreciated. Thanks in advance.

There is a delay when the w5100 tries to establish a connection of about 1.6 seconds. Is that what you mean? You can reduce that to about 200ms. Would that help? Here is a post on how to do it.
http://forum.arduino.cc/index.php?topic=181284.msg1343940#msg1343940

Thanks for the reply Tim, the situation in that post sounds very similar to mine. However, I just tried adding the code and afraid it is still not working.

askduino:
Thanks for the reply Tim, the situation in that post sounds very similar to mine. However, I just tried adding the code and afraid it is still not working.

Then you should post your code.

Here is the simplified version of the code which I have tried and tested to have the same result as the full code. The full code contains a lot of html which makes it hard to look at.

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 
  0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192,168,1,111);
EthernetServer server(88);
#include <VirtualWire.h>
#define numOfDevices 16

byte deviceNumber[numOfDevices] = {
  43, 42, 37, 40, 38, 39, 49, 41, 48, 34, 35, 36, 44, 45, 46, 47 
};
String deviceName[numOfDevices] = {
  "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Pin 34", "Pin 35", "Pin 36", "Pin 44", "Pin 45", "Pin 46", "Pin 47"
};

void setup() 
{

  for( int i = 0; i < numOfDevices; i++)
  {
    pinMode(deviceNumber[i], OUTPUT); 
    digitalWrite(deviceNumber[i], HIGH);
  } 
  
  vw_set_rx_pin(25);   
  vw_setup(1500);
  vw_rx_start(); 

  Ethernet.begin(mac, ip);
  server.begin();  
}

void loop() 
{
  uint8_t buf[2];
  uint8_t buflen = 2;   

  if (vw_get_message(buf, &buflen))
  {
    String receivedMessage;        

    for (int i = 0; i < buflen; i++)
    {            
      receivedMessage += char(buf[i]);       
    }

    int receivedNum = receivedMessage.toInt();

    if( digitalRead(deviceNumber[receivedNum]) == HIGH )
    {
      digitalWrite(deviceNumber[receivedNum], LOW);
    }
    else
    {
      digitalWrite(deviceNumber[receivedNum], HIGH);
    }
  }

  EthernetClient client = server.available();

  if (client) 
  {  
    String input = "";
    boolean currentLineIsBlank = true;    

    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        input += c;

        if (c == '\n' && currentLineIsBlank) 
        {          
          input.replace("%20", " ");
          input = input.substring(input.indexOf("GET")+5, input.indexOf("HTTP")-1);

          if( input.endsWith("/") == true )
          {
            input = input.substring(0, input.length()-1);
          }

          if( input.substring(0,1).equals("?") )
          {            
            input = input.substring(1);

            for(int i = 0; i < numOfDevices; i++)
            {
              if( input.equalsIgnoreCase(deviceName[i]) )
              {    
                if( digitalRead(deviceNumber[i]) == LOW )
                {
                  digitalWrite(deviceNumber[i], HIGH);
                }
                else
                {
                  digitalWrite(deviceNumber[i], LOW);
                }
                break;           
              }                
            }
          }          
           break;
        }
        if (c == '\n') 
        {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') 
        {
          currentLineIsBlank = false;
        }
      }
    }    
    client.stop();
  }
}

That code is abbreviated! You even removed the section of code I recommended in my first post.

// add this to the includes
#include <utility/w5100.h>

   // in setup() after Ethernet.begin(), call this function.
   W5100.setRetransmissionCount(1);
  uint8_t buf[2];
  uint8_t buflen = 2;   

  if (vw_get_message(buf, &buflen))
  {
    String receivedMessage;        

    for (int i = 0; i < buflen; i++)
    {            
      receivedMessage += char(buf[i]);       
    }

Do you really need to piss away resources on a String to wrap a string that contains 2 characters? Get real.

Tim, like I said your solution DID NOT WORK, that was why I reverted to the original code.

Paul, memory isn't critical to me for this application, so it doesn't really matter to me. It's not like I'm writing code for NASA or something. If picking on these small things unrelated to the question makes you feel a like bigger man, you're welcome.

askduino:
Tim, like I said your solution DID NOT WORK, that was why I reverted to the original code.

Did not work? Maybe you should be more specific. Does it crash? Does it delay for a few minutes? Does it let out the magic smoke?

How long is the delay when your network connection fails?

edit: Never mind. If you are using server code, and you break the connection, any delay on your web browser would be dependent on the web browser, not the server code on the Arduino.

SurferTim:
Did not work? Maybe you should be more specific. Does it crash? Does it delay for a few minutes? Does it let out the magic smoke?

How long is the delay when your network connection fails?

Sometimes it responds to commands to turn the relay on/off, sometimes it doesn't. The result has become intermittent, say for every 3-5 button presses, the receiver then processes the signal to the relay.

In layman's terms, randomly. When the button is pressed on the transmitter, it does not work every single time, as when the ethernet cable is plugged in. More like by chance.

You do not need to use "layman's terms". I understand both "programmer" and "network specialist" terms.

I recommend putting a few serial.println() calls in there to determine exactly where the delay is occurring. If there is no cable, the server.available() call will never evaluate to true, and the rest of that code will not run.

edit: The w5100 does not know if the CAT5 cable is disconnected or the router is down. It does not have that capability. It only checks the sockets for a client connection. If there is no network connection, the listening socket will not get a client connection, and server.available() should immediately return false.

If the connection breaks while the client is sending the request, and doesn't get to send the blank line, the code will freeze there in an infinite loop.

I appreciate the time Tim, but I would also appreciate if you could read clearly what I have already posted, as you are asking to repeat things that are already said. If the LAN cable is disconnected, the "rest of the code" doesn't really matter anymore if it runs, as that is the "server" part of the code. The part that matters in the portion above for the 433 receiver code. Serial.println shows consistent running of the code, it did not pause anywhere at all.

In addition to your edit:
When no client has connected to the server before, the problem is already apparent. ie. the transmitter is tested straight from the Mega's reset. And if say it does get stuck in a infinite loop, then pressing the button on the transmitter should not activate any relays again. But in this situation it does, only randomly. So I am sure it is not stuck in an infinite loop.

I'm not sure I understand your problem. If the server part of the code is not running, then you should not get a delay unless it is the 433 part of the code.

Are you certain it is not caused by the cable being disconnected while in the "if(client)" part of the code? I can see how that could cause a delay.

I'm not sure I understand your problem. If the server part of the code is not running, then you should not get a delay unless it is the 433 part of the code.

Yes, that is why I am baffled too.

Are you certain it is not caused by the cable being disconnected while in the "if(client)" part of the code? I can see how that could cause a delay.

Yes, I left the cable unplugged, reset the Arduino and then tried the transmitter.