Arduino Mega reads old GET requests that does not exist anymore

Hi,

I ve done some testing with the webserver on the arduino and I’m making GET requests to the arduino to change LED pmw values. In my set up I got 2 leds that I can change from a webinterface with a slider ( jquery UI) one for each led.

I got it all working fine except that when the arduino code read the GET request it somehow has memorized an old get request (or so it seems) when I move the slider the page sends a GET request with the LED name (in my case &whiteOne=XXXX) XXXX is the current value from the slider.

my led lights up fine only to turn off shortly after and if I read the serial output of the request I can see that whiteOne=0 in the request however I haven’t sent whiteOne=0.

The funny thing is does not happen with the other LED called whiteTwo. And I’ve also changed my javascript code (I renamed whiteOne to whiteOna in the GET request) and then my led works fine but looking at the Serial output I can see that I still somehow get whiteOne=0 in the request.

Sure the easy fix would be to just use another name for that LED but I do not like it when I do not know why something is going wrong.

Here is the test webpage there is other stuff in the code as well but never mind it:

<!DOCTYPE html>
<html>
    <head>
        <title>Arduino Ajax I/O</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
  <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
  <script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
        <script> 
 strLED1 = "";
 strLED2 = "";
 var LED1_state = 0;
 var LED2_state = 0;
 ledval = "";
 
 $(function() {
 $( "#whiteOne" ).slider({
 range: "min",
 min: 0,
 max: 4095,
 value: 60,
 step: 50,
 slide: function( event, ui ) {
 $( "#val-whiteOne" ).val( ui.value );
 ledval = "&whiteOnes=" + ui.value;
 //ledval = anewval; 
 },
 change: function(event, ui){
 sendData();
 }
 
 });
 
 $( "#val-whiteOne" ).val( $( "#whiteOne" ).slider( "value" ) );
 
 });
 
 $(function() {
 $( "#whiteTwo" ).slider({
 range: "min",
 min: 0,
 max: 4095,
 value: 60,
 step: 50,
 slide: function( event, ui ) {
 $( "#val-whiteTwo" ).val( ui.value );
 //var anewval 
 ledval = "&whiteTwo=" + ui.value; 
 //ledval = anewval; 
 },
 change: function(event, ui){
 sendData();
 }
 
 });
 $( "#val-whiteTwo" ).val( $( "#whiteTwo" ).slider( "value" ) );
 
 });

 
 function sendData(){
 nocache = "&nocache=" + Math.random() * 100000;
 var request = new XMLHttpRequest();
 
 request.open("GET", "ajax_input" + ledval + nocache, true);
 request.send(null);
 setTimeout('sendData()', 1000);
 ledval ="null";
 strLED1 = "";
 strLED2 = "";
 
 

 }
 
 
 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;
 // get analog inputs
 
 // LED 1
 
 // LED 2
 
 // LED 3
 if (this.responseXML.getElementsByTagName('LED')[0].childNodes[0].nodeValue === "on") {
 document.getElementById("LED1").innerHTML = "LED 1 is ON (D8)";
 LED1_state = 1;
 }
 else {
 document.getElementById("LED1").innerHTML = "LED 1 is OFF (D8)";
 LED1_state = 0;
 }
 // LED 4
 if (this.responseXML.getElementsByTagName('LED')[1].childNodes[0].nodeValue === "on") {
 document.getElementById("LED2").innerHTML = "LED 2 is ON (D9)";
 LED2_state = 1;
 }
 else {
 document.getElementById("LED2").innerHTML = "LED 2 is OFF (D9)";
 LED2_state = 0;
 }
 }
 }
 }
 }
 // send HTTP GET request with LEDs to switch on/off if any
 
 sendData();
 /*request.open("GET", "ajax_inputs" + "noInput" + nocache, true);
 
 }else{
 request.open("GET", "ajax_inputs"  + nocache, true);
 }
 request.send(null);
 setTimeout('GetArduinoIO()', 1000);
 /*tempvar = ledval;
 ledval ="";
 strLED1 = "";
 strLED2 = "";*/
 
 }
 // service LEDs when checkbox checked/unchecked
 
 function GetButton1()
 {
 if (LED1_state === 1) {
 LED1_state = 0;
 strLED1 = "&LED1=0";
 }
 else {
 LED1_state = 1;
 strLED1 = "&LED1=1";
 }
 }
 function GetButton2()
 {
 if (LED2_state === 1) {
 LED2_state = 0;
 strLED2 = "&LED2=0";
 }
 else {
 LED2_state = 1;
 strLED2 = "&LED2=1";
 }
 }
 </script>
    </head>
    <body onload="GetArduinoIO()">
        <h1>Arduino Ajax I/O</h1>
    
 <div class="IO_box">
 <h2>LEDs Using Buttons</h2>
 <button type="button" id="LED1" onclick="GetButton1()">LED 1 is OFF (D8)</button>


 <button type="button" id="LED2" onclick="GetButton2()">LED 2 is OFF (D9)</button>


 
 <p class="small_text">D10 to D13 used by Ethernet shield</p>
 </div>
 <div id="myslidercont">
 <p>
  <label for="val-whiteOne">Volume:</label>
  <input type="text" id="val-whiteOne" readonly style="border:0; color:#f6931f; font-weight:bold;">
</p>
 
<div id="whiteOne" class="slider" style="width:200px"></div>

<p>
  <label for="val-whiteTwo">Volume:</label>
  <input type="text" id="val-whiteTwo" readonly style="border:0; color:#f6931f; font-weight:bold;">
</p>

<div id="whiteTwo" class="slider" style="width:200px"></div>
 
 
 </div>
    </body>
</html>

Here is the arduino code:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// 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,2,2); // IP address, may need to change depending on network
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[3] = {0}; // stores the states of the LEDs


// LED VALUES:| power | start | rampup | end | rampdown | name |
String channel_one[6] ={""};
String channel_two[6] ={""};
String channel_three[6] ={""};
String channel_four[6] ={""};

void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
    
    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 on pins 2, 3 and 5
    /*pinMode(2, INPUT);
    pinMode(3, INPUT);
    pinMode(5, INPUT);*/
    // LEDs
    /*pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);*/
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
     pwm.begin();
  pwm.setPWMFreq(1600);  
}

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_input")) {
                        // 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)
}

// checks if received HTTP request is switching on/off LEDs
// also saves the state of the LEDs
void SetLEDs(void)
{
   
    // LED 3 (pin 8)
    if (StrContains(HTTP_req, "LED1=1")) {
        LED_state[1] = 1;  // save LED state
        digitalWrite(8, HIGH);
    }
    else if (StrContains(HTTP_req, "LED1=0")) {
        LED_state[1] = 0;  // save LED state
        digitalWrite(8, LOW);
    }
    // LED 4 (pin 9)
    if (StrContains(HTTP_req, "LED2=1")) {
        LED_state[2] = 1;  // save LED state
        digitalWrite(9, HIGH);
    }
    else if (StrContains(HTTP_req, "LED2=0")) {
        LED_state[2] = 0;  // save LED state
        digitalWrite(9, LOW);
    }
    
    /* if (StrContains(HTTP_req, "value=")) {
          String temp = HTTP_req;
       int place = temp.indexOf("value=");
        place = place+6;
        
        
        String mystring = temp.substring(place, place+4);
        int myInt = mystring.toInt();
        if(myInt>4095){
          myInt=4095;
        }
        if(myInt<1){
         myInt=1;
        }
        pwm.setPWM( 0, 1, myInt );
        Serial.println(" ");
        Serial.print("My string: ");
        Serial.println(mystring);
    }*/
    if (StrContains(HTTP_req, "whiteOnes=")) {
          String temp = HTTP_req;
       int place = temp.indexOf("whiteOnes=");
        place = place+10;
        
        
        String mystring = temp.substring(place, place+4);
        int myInt = mystring.toInt();
        if(myInt>4095){
          myInt=4095;
        }
        if(myInt<1){
         myInt=1;
        }
        pwm.setPWM( 1, 1, myInt );
        channel_one[0] = String(myInt);
        if(myInt>1500){
           LED_state[1]=true;
        }else {
           LED_state[1]=false;
        }
        
        Serial.println(" ");
        Serial.print("channel 1: ");
        Serial.println(channel_one[0]);
    }
    
    if (StrContains(HTTP_req, "whiteTwo=")) {
          String temp = HTTP_req;
       int place = temp.indexOf("whiteTwo=");
        place = place+9;
        
        
        String mystring = temp.substring(place, place+4);
        int myInt = mystring.toInt();
        if(myInt>4095){
          myInt=4095;
        }
        if(myInt<1){
         myInt=1;
        }
        pwm.setPWM( 0, 1, myInt );
        channel_two[0] = String(myInt);
        if(myInt>1500){
           LED_state[2]=true;
        }else {
           LED_state[2]=false;
        }
        Serial.println(" ");
        Serial.print("cahnnel 2: ");
        Serial.println(channel_two[0]);
    }
}

here is the second part of the arduino code:

// 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, 5};  // pins interfaced to switches
    
    cl.print("<?xml version = \"1.0\" ?>");
    cl.print("<inputs>");
    // read analog inputs
   /* for (count = 2; count <= 5; count++) { // A2 to A5
        analog_val = analogRead(count);
        cl.print("<analog>");
        cl.print(analog_val);
        cl.println("</analog>");
    }
     //read switches
    for (count = 0; count < 3; count++) {
        cl.print("<switch>");
        if (digitalRead(sw_arr[count])) {
            cl.print("ON");
        }
        else {
            cl.print("OFF");
        }
        cl.println("</switch>");
    }
    */
   // checkbox LED states
    // LED1
   /*cl.print("<LED>");
    if (LED_state[0]) {
        cl.print("checked");
    }
    else {
        cl.print("unchecked");
    }
    cl.println("</LED>");
    // LED2
    cl.print("<LED>");
    if (LED_state[1]) {
        cl.print("checked");
    }
    else {
        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>");
    // LED4
    cl.print("<LED>");
    if (LED_state[2]) {
        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;
}

Can anyone see my problem I’ve been starring at this code for a while now I’m getting blinded my the code can’t find anything wrong but there is something wrong with it.[/code]

String channel_one[6] ={""};
String channel_two[6] ={""};
String channel_three[6] ={""};
String channel_four[6] ={""};

Why do have arrays of String objects when you only ever assign values to the first element of each array?

Why are you pissing away resources on the String class, anyway?

                        if (webFile) {
                            while(webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }

Sending a 512 byte packet with one character as the payload is wasting a lot of time and effort. You CAN read more than one byte from the file, and you CAN write more than one byte to the client packet at a time.

I gave up reading your code at this point. You posted code with so much commented out crap that it is hard to follow. Before posting code DELETE commented out code, so we don't have to wade through it.

You failed to post any serial output to back up your claims, too.

Hi PaulS,

I understand your concern about wasting resources. The I will be adding more data to the string arrays later on that is why it seems like a waste right now, the same goes for the payload there will be a long strings with various values later on as well.

I will add the Serial output when I get back home.