Basic Web Server Question

Hi, I’m very new to Arduino and HTML and have found and adapted some code from the book “Exploring Arduino: Tools and Techniques for Engineering Wizardry” by John Wiley & Sons

The code is as shown below:

// Arduino Web Server for controlling 8 Relays

//include <UIPEthernet.h>      // Using the ENC28J60 so use UIP library
#include <Ethernet.h>         // Using standard Ethernet library for UNO and Shield
#include <SPI.h>

#define IP_PORT 8080
IPAddress myIp (192, 168, 0, 221); // Configure your static IP address here

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

const int Relay1 = 2;
const int Relay2 = 3;
const int Relay3 = 4;
const int Relay4 = 5;
const int Relay5 = 6;
const int Relay6 = 7;
const int Relay7 = 8;
const int Relay8 = 9;

int pin;                      // variable used for GET request

// Start the server
EthernetServer server = EthernetServer(IP_PORT);

boolean receiving = false;  // To keep track of wether we are
                            // getting data.

void setup() {
  
  Serial.begin(9600);

  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);
  pinMode(Relay5, OUTPUT);
  pinMode(Relay6, OUTPUT);
  pinMode(Relay7, OUTPUT);
  pinMode(Relay8, OUTPUT);

  // Initialise Ethernet
  Ethernet.begin(mac, myIp);

  // Allow the ethernet interface a second to initialize
  delay(1000);

  // Start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

}

void loop() {
  
  EthernetClient client = server.available();

  if (client)
  {
    Serial.println("Client begin");
    // An HTTP request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read(); // Read from the incoming buffer

        if(receiving && c == ' ') receiving = false; // Done receiving
        if(c == '?') receiving = true; // Found arguments

        // This looks at the GET requests
        if(receiving)
        {

          // A Relay command is specified with an R
          if (c == 'R')
          {
            Serial.print("Toggling Pin ");
            pin = client.parseInt();
            Serial.println(pin);

            digitalWrite(pin, !digitalRead(pin));
            break;
          }
        }

        // Print out the response header and the HTML page
        if(!sentHeader)
        {
          // Send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html\n");

          // Relay 1 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='2' />");
          client.println("<input type='submit' value='Relay 1' />");
          client.println("</form>");

          // Relay 2 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='3' />");
          client.println("<input type='submit' value='Relay 2' />");
          client.println("</form>");

          // Relay 3 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='4' />");
          client.println("<input type='submit' value='Relay 3' />");
          client.println("</form>");

          // Relay 4 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='5' />");
          client.println("<input type='submit' value='Relay 4' />");
          client.println("</form>");

          // Relay 5 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='6' />");
          client.println("<input type='submit' value='Relay 5' />");
          client.println("</form>");

          // Relay 6 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='7' />");
          client.println("<input type='submit' value='Relay 6' />");
          client.println("</form>");

          // Relay 7 toggle button
          client.println("<form action'' method='get'>");
          client.println("<input type='hidden' name='R' value='8' />");
          client.println("<input type='submit' value='Relay 7' />");
          client.println("</form>");

          // Relay 8 toggle button
          client.println("<form action='' method='get'>");
          client.println("<input type='hidden' name='R' value='9' />");
          client.println("<input type='submit' value='Relay 8' />");
          client.println("</form>");

          // Add additional forms for controlling more things here

          sentHeader = true;
        }

        if (c == '\n' && currentLineIsBlank) break;

        if (c == '\n')
        {
          currentLineIsBlank = true;
        }
        else if (c != '\r')
        {
          currentLineIsBlank = false;
        }
      }
    }
    delay(50);  // Give the web browser time to receive the data
    client.stop(); // Close the connection:
  }
}

The code almost works as expected, but for some reason the section of code that handles the GET request is being run twice, so the actual result is that the relay will toggle on, then toggle off.

I was expecting it to toggle the relay state once and then close the connection.

For debugging, the serial monitor displays the following messages after one press of the button:

server is at 192.168.0.221
Client begin
Toggling Pin 2
Client begin
Toggling Pin 2

As you can see with the “Client begin” message, the arduino runs through the same toggle code twice.

Thanks in advance

Be advised that some browsers make a second request for a favorite icon, which might be triggering a second toggle.

zoomkat:
Be advised that some browsers make a second request for a favorite icon, which might be triggering a second toggle.

Ah, thanks for that, I thought I was missing something in the code. I will make an attempt to write a conditional that ignores the second request.