I'm using a SainSmart Wiznet W5100 ethernet shield and an Arduino Uno to try to create a webserver that reads POST information sent by a form and interprets the information to control the turning on and off of lights at specific times. The problem I am having is that the WebServer is being inconsistent. Here is my code I am using:
#include <SPI.h>
#include "Ethernet.h"
// Ethernet library configuration
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 0, 222 }; // ip in lan
EthernetServer server(82); //server port
// HMTL processing variables
String readString = ""; //string to get incoming data
char c;
char buffer[10];
int dataLength =0;
// Buffer containing processed hmtl data
char data[50];
char datamotor[5];
int index=3;
//Setting the time
int wdstarth = 0;
int wdstartm = 0;
int wdstartp = 0;
int westarth = 0;
int westartm = 0;
int westartp = 0;
int wdstoph = 0;
int wdstopm = 0;
int wdstopp = 0;
int westoph = 0;
int westopm = 0;
int westopp = 0;
int control = 2;
// Setup function
void setup()
{
Ethernet.begin(mac, ip); //start Ethernet
Serial.begin(9600);
Serial.print("The server is at: ");
Serial.println(Ethernet.localIP());
}
// Loop function
void loop()
{
EthernetClient client = server.available();
if (client)
{
while (client.connected())
{
while (client.available()) // Receive client data
{
Serial.print(".");
c = client.read(); //read char by char HTTP request
readString +=c;
//Serial.print(c); //output chars to serial port
// If first request upon connexion, the 3 first characters will be "GET"
// If "GET" is caught, skip the request info
if( readString.equals("GET"))
{
Serial.println("");
Serial.println("GET caught, skipping request and printing HTML");
break;
}
// Otherwise, if the request contains data,
// the first characters will be "POST"
// We then skip the request header and this "if" becomes our main function
if( readString.equals("POST"))
{
Serial.println("");
Serial.println("POST caught, skipping header and acquiring DATA");
// 320 is arbitrary. The actual length that has to be skipped depends on
// several user settings ( browser, language, addons...)
// the skipped length has not to be too long to skip relevant data
// and not to short to waste computing time
for(int i=0; i<320; i++)
{
c = client.read();
Serial.print(c); // UNCOMMENT FOR DEBUG
}
//Searches for "Length: "
while(c != 'L')
{
c = client.read();
Serial.print(c); // UNCOMMENT FOR DEBUG
}
// Skip "Length: "
for (int i=0; i<7; i++)
{
c = client.read();
Serial.print(c); // UNCOMMENT FOR DEBUG
}
// Read the data package length
readString="";
c = client.read();
while(c != '\n')
{
readString += c;
Serial.print(c);
c = client.read();
}
// convert data read from String to int
readString.toCharArray(buffer, readString.length());
dataLength = atoi(buffer);
Serial.println("");
Serial.print("dataLength: ");
Serial.println(dataLength);
// gets DATA
client.read(); // skips additional newline
client.read();
for (int i=0; i<dataLength; i++)
{
data[i] = client.read();
}
Serial.println("");
Serial.print("data: ");
Serial.println(data);
readString=data;
checkURL(readString);
readString ="";
}
}
// HTML CODE
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connnection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// add a meta refresh tag, so the browser pulls again every 5 seconds:
// client.println("<meta http-equiv=\"refresh\" content=\"5\">");
// print the hour, minute and second:
client.print("<center><table border='1'><tr><td colspan='4' align='center'><b>Omni Systems Outdoor Lights Controller</b></td></tr><tr><td colspan='4' align='center'>");
//FORM
client.println("</td></tr><form method='post'><tr>");
client.println("<td align='center' colspan='2'><b>Weekdays</b></td><td align='center' colspan='2'><b>Weekends</b></td></tr>");
client.println("<tr><td align='center'><b>Start:</b></td><td align='center'><input type='text' name='wdstart' size='7'></td><td align='center'><b>Start:</b></td><td align='center'><input type='text' name='westart' size='7'></td>");
client.println("<tr><td align='center'><b>Stop:</b></td><td align='center'><input type='text' name='wdstop' size='7'></td><td align='center'><b>Stop:</b></td><td align='center'><input type='text' name='westop' size='7'></td>");
client.println("</tr><tr><td colspan='4' align='center'><b>Light Control: ");
client.println("</td></tr><tr><td colspan='4' align='center'><input type='submit' value='Submit Changes'></td></tr></table>");
client.println("</html>");
Serial.println("__________");
delay(100);
client.stop();
}
}
// Reinitializing variables
readString =""; // Reinitialize String
for (int i=0; i<10; i++)
{buffer[i] = '\0';}
for (int i=0; i<50; i++)
{data[i] = '\0';}
for (int i=0; i<5; i++)
{datamotor[i] = '\0';}
dataLength =0;
index = 3;
}
void checkURL(String readString) {
int wdstartindex = readString.indexOf("wdstart=");
int westartindex = readString.indexOf("westart=");
int wdstopindex = readString.indexOf("wdstop=");
int westopindex = readString.indexOf("westop=");
wdstarth = readString.substring(wdstartindex+8, readString.indexOf("%3A")).toInt();
wdstartm = readString.substring(readString.indexOf("%3A")+3, westartindex-1).toInt();
westarth = readString.substring(westartindex+8, readString.indexOf("%3A", westartindex)).toInt();
int colon = readString.indexOf("%3A", westartindex)+3;
int stop = wdstopindex - 1;
westartm = readString.substring(colon, stop).toInt();
wdstoph = readString.substring(wdstopindex+7, readString.indexOf("%3A", wdstopindex)).toInt();
colon = readString.indexOf("%3A", wdstopindex)+3;
stop = westopindex - 1;
wdstopm = readString.substring(colon, stop).toInt();
// westoph = readString.substring(westopindex+7, readString.indexOf("%3A", westopindex)).toInt();
// colon = readString.indexOf("%3A", westopindex)+3;
// stop = readString.length()-1;
// westopm = readString.substring(colon, stop).toInt();
Serial.print("Weekday Start Time: ");
Serial.print(wdstarth);
Serial.print(":");
Serial.println(wdstartm);
Serial.print("Weekend Start Time: ");
Serial.print(westarth);
Serial.print(":");
Serial.println(westartm);
Serial.print("Weekday Stop Time: ");
Serial.print(wdstoph);
Serial.print(":");
Serial.println(wdstopm);
// Serial.print("Weekend Stop Time: ");
// Serial.print(westoph);
// Serial.print(":");
// Serial.println(westopm);
}
The problem I am having is the last method, checkURL(). What it does is interpret the readString, which is the POST data, and set variables equal to the values found in the string. The problem is, I can check any 3 variables in any order, but as soon as I try to check all 4, the WebServer hangs and does one of two things:
- The serial feed stops and the webserver hangs until I reset it
- The serial feed keeps repeating the POST information infinitely until I have to reset it
I need to be able to read these 4 variables and one or two more...I can't have only 3 working. I don't get why only 3 of the 4 checks will work in any order or combination but all 4 cause the webserver/arduino to bug out. Also various (readString.indexOf("whatever") >= 0) cause the webserver to bug out similarly, but that's a different issue. I'm more interested in this right now.
If anyone can give me some insight on this, I would appreciate it so much. I've spent 10+ hours getting nowhere because code I am almost 100% positive should work doesn't.