Slow/Delayed AJAX communication via WiFi Shield

Hello everyone,

I am a mechanical engineering student working on a project and I have come across a few problems.
My hardware currently consists of an Arduino Uno R3 with an Arduino WiFi Shield and a wireless router.

To give a summary, I have designed an HTML/JavaScript website with one button that will turn on/off the built-in LED via an AJAX get request. The button has been designed so that when I perform a "mousedown," the LED turns on. Similarly, "mouseup" will turn the LED off.

#include <SPI.h>
#include <WiFi.h>

IPAddress ip(192,168,0,200); // Set a static IP

...
int status = WL_IDLE_STATUS;
WiFiServer server(80);

boolean isReading = false;

void setup() {
  WiFi.config(ip);
  pinMode(9, OUTPUT);
...
} // end setup()

void loop() {
    WiFiClient 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 bytes from client
		// 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");
                    client.println("Content-Type: text/html");
                    client.println("Connection: keep-alive");
                    client.println();

                        client.println("<!DOCTYPE html>");
                        client.println("<html><head>");
                        client.println("<script>");
                        client.println("function GetLed(c){");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("request.open(\"GET\", \"?action=\" +c);");
                        client.println("request.send();}");
                        client.println("</script></head><body>");
                        client.println("<h1>Attempt at speed</h1>");
                        client.println("<button id=\"led\" type=\"button\">LED</button>");
                          client.println("<script>");
                        client.println("led.addEventListener(\"mousedown\",function(){GetLed(1);});");
                        client.println("led.addEventListener(\"mouseup\",function(){GetLed(0);});");
                          client.println("</script></body></html>");
                          client.println("");
                          break;
                } // End client.println stuffs

                if (c == ' ') isReading = false;
                if (c == '?') isReading = true;
                if (isReading){
                  if (c == '1') {
                    digitalWrite(9,HIGH);
                  }
                  if (c == '0') {
		    digitalWrite(9,LOW);
                  }
                }
                // every line of text received from the client ends with \r or \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(50);      // give the web browser time to receive the data
        client.stop(); // close the connection
        
    } // end if (client)
} // end void

The LED turns on and off instantly once the left mouse button is held or released (as expected); HOWEVER, there is an approximate 2 second delay before I can use the button again, else the system will hang or lag.
I previously had the serial monitor open, which would display all of the HTTP requests. Like I said, I wasn't able to execute another command until the get request went through and was displayed completely on the serial monitor (which makes sense), but I do not understand why it is taking so long.

Programming isn't really something that is stressed in my curriculum, so I would appreciate any help.
Is there something wrong with the way I have structured my code (particularly in the void loop section), or is it a hardware issue?
Thank you in advance.

In the future, I will be implementing servos and multiple buttons to control them.

You can put in some serial logging to try to figure out what it's doing while it's in that 1 second delay - that's what I would probably do. Is it sitting in loop spinning, getting told there's no client? Is it in that block of code, but hung up waiting for some call to return?

Be prepared for the possibility that this is a limitation of the hardware.

Thanks for the tip DrAzzy.

I inserted a bunch of Serial.println() commands throughout my code and I have noticed that there is a short hang between Serial.prints here in one of the major if clauses:

...
client.println("<script>");          
client.println("function GetLed(c){");                     
client.println("var request = new XMLHttpRequest();");              
    Serial.println("request.open");                        
client.println("request.open(\"GET\", \"?=\" +c);");
    Serial.println("request.send");                        
client.println("request.send();}");
    Serial.println("request.send complete");   ...

When I click my button, the Serial monitor displays everything up to "request.send complete," pauses momentarily, and then prints out the rest of some non-important debugging code, ultimately ending with the client.stop().

This leads me to believe that the Arduino server is unable to handle communication while it is completing a request.
Does that sound about right?

Update:

I sort of have it figured out.
It seems like the reason why my code is taking so long to run is because I need to find a way to remove my commands (digitalWrites) out of the void loop.

Not exactly sure if this is 100% correct, but it's possible that every time I click the button, the HTML code is rewritten again via client.print().

We'll see how this goes.

Translating the string in your println (to get to the actual javascript command)

client.println("request.open(\"GET\", \"?=\" +c);");

Becomes

request.open("GET", "?=" +C);

Since the value of C just gets appended to the ?= you don't have the third paramater to your xml call, which would specify whether it's an asynchronous call.

So I'd suggest changing it to read.

client.println("request.open(\"GET\", \"?=\" +c, true);");

Hey KenF,

I will try that.

But if my knowledge is correct, isn't a request.open() async true my default if not specified?

Regardless, I will incorporate your feedback. Thanks!