Web client from ESP8266 to Arduino Mega.

I am new to creating an html webpage from the esp8266, and I have a few questions on what I have seen.

Here is the code I currently have, but do definitely plan on changing it quite a bit. It's an example from the WiFiEsp.h library. The example I used was the turning on the LED example.

Here is my altered code so far:

#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#include <WiFiEspServer.h>
#include <WiFiEspUdp.h>
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

/*
 WiFiEsp example: WebServerLed
 
 A simple web server that lets you turn on and of an LED via a web page.
 This sketch will print the IP address of your ESP8266 module (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to turn on and off the LED on pin 13.

 For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
*/

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include <SoftwareSerial.h>
SoftwareSerial Serial2(17, 16); // RX, TX

#endif

char ssid[] = "SSID";            // your network SSID (name)
char pass[] = "password";        // your network password
int status = WL_IDLE_STATUS;

int ledStatus = LOW;
int RED_LED = 6;

WiFiEspServer server(80);

Servo servo1;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(3);
int pos = 0;

// use a ring buffer to increase speed and reduce memory allocation
RingBuffer buf(8);

void setup()
{
  pinMode(RED_LED, OUTPUT);  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);   // initialize serial for debugging
  Serial2.begin(115200);    // initialize serial for ESP module
  WiFi.init(&Serial2);    // initialize ESP module
  AFMS.begin();

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  printWifiStatus();
  
  // start the web server on port 80
  server.begin();

  servo1.attach(9);
  servo1.write(90);

  myMotor1->setSpeed(150);
  //myMotor1->run(FORWARD);
  // turn on motor
  //myMotor1->run(RELEASE);
}


void loop()
{
  WiFiEspClient client = server.available();  // listen for incoming clients

  if (client) {                               // if you get a client,
    Serial.println("New client");             // print a message out the serial port
    buf.init();                               // initialize the circular buffer
    while (client.connected()) {              // loop while the client's connected
      if (client.available()) {               // if there's bytes to read from the client,
        char c = client.read();               // read a byte, then
        buf.push(c);                          // push it to the ring buffer

        // printing the stream to the serial monitor will slow down
        // the receiving of data from the ESP filling the serial buffer
        //Serial.write(c);
        
        // you got two newline characters in a row
        // that's the end of the HTTP request, so send a response
        if (buf.endsWith("\r\n\r\n")) {
          sendHttpResponse(client);
          break;
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (buf.endsWith("GET /H")) {
          Serial.println("Turn led ON");
          ledStatus = HIGH;
          digitalWrite(RED_LED, HIGH);   // turn the LED on (HIGH is the voltage level)
        }
        else if (buf.endsWith("GET /L")) {
          Serial.println("Turn led OFF");
          ledStatus = LOW;
          digitalWrite(RED_LED, LOW);    // turn the LED off by making the voltage LOW
        }/* else if (buf.endsWith("GET /SR")) { //Turning the servo to the right
            while (pos < 180) {
              servo1.write(pos++);
              delay(5);
            }
        } else if (buf.endsWith("GET /SL")) {   //Just testing turning the servo to the left
            while(pos > 3) {
            servo1.write(pos--);
            delay(5);
            }
        }*/ else if (buf.endsWith("GET /M")) {  //this command moves the DC motor forward
            myMotor1->run(FORWARD);
          } else if (buf.endsWith("GET /MS")) { //this command moves the DC motor backwards
            myMotor1->run(BACKWARD);
          }
        }
      }
              
      // close the connection
      client.stop();
      Serial.println("Client disconnected");
    }
}


void sendHttpResponse(WiFiEspClient client)
{
  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:text/html");
  client.println();
  
  // the content of the HTTP response follows the header:
  client.print("The LED is ");
  client.print(ledStatus);
  client.println("
");
  client.println("
");
  
  client.println("Click <a href=\"/H\">here</a> turn the LED on
");
  client.println("Click <a href=\"/L\">here</a> turn the LED off
");
  //client.println("Click <a href=\"/SR\">here</a> to turn servo right
");
  //client.println("Click <a href=\"/SL\">here</a> to turn servo left
");
  client.println("Click <a href=\"/M\">here</a> turn motor
");
  client.println("Click <a href=\"/MS\">here</a> stop motor
");
  
  // The HTTP response ends with another blank line:
  client.println();
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

When I run this code, it gives me an IP address which I visit to control certain digital pins from the arduino mega. So far every pin as been able to be controlled successfully. We were able to turn an LED on/off, control a servo and control a DC motor. The only issue is when a button is pressed on the webpage, there are a few noticeable problems.

1. When one button is pressed too many times, it takes time to process the request and some times doesn't even execute what the button was made for. For example, the button for turning the servo to the right works, but only when patiently pressed. If we give it time to load up the webpage, it works. If we press it too many times, it does not work. The same with the LED. If the LED is on, and we want it off by pressing the button many times consecutively, it doesn't turn off.

2. Does the webpage have to refresh every single time a button is pressed? I noticed when a button is pressed, it changes the url according to which button was pressed. The "GET /H" below shows up on the url when the button to turn on the LED is pressed.

if (buf.endsWith("GET /H")) {
          Serial.println("Turn led ON");
          ledStatus = HIGH;
          digitalWrite(RED_LED, HIGH);   // turn the LED on (HIGH is the voltage level)
        }
        else if (buf.endsWith("GET /L")) {
          Serial.println("Turn led OFF");
          ledStatus = LOW;
          digitalWrite(RED_LED, LOW);    // turn the LED off by making the voltage LOW
        }

3. The last issue I've noticed is when too many buttons are present on the webpage, it takes a little longer to execute. Is there a reason for this? We had six buttons at the time we have problems loading the webpage.

Can someone enlighten me on the art of creating a simple and efficient webpage using the ESP8266 with the Arduino MEGA?

Try sending the entire HTTP response in a single call to client.println(), rather than a bunch of separate calls. There may be some limit to how much you can send at once and if your response exceeds that you may need to break it into a couple pieces but do the least number of prints possible. I haven't done this with your configuration of ESP8266 running AT firmware controlled by AVR, but I had a project with some larger web pages served by an ESP8266 and sending the whole page at once (or in a couple pieces) made it dramatically faster.

Here's a tip for improving the performance of the WiFiEsp library:
The library has debug output on by default, which is useful if you're having a problem but causes pointless overhead once you have it running correctly. You can turn it off by opening the src/utility/debug.h file found in the WiFiEsp library in a text editor and making the change shown here:

This may make your system a bit more responsive.

You also have some debug prints to Serial in your code. This is a good practice while developing but they should be disabled when not in use. A useful system for easily enabling or disabling Serial with no overhead is to add these lines to your sketch before setup():

#define DEBUG false //set to true for debug output, false for no debug ouput
#define Serial if(DEBUG)Serial

So I have tried everything you mentioned, and while it did run faster, it still wouldn't load every single button we wrote. We tried placing 6 buttons in one client.println(), and it worked. Then we place 8 buttons in one client.println() and it wouldn't load. We found the limit to be around 6 buttons per client.println(). When we tried separating the client.println()'s, it still wouldn't load all the buttons. I even tried separating the buttons into several println() functions. Now I have questions more questions.

We had an idea of making a simple html page, and trying to load it all in, kinda like you said you did. Although, we had an idea of giving the arduino an html page, then sending it to the esp8266. How would that be possible? We want the webpage to be a little bigger than 6 buttons, and want it to load faster. Are there any libraries you know of that can serve an html page by the esp8266 sent through the arduino? Is there maybe any articles or journals you know of that can help us out a little with serving html pages through serial communications between an esp and arduino?