Arduino + Ethernetshield lockup

Greetings and Merry Christmas,

I have a problem that I am hoping some fine Gentleman/Lady could help me with. I have recently started dabbling in the Internet Of Things, so I wrote a small bit of code, that I found on a very helpful online tutorial, that reads a pot and operates a servo. The code seems to work fine in the start then locks up after a bit, it also doesn’t seem to load on mobile web browsers. Would you be so kind as to have a look and give me advice on where it is going wrong.

P.S. If anyone could explain to me how I would be able to control the servo position with a slider that would also be appreciated.


#include <Servo.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#define REQ_BUF_SZ 60

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 0, 0, 20); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80
Servo Valve1;
File webFile;
char HTTP_req[REQ_BUF_SZ] = {0};
char req_index = 0;

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

  Serial.begin(9600);       // for debugging
  Valve1.attach(9);

  // 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.");
  Ethernet.begin(mac, ip);  // initialize Ethernet device
  server.begin();           // start to listen for clients
}

void loop()
{
    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, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        Valve();
                        // 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)
}



void Valve()
{
  if (StrContains(HTTP_req, "Valve=2"))
  {
    Valve1.write(0);
  }
  else if (StrContains(HTTP_req, "Valve=1"))
  {
    Valve1.write(80);
  }
  else if (StrContains(HTTP_req, "Valve=0"))
  {
    Valve1.write(160);
  }
}

void XML_response(EthernetClient cl)
{
  int analog_val;

  cl.print("<?xml version = \"1.0\" ?>");
  cl.print("<inputs>");
  analog_val = analogRead(A5);
  cl.print("<sw_an_data>'");
  cl.print(analog_val);
  cl.println("</sw_an_data>");
}


// 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;
}

void StrClear(char *str, char length)
{
  for (int i = 0; i < length; i++) {
    str[i] = 0;
  }
}

<!DOCTYPE html>
<html>
 <head>
     <title>Servo Control and Sensor Data</title>
     <script>
         strValve = "";
         var Flow = 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) {
                             document.getElementById("sw_an_data").innerHTML = this.responseText;
                         }
                     }
                 }
             }
             request.open("GET", "ajax_inputs"+ strValve + nocache, true);
             request.send(null);
             setTimeout("GetArduinoIO()", 1000);
         }
         function SetStateOpen()
         {
             strValve = "&Valve=2"
         }
         function SetStatePartial()
         {
             strValve = "&Valve=1"
         }
         function SetStateClosed()
         {
             strValve = "&Valve=0"
         }
     </script>
 </head>
<body onload="GetArduinoIO()">
    <h1>Flow and Valve control</h1>
    <div id="sw_an_data">
    </div>
    <h2>Control</h2>
    <button id="Open" onclick="SetStateOpen()">Open Valve</button>

    <button id="Partial" onclick="SetStatePartial()">Partially Open Valve</button>

    <button id="Close" onclick="SetStateClosed()">Close Valve</button>

</body>
</html>

Is this device exposed to the internet? If so, you could be losing all your sockets. Your code will also lock up if the client does not send a blank line.

The device runs of the local network, its plugged in directly to the router and is accessed with internal IP. I want to get it up and running first before I port forward and connect it to the web.

Put some println debug calls in it and determine where it is locking up.

P.S. If anyone could explain to me how I would be able to control the servo position with a slider that would also be appreciated.

Attached is a zip file with servo slider files from a past project. The files are served from the SD card on the ethernet shield. The sliders may not work just the way you want as you position the slid3r then send the position command.

slider files.zip (6.11 KB)

From what I can tell, the lock up seems to be due to it not initiating a new line for some reason it just keeps writing to the same line adding text to it.

Also thanks heaps for those files, they will help a lot.