Arduino Ethernet Shield not working continuously in the right way

Hello Experts,

i need support, i am working on project which will perform the below,

  1. Control the light using LDR sensor with the help of relays to connect to high voltage
  2. Control Pump motor On and Off State
  3. the Arduino is connected to router using ethernet shield with web page which enable controlling the previous mentioned cases

the Issue
the LDR is working without no issues, however the webpage some times is working and sometimes not , i do not know the actual reason for this...
it is working once i power it ON but after some time, it is not working and the ping is not working nor the webpage

i am using SD card as well for two images that is displayed on the webpage

this is my code on the arduino

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   60

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 10); // IP address, may need to change depending on network  
byte subnet[] = { 255, 255, 255, 0 };
IPAddress gateway(192, 168, 1, 1);  // assign Gateway to the ethernet
IPAddress dns(8, 8, 8, 8);

EthernetServer server(80);  // create a server at port 80
File webFile;               // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = { 0 }; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer
boolean LED_state[2] = { 0 }; // stores the states of the LEDs
int sensorReading = 0;
int LDR = 0;
int Interrupt = 0;
int Motor_state = 0;
int Night_counter=0 ;
int Day_counter=0 ;

void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);

    SD.begin(4);  // initializing SD card for usage
  //  Serial.begin(9600);       // for debugging

    // initialize SD card
 //   Serial.println("Initializing SD card...");
 //   if (!SD.begin(4)) {
 //      Serial.println("ERROR - SD card initialization failed!");
 //       return;    // init failed
 //  }
 //   Serial.println("SUCCESS - SD card initialized.");
 //   // check for index.htm file
 //   if (!SD.exists("index.htm")) {
 //       Serial.println("ERROR - Can't find index.htm file!");
 //       return;  // can't find index file
 //   }
 //   Serial.println("SUCCESS - Found index.htm file.");

    // switches
    pinMode(2, INPUT);
    pinMode(3, INPUT);
    // LEDs

    pinMode(8, OUTPUT); // to force light on in the morning ,, it can be connected to ULN2003 and same output point as pin 5
    pinMode(5, OUTPUT);  // Normal LDR relay 
    pinMode(6, OUTPUT);  // to force light off in the morning 
    pinMode(7, OUTPUT);  // used to turn ON motor
    pinMode(A5, OUTPUT); // used to turn OFF motor
    pinMode(A4, OUTPUT); // used as help to make one relay up and ethernet chip start working while some relay is up

digitalWrite(5, HIGH);
 digitalWrite(6, HIGH);
 digitalWrite(8, HIGH);

 digitalWrite(7, HIGH);
 digitalWrite(A5, HIGH);
  digitalWrite(A4, HIGH);

// Ethernet.begin(mac, ip);  // initialize Ethernet device
Ethernet.begin(mac,ip,gateway,subnet);

    server.begin();           // start to listen for clients
}

void loop()
{    

  
    LDR_Reading();
    MotorInputState();
    digitalWrite(A4, LOW);
    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // limit the size of the stored received HTTP request
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    // remainder of header follows below, depending on if
                    // web page or XML page is requested
                    // Ajax request - send XML file
                    if (StrContains(HTTP_req, "motor.jpg")) {
                        webFile = SD.open("motor.jpg");
                        client.println("Cache-Control: public,max-age=31536000,immutable");
                        client.println("Content-Type: image/jpeg");
                        client.println("Connection: keep-alive");
                        client.println();
                        if (webFile) {
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    else if (StrContains(HTTP_req, "lamp.jpg")) {
                        webFile = SD.open("lamp.jpg");
                        client.println("Cache-Control: public,max-age=31536000,immutable");
                        client.println("Content-Type: image/jpeg");
                        client.println("Connection: keep-alive");
                        client.println();
                        if (webFile) {
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    else if (StrContains(HTTP_req, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        SetLEDs();
                        // send XML file containing input states
                        XML_response(client);
                    }
                    else {  // web page request
                        // send rest of HTTP header
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                        webFile = SD.open("index.htm");        // open web page file
                        if (webFile) {
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    // display received HTTP request on serial port
           //         Serial.print(HTTP_req);
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                }
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)

    // check the Input values 
    LDR_State_Checker();
}

void LDR_Reading(void)
{
    int ldr = A0;
    sensorReading = analogRead(ldr);
}
  void LDR_State_Checker(void)
{  
    if (sensorReading < 300 && Interrupt == 0)
    { // LED_state[0] = 1;  // save LED state
       Night_counter++ ;  
        LED_state[0] = 1;
        LDR = 1;
          if (Night_counter > 5000) {digitalWrite(5, LOW);  //Makes the LED glow in Dark 
        }
    }
    else if (sensorReading > 300 && Interrupt == 0)
    {  // LED_state[0] = 0;  // save LED state
        Day_counter++;
        LED_state[0] = 0;
        LDR = 0;  
         if (Day_counter > 5000) {digitalWrite(5, HIGH);   //Turns the LED OFF in Light.
        } 
    }
    
if (Day_counter == 8000){
    Day_counter = 0;
    }
if (Night_counter == 8000){
    Night_counter = 0;
    }
}

void MotorInputState(void)
{
    int MotorInputReading = digitalRead(3);
    if (MotorInputReading == 1)
    {
        LED_state[1] = 1;
        Motor_state = 1;

    }
    else if (MotorInputReading == 0)
    {
        LED_state[1] = 0;
        Motor_state = 0;
    }

}

// checks if received HTTP request is switching on/off LEDs
// also saves the state of the LEDs
void SetLEDs(void)
{
    // LED 1 (pin 6)
    if (StrContains(HTTP_req, "LED1=1") && LDR == 1) {
        LED_state[0] = 1;  // save LED state
        digitalWrite(6, HIGH); // will make LDR continue working at night
        Interrupt = 0;
    }
    else if (StrContains(HTTP_req, "LED1=1") && LDR == 0) {
        LED_state[0] = 1;  // save LED state
        digitalWrite(8, LOW); // will force light to turn up at daylight by admin
        Interrupt = 1;
    }
    else if (StrContains(HTTP_req, "LED1=0") && LDR == 1) {
        LED_state[0] = 0;  // save LED state
        digitalWrite(6, LOW); // will turn on the light at night by admin
        Interrupt = 1;
    }
    else if (StrContains(HTTP_req, "LED1=0") && LDR == 0) {
        LED_state[0] = 0;  // save LED state
        digitalWrite(8, HIGH);
        Interrupt = 0;
    }

    // LED 2 (pin 7)
    if (StrContains(HTTP_req, "LED2=1") && Motor_state == 0) { // here to control web page to power on motor by contacting relay 3 sec then disconnect it
        LED_state[1] = 1;  // save LED state for revealing this motor state on the webpage
        Motor_state == 1;  // bec the next connection need the actual state of the motor in the program 
        digitalWrite(7, LOW);
        delay(2000);
        digitalWrite(7, HIGH);

    }
    else if (StrContains(HTTP_req, "LED2=1") && Motor_state == 1) {
        LED_state[1] = 1;  // save LED state
        Motor_state == 1;
    }
    else if (StrContains(HTTP_req, "LED2=0") && Motor_state == 1) {
        LED_state[1] = 0;  // save LED state for revealing this motor state on the webpage
        Motor_state == 0; //  bec the next connection need the actual state of the motor in the program 
        digitalWrite(A5, LOW);
        delay(2000);
        digitalWrite(A5, HIGH);
    }
    else if (StrContains(HTTP_req, "LED2=0") && Motor_state == 0) {
        LED_state[1] = 0;  // save LED state
        Motor_state == 0;
    }
}

// send the XML file with analog values, switch status
//  and LED status
void XML_response(EthernetClient cl)
{
    int analog_val;            // stores value read from analog inputs
    int count;                 // used by 'for' loops
    int sw_arr[] = { 2, 3 };  // pins interfaced to switches

    cl.print("<?xml version = \"1.0\" ?>");
    cl.print("<inputs>");
    // checkbox LED states
    // LED1
    cl.print("<LED>");
    if (LED_state[0] == 1) {
        cl.print("checked");
    }
    else if (LED_state[0] == 0) {
        cl.print("unchecked");
    }
    cl.println("</LED>");
    // button LED states
    // LED3
    cl.print("<LED>");
    if (LED_state[1]) {
        cl.print("on");
    }
    else {
        cl.print("off");
    }
    cl.println("</LED>");
    cl.print("</inputs>");
}

// sets every element of str to 0 (clears array)
void StrClear(char* str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char* str, char* sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);

    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}
</>

And the below is the SD web page file

<!DOCTYPE html>
<html>
    <head>
        <title>Arduino Ajax LED Button Control</title>
        <script>
		strLED1 = "";
		strLED2 = "";
		var LED2_state = 0;
		function GetArduinoIO()
		{
			nocache = "&nocache=" + Math.random() * 1000000;
			var request = new XMLHttpRequest();
			request.onreadystatechange = function()
			{
				if (this.readyState == 4) {
					if (this.status == 200) {
						if (this.responseXML != null) {
							// XML file received - contains analog values, switch values and LED states
							var count;
							// LED 1
							if (this.responseXML.getElementsByTagName('LED')[0].childNodes[0].nodeValue === "checked") {
								document.LED_form.LED1.checked = true;
							}
							else {
								document.LED_form.LED1.checked = false;
							}
							// LED 2
							if (this.responseXML.getElementsByTagName('LED')[1].childNodes[0].nodeValue === "on") {
								document.getElementById("LED2").innerHTML = "LED 2 is ON (D7)";
								LED2_state = 1;
							}
							else {
								document.getElementById("LED2").innerHTML = "LED 2 is OFF (D7)";
								LED2_state = 0;
							}
						}
					}
				}
			}
			// send HTTP GET request with LEDs to switch on/off if any
			request.open("GET", "ajax_inputs" + strLED1 + strLED2 + nocache, true);
			request.send(null);
			setTimeout('GetArduinoIO()', 1000);
			strLED1 = "";
			strLED2 = "";
		}
		// service LEDs when checkbox checked/unchecked
		function GetCheck()
		{
			if (LED_form.LED1.checked) {
				strLED1 = "&LED1=1";
			}
			else {
				strLED1 = "&LED1=0";
			}
		}
		function GetButton1()
		{
			if (LED2_state === 1) {
				LED2_state = 0;
				strLED2 = "&LED2=0";
			}
			else {
				LED2_state = 1;
				strLED2 = "&LED2=1";
			}
		}
	</script>
	<style>
		.IO_box {
			float: left;
			margin: 0 20px 20px 0;
			border: 1px solid blue;
			padding: 0 5px 0 5px;
			width: 120px;
		}
		h1 {
			font-size: 120%;
			color: blue;
			margin: 0 0 10px 0;
		}
		h2 {
			font-size: 85%;
			color: #5734E6;
			margin: 5px 0 5px 0;
		}
		p, form, button {
			font-size: 80%;
			color: #252525;
		}
		.small_text {
			font-size: 70%;
			color: #737373;
		}
	</style>
    </head>
    <body onload="GetArduinoIO()">
        <h1>Arduino Ajax LED Button Control</h1>
		<div class="IO_box">
			<h2>LED Using Checkbox</h2>
			<form id="check_LEDs" name="LED_form">
				<input type="checkbox" name="LED1" value="0" onclick="GetCheck()" />Motor is OFF click to turn ON<br /><br />
			</form>
		</div>
		<div class="IO_box">
			<h2>Light Status</h2>
			<button type="button" id="LED2" onclick="GetButton1()">Light is OFF Click to turn ON</button><br /><br />
		</div>
    </body>
</html>

What sort of Arduino is this being used on? What are the memory usage figures from the build process.?

Before calling client.stop() you have a 1ms delay that you hope will allow the web browser time to receive all the data. Have you considered using client.flush() instead that should make sure all the data has been sent? Not sure this will have anything to do with the main problem, but delays on ethernet when something sends a large amount of data are not uncommon.

arduino UNO is used in this project, regarding client.stop() i think it needs to be increased may be to 1 sec as the arduino UNO is connected to switch and then to router .. i did not really know about client.flush() option can you recommend where to be used in my code ,,
this is the memory usage figure from the build process.....
Sketch uses 21918 bytes (67%) of program storage space. Maximum is 32256 bytes.
Global variables use 1502 bytes (73%) of dynamic memory, leaving 546 bytes for local variables. Maximum is 2048 bytes.

by the way the circuit got freezed even the LDR checking was not working in the morning keeping the light still ON until hard reset then it is off i am not sure why exactly this behavior is happening

You need to be aware that both the SD library and the Ethernet library dynamically allocate buffers that are used when in operation. In both cases these are 512bytes iirc. You only have 546 bytes available, if any function you call allocates memory you are very likely to run into memory problems which can often show themselves as either a system crash or hang (in the first case there is usually an unexplained reboot and in the second everything just appears to stop working) - I suspect you are running out of memory and the system is hanging. Have a look at the FreeRam function this should allow you to check the amount of memory in use dynamically.

I was suggesting replacing the delay before stop with the flush to ensure that all data has gone before stopping. I have to admit to not actually having use this though!

Can you guide where i can check for the free RAM dynamically as i am new to the arduino .. or if you can provide link which illustrate the steps to do this

Have a look here: Arduino Playground - AvailableMemory
Specifically at the freeRam code.

OK, I'll reproduce it here to save future broken links:

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

You call it anywhere you think might be worth checking, such as before and after starting Ethernet, or SD, or a server or client etc. Just insert the line below:

Serial.println(freeRam());

I suggest you print out a comment before that line such as:
Serial.print(F("Calling Ethernet.begin"));

That way you should get any indication around where you might run out of memory.

Hello ,,

I found the freeRAM is always 506 ,, i will update in case it is freezing
i added the client.flush() after delay(500),,
also i changed the code that is used for the cache, i noticed it decreased the latency in the reply and i am not using it now
nocache = "&nocache=" + Math.random() * 1000000;
and also

request.open("GET", "ajax_inputs" + strLED1 + strLED2 , true);
request.send(null);
setTimeout('GetArduinoIO()', 3000);

i changed the Timeout to be 3sec instead of 1sec

but i still do not know the actual root cause for my issue!!

The usual causes of an Arduino to just "stop working" are:
a) Power supply
b) Code issues - especially memory scribbles
c) wiring to external devices

I still suspect a code problem, but you should certainly check out the other common sources of Arduinos "stopping working".

You are controlling a pump via some relays, can you post a picture of the setup and a sketch of the intended wiring. Is there a link to the relays you are using? How are the relays being powered?
Drawing to much power from an Arduino can cause issues. Feedback from relays can cause issues.

Wiring to external devices such as your LDR sensor should be checked to ensure there is no external interference, that all wires are secure with good contacts etc.

Your comment that the FreeRam function always returns 506 is worrying. Can you post the code will all the calls to freeram present?

New update today,,,
i edited what i mentioned before

  1. added the function which gives info. about FreeRam
  2. removed the line for no cache
    nocache = "&nocache=" + Math.random() * 1000000;

3.also for the continous AJAX call i changed the timeout to be 3 sec instead of 1 sec

these changes are not major changes,, the only change that i think it might affect something is that now i am trying while connecting serial communication to my laptop as well as the power is taken from usb port of the laptop ,, After around 8 hours it is the ethernet communication is still working which is really confusing for me ......
i was previously using Chinese adaptor which generate 5v with current 1 amp using usb port

@countrypaul

for you question these are the answers
for the communication of the arduino with the relays i am using these relays

image

the power of the relay is driven from the arduino board
i already tested the circuit with only very Simple LDR code ONLY which conrtol the 5v volt relay and this 5v relay is controlling the magnetic coil of another 220v relay ,, and the 220 volt relay control the neutral line of the light bulb...
so arduino do the following
control 5v relay which control neutral line of 220v coil relay which control the neutral line of the LAMP

the same way is the wiring connection to the pump

when i was testing the setup of relay i tested relays for the LDR and it is actually working perfectly
however my issue is with the remote control using ethernet communication
i don't have any issue with the automatic LDR control neither the code nor the wiring as i tested this separately and it is working as expected

 void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);

    SD.begin(4);  // initializing SD card for usage
    Serial.begin(9600);       // for debugging

    // initialize SD card
 //   Serial.println("Initializing SD card...");
 //   if (!SD.begin(4)) {
 //      Serial.println("ERROR - SD card initialization failed!");
 //       return;    // init failed
 //  }
 //   Serial.println("SUCCESS - SD card initialized.");
 //   // check for index.htm file
 //   if (!SD.exists("index.htm")) {
 //       Serial.println("ERROR - Can't find index.htm file!");
 //       return;  // can't find index file
 //   }
 //   Serial.println("SUCCESS - Found index.htm file.");

    // switches
 //   pinMode(2, INPUT);
    pinMode(3, INPUT);
    // LEDs

    pinMode(8, OUTPUT); // to force light on in the morning ,, it can be connected to ULN2003 and same output point as pin 5
    pinMode(5, OUTPUT);  // Normal LDR relay 
    pinMode(6, OUTPUT);  // to force light off in the morning 
    pinMode(7, OUTPUT);  // used to turn ON motor
    pinMode(A5, OUTPUT); // used to turn OFF motor

digitalWrite(5, HIGH);
 digitalWrite(6, HIGH);
 digitalWrite(8, HIGH);

 digitalWrite(7, HIGH);
 digitalWrite(A5, HIGH);
 
// Ethernet.begin(mac, ip);  // initialize Ethernet device
  //       delay(2000);

delay(3000);   // trying to put delay before enabling 

 pinMode(A4, OUTPUT); // sets the digital pin as output 
 digitalWrite(A4, LOW); 
 delay(1000); //for ethernet chip to reset 
 digitalWrite(A4, HIGH);
 delay(1000); //for ethernet chip to reset
 pinMode(A4, INPUT); // sets the digital pin input
 delay(1000); //for ethernet chip to reset 

 Serial.print(F("Calling before Ethernet.begin"));
 Serial.println(freeRam());
Ethernet.begin(mac, ip, subnet);
delay(2000);
 Serial.print(F(" After Ethernet.begin"));
 Serial.println(freeRam());
server.begin();           // start to listen for clients
}

void loop()
{    
    Serial.print(F("In the begining "));
 Serial.println(freeRam());
  
    LDR_Reading();
 Serial.print(F(" After LDR Reading "));
 Serial.println(freeRam());
    MotorInputState();

  Serial.print(F(" After Motor Input State"));
 Serial.println(freeRam());

    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // limit the size of the stored received HTTP request
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    // remainder of header follows below, depending on if
                    // web page or XML page is requested
                    // Ajax request - send XML file
                    if (StrContains(HTTP_req, "motor.jpg")) {
                      webFile = SD.open("motor.jpg");
                        if (webFile) {
                        client.println("Cache-Control: public,max-age=31536000,immutable");
                        client.println("Content-Type: image/jpeg");
                        client.println("Connection: close");
                        client.println();
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    else if (StrContains(HTTP_req, "lamp.jpg")) {
                      webFile = SD.open("lamp.jpg");                        
                        if (webFile) {
                        client.println("Cache-Control: public,max-age=31536000,immutable");
                        client.println("Content-Type: image/jpeg");
                        client.println("Connection: close");
                        client.println();
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    else if (StrContains(HTTP_req, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        SetLEDs();
                        // send XML file containing input states
                        XML_response(client);
                         Serial.print(F(" After AJAX_input"));
                         Serial.println(freeRam());
                    }
                    else {  // web page request
                        // send rest of HTTP header
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                        webFile = SD.open("index.htm");        // open web page file
                        if (webFile) {
                            while (webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    // display received HTTP request on serial port
           //         Serial.print(HTTP_req);
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                }
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(500);      // give the web browser time to receive the data
        client.flush() ;
        client.stop(); // close the connection
    } // end if (client)

 Serial.print(F("Before Light Control"));
 Serial.println(freeRam());
    // check the Input values 
    LDR_State_Checker();
     Serial.print(F(" After light Control"));
 Serial.println(freeRam());
}


int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void LDR_Reading(void)
{
    sensorReading = analogRead(A0);
}
  void LDR_State_Checker(void)
{  
    if (sensorReading < 100 && Interrupt == 0)
    { // LED_state[0] = 1;  // save LED state 
        LED_state[0] = 1;
        LDR = 1;
       digitalWrite(5, LOW);  //Makes the LED glow in Dark 
       delay(1000);
       // }
    }
    else if (sensorReading > 300 && Interrupt == 0)
    {  // LED_state[0] = 0;  // save LED state
        LED_state[0] = 0;
        LDR = 0;         
          digitalWrite(5, HIGH);   //Turns the LED OFF in Light.
       delay(1000);

    }
}

void MotorInputState(void)
{
    int MotorInputReading = digitalRead(3);
    if (MotorInputReading == 1)
    {
        LED_state[1] = 1;
        Motor_state = 1;

    }
    else if (MotorInputReading == 0)
    {
        LED_state[1] = 0;
        Motor_state = 0;
    }

}

// checks if received HTTP request is switching on/off LEDs
// also saves the state of the LEDs
void SetLEDs(void)
{
    // LED 1 (pin 6)
    if (StrContains(HTTP_req, "LED1=1") && LDR == 1) {
        LED_state[0] = 1;  // save LED state
        digitalWrite(6, HIGH); // will make LDR continue working at night
        Interrupt = 0;
    }
    else if (StrContains(HTTP_req, "LED1=1") && LDR == 0) {
        LED_state[0] = 1;  // save LED state
        digitalWrite(8, LOW); // will force light to turn up at daylight by admin
        Interrupt = 1;
    }
    else if (StrContains(HTTP_req, "LED1=0") && LDR == 1) {
        LED_state[0] = 0;  // save LED state
        digitalWrite(6, LOW); // will turn on the light at night by admin
        Interrupt = 1;
    }
    else if (StrContains(HTTP_req, "LED1=0") && LDR == 0) {
        LED_state[0] = 0;  // save LED state
        digitalWrite(8, HIGH);
        Interrupt = 0;
    }

    // LED 2 (pin 7)
    if (StrContains(HTTP_req, "LED2=1") && Motor_state == 0) { // here to control web page to power on motor by contacting relay 3 sec then disconnect it
        LED_state[1] = 1;  // save LED state for revealing this motor state on the webpage
        Motor_state == 1;  // bec the next connection need the actual state of the motor in the program 
        digitalWrite(7, LOW);
        delay(2000);
        digitalWrite(7, HIGH);

    }
    else if (StrContains(HTTP_req, "LED2=1") && Motor_state == 1) {
        LED_state[1] = 1;  // save LED state
        Motor_state == 1;
    }
    else if (StrContains(HTTP_req, "LED2=0") && Motor_state == 1) {
        LED_state[1] = 0;  // save LED state for revealing this motor state on the webpage
        Motor_state == 0; //  bec the next connection need the actual state of the motor in the program 
        digitalWrite(A5, LOW);
        delay(2000);
        digitalWrite(A5, HIGH);
    }
    else if (StrContains(HTTP_req, "LED2=0") && Motor_state == 0) {
        LED_state[1] = 0;  // save LED state
        Motor_state == 0;
    }
}

// send the XML file with analog values, switch status
//  and LED status
void XML_response(EthernetClient cl)
{
    int analog_val;            // stores value read from analog inputs
    int count;                 // used by 'for' loops
    int sw_arr[] = { 2, 3 };  // pins interfaced to switches

    cl.print("<?xml version = \"1.0\" ?>");
    cl.print("<inputs>");
    // checkbox LED states
    // LED1
    cl.print("<LED>");
    if (LED_state[0] == 1) {
        cl.print("checked");
    }
    else if (LED_state[0] == 0) {
        cl.print("unchecked");
    }
    cl.println("</LED>");
    // button LED states
    // LED3
    cl.print("<LED>");
    if (LED_state[1]) {
        cl.print("on");
    }
    else {
        cl.print("off");
    }
    cl.println("</LED>");
    cl.print("</inputs>");
}

// sets every element of str to 0 (clears array)
void StrClear(char* str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char* str, char* sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);

    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}

Sample of the output

In the begining 506
 After LDR Reading 506
 After Motor Input State506
Before Light Control506
 After light Control506
In the begining 506
 After LDR Reading 506
 After Motor Input State506
Before Light Control506
 After light Control506
In the begining 506
 After LDR Reading 506
 After Motor Input State506
Before Light Control506
 After light Control506
In the begining 506
 After LDR Reading 506
 After Motor Input State506
Before Light Control506
 After light Control506
In the begining 506
 After LDR Reading 506
 After Motor Input State506
Before Light Control506
 After light Control506

i am really suspecting that keeping serial communication with the laptop is making difference with the Arduino and keeping the ethernet channel up but i will test this also today and check the output

If you disconnected the Relay board form the Arduino and temporarily changed the code to simulate an LDR reading and motor input state that might allow you to run the Arduino without any possible interference from the external components. Hopefully the problem would still show up and we could be fairly certain that it is purely a software problem.

You put the Freeram readings around the calls to light control and motor input state, there functions are quite simple and we can see they make no dynamic memory allocation.

I mentioned earlier that Ethernet and SD dynamically allocate memory and that it might be worth checking where that happens, such as before and after starting Ethernet, or SD, or a server or client etc.

I would certainly put it before and after:

EthernetClient client = server.available();
webFile = SD.open("lamp.jpg");

I notice you have a call to freeram after Ajax_input but that is not shown in you output log. Does that mean it was never called in your test, or that the problem showed up before/during that section of code?

Just to clarify, regarding testing the LDR reading,, i did not remove the relays for the LDR i kept it
which means as per the reading of the LDR the real light will go on and off with no issues ..

i will consider putting before and after

EthernetClient client = server.available();
webFile = SD.open("lamp.jpg");

for the time being is there any chance that serial communication with the laptop can add something as i mentioned before??

I realise that you did not remove the relays etc. when you did your tests, that is why I am suggesting you do so and rerun the test. If the problem shows up without the relay card and without your other parts connected it becomes much easier for someone else to reproduce the problem with just their Uno and Ethernet shield (which version do you have?). I have an Uno and Ethernet shield but not the other parts for example.

I suggest you put a call and printout between those lines too so we can see where memory is used (assuming it is).

I would be very surprised if the serial communications have any effect on the problem as serial is used by just about everyone during development and debugging - however because we cannot say what the problem is at present we cannot rule it out completely.

i added the required printout and got the output

In the begining 500
 After LDR Reading 500
 After Motor Input State500
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
 **Before SD OPEN LAMP 500**
** After SD OPEN LAMP 469**
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
 **BeforeSD OPEN MOTOR 500**
** After SD OPEN MOTOR 469**
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
Before Light Control500
 After light Control500
In the begining 500
 After LDR Reading 500
 After Motor Input State500
 After AJAX_input500
Before Light Control500
 After light Control500
In the begining 500

however all the time the circuit is not hanging and working normally..
i am not sure actually where could be the root cause....
could it be the router or the cable connection doing something to the circuit??

I assume you have not disconnected the relay card so it is entirely the hardware setup you first mentioned?

If the above is correct, this is one of those problems that will fall into the very hard to find (if ever) category!

How long did you run it for with no hanging - i.e. working as normally expected?
How long did it run previously before hanging?

If the only change you have made between it running and hanging and running and working normally is to put the extra lines in checking the freeram - then try commenting them out. If the problem corresponds directly with the presence of those lines it will give us a large clue as to what to look for. You will have to try this a few times, I suggest 3 each without the lines and with the lines present. It may be that you find the code changes make no difference and it was just coincidence that adding them occurred at the same time.

Adding extra code can cause the compiler/linker to rearrange things in memory that can sometimes make problems appear or as in this case disappear. Having a definite changes to code that shows/hides the problem is a major advantage even if the piece of code that is changed is not directly involved in the problem. If, for example, there was an error in your code causing it to write beyond the end of an array bound and "scribble" on some other memory, then adding code might make changes to the memory that put a variable in the problem location.

Problems with ethernet should not normally cause a hangup. You should be able to, for example, disconnect the ethernet at the router, wait a few seconds and reconnect it without causing problems with the Arduino (your code may not deal with it but that is another problem).

More likely, imho, is a poor connection with the other hardware, the relay card for example. Have you move any wires connecting things that could explain things? I would try Not to change anything at all on the hardware side until you have tested whether those lines of code do have a direct effect on whether your system hangs up or not.

A problem with the router is unlikely (but not impossible) to cause the sort of effect you have described. Normally if a router starts sending out bad packets that will effect everything on the network and show up in multiple places, you could check the event log on your PC to see if anything strange has occurred though.

@countrypaul ,, i am not connecting any component while performing the test ,, just the arduino UNO and ethernet shield however yesterday i found it hanged
it was connected to external power source
now i pluged it with my laptop usb port and will keep monitoring it

@countrypaul any idea for what might be going on ,, i am not expert in coding but i can understand what every function in code is doing and am not able to see any error in the code!!

As I have said, my first suspicion was that of a memory problem, but that appears to be less likely given what you have said.

Since you have now tried with no components other than the Ethernet shield connected, the quality of the power supply needs to be considered imho. Often PC USB ports only deliver 500ma power (so I have been told) so using an external PS is often a good idea. If the power supply is the problem then attaching more devices powered through the Arduino power supply can make things worse. What is your external power source that you have tried?

Can you provide a link to the LDR and also the supply of the relay shield (there are many that look the same so to make sure we are referencing the same one). We can then check on how much power is likely to be used and whether the power supply will suffice (including how it is utilised). We have seen cases where the power supply is good but with everything wired through the Arduino there is a further limit that shows itself with apparent random effects.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.