Control your Arduino from the web

Part 1 of the Arduino Ethernet Shield Web Server Tutorial
This multi-part tutorial shows how to set up an Arduino with Ethernet shield as a web server. The web servers in this tutorial are used to serve up web pages that can be accessed from a web browser running on any computer connected to the same network as the Arduino.
Some of the Arduino web server pages allow access to the Arduino hardware – this allows hardware to be controlled (e.g. switching on and off an LED from the web page) and monitored (e.g. reading the state of a switch and displaying it on a web page).
The tutorial teaches what is required to build a web server including all the technology such as HTTP, HTML, CSS, JavaScript, AJAX, etc. It starts with the very basics of hosting a simple web page on the Arduino and advances step-by-step from there.


Hardware Required

Hardware Components

The hardware required for following this series of tutorials is:
  • An Arduino board such as the Arduino Uno
  • An Arduino Ethernet shield
  • An Ethernet cable, wired straight for connecting to your network router
  • A USB cable for powering and programming the Arduino
  • A micro SD card, e.g. a 2Gb card that is SPI compatible – only required for some of the servers
  • A computer with a micro SD card slot or a card reader with a micro SD card slot – only required for SD card servers
There will be additional components required as listed in each tutorial, such as LEDs, resistors, switches, etc. and a breadboard and wire kit for building the circuits.

Hardware Setup

Before starting:
  1. Plug the Ethernet shield into the Arduino, connect it to the network and test it.
  2. Test the SD card in the Ethernet shield.
Part 2 of the Arduino Ethernet Shield Web Server Tutorial
A very basic web server that serves up a single web page using the Arduino Ethernet shield. An SD card is not used in this example as the web page forms part of the Arduino sketch.
/*--------------------------------------------------------------

--------------------------------------------------------------*/

#include <SPI.h>
#include <Ethernet.h>

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 0, 0, 20); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80

void setup()
{
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
}

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
                // 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: close");
                    client.println();
                    // send web page
                    client.println("<!DOCTYPE html>");
                    client.println("<html>");
                    client.println("<head>");
                    client.println("<title>Arduino Web Page</title>");
                    client.println("</head>");
                    client.println("<body>");
                    client.println("<h1>Hello from Arduino!</h1>");
                    client.println("<p>A web page from the Arduino server</p>");
                    client.println("</body>");
                    client.println("</html>");
                    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)
}

Using the Sketch

Copy the above sketch and paste it into the Arduino IDE. Change the MAC address in the sketch to match the numbers on the sticker on the bottom of your Ethernet shield. Change the IP address in the sketch to match the IP address range of your network.
Your hardware must be set up as described in part 1 of this tutorial.
Load the sketch to the Arduino and then open a web browser on a computer that is connected to the same network as the Arduino.
Surf to the Arduino by typing the IP address of the Arduino into the URL field of the browser, e.g. 10.0.0.20 in the above sketch.
The browser should display a web page as shown below.
Web page served by Arduino web server
Web Page Served by Arduino Web Server

Problem Solving

Resetting
If you were not able to connect to the Arduino, try resetting it by pressing the reset button on the Ethernet shield and then surf to the web server again.
IP Address and Address Range
Make sure that you have set the correct Arduino IP address for the address range of your network. The first three numbers of the IP address must match your network. The last number must be unique – i.e. it must be the only device on the network with that number.
Gateway and Subnet Mask
Try specifying the network gateway and subnet mask in the sketch if there are still network connection problems. You will need to change the addresses in the code below to match your network.
Add the gateway and subnet under the MAC address in the sketch:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
// the router's gateway address:
byte gateway[] = { 10, 0, 0, 1 };
// the subnet:
byte subnet[] = { 255, 255, 0, 0 };
And then initialize the Ethernet device with these settings in the setup() part of the sketch:
Ethernet.begin(mac, ip, gateway, subnet);
Ethernet Cable
When connecting to the network through an Ethernet router/hub/switch, an Ethernet cable that is wired one-to-one must be used to connect the Arduino. Do not use a crossover cable.

Basic Web Server Explained

Read the comments in the above sketch to see what specific lines of code do. This explanation shows what request the server must respond to and what data it must send back.

Client Request

When you surf to the IP address of the Arduino server, the web browser (client) will send a request, such as the one shown below, to the server.
GET / HTTP/1.1\r\n
Host: 10.0.0.20\r\n
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3\r\n
Accept-Encoding: gzip, deflate\r\n
Connection: keep-alive\r\n
\r\n
The information in the request will differ, depending on the browser and operating system that the request is sent from.
The \r\n characters that you see at the end of every line of text in the request are non-visible characters (non-printable characters). \r is the carriage return character and \n is the linefeed character (or newline character).
The last line of the request is simply \r\n without and preceding text. This is the blank line that the Arduino sketch checks for before sending a response to the client web browser.
In other words, the sketch reads every character from the above request and knows when the end of the request has been reached because it finds the blank line.

Server Response

After receiving the request for a web page from the client, the server first sends a standard HTTP response and then the web page itself.
The response sent from the Arduino is as follows:
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Connection: close\r\n
\r\n
Again the non-visible characters \r\n are shown in the above response. The println() function in the the sketch automatically adds the \r\n characters to the end of each line. The empty println() function at the end of the HTTP response simply sends the \r\n with no text in front of it.
The above request and response are part of HTTP (Hypertext Transfer Protocol).

Web Page

After the server has sent the HTTP response, it sends the actual web page which is then displayed in the browser.
The web page consists of text with HTML tags. You do not see the tags in the browser as these tags are interpreted by the browser.
To see the actual HTML source code, in the browser right-click on the page from the Arduino server and then click View Page Source.
The actual HTML markup tags are shown below.
HTML code of the web page
Web Page HTML Code (Markup)
HTML and other web page code is explained in the next part of this tutorial.

Comments