Created on: 21 January 2013
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.
The following Arduino sketch will enable the Arduino with Ethernet shield to serve up a single web page that can be viewed in a web browser.
/*-------------------------------------------------------------- Program: eth_websrv_page Description: Arduino web server that serves up a basic web page. Does not use the SD card. Hardware: Arduino Uno and official Arduino Ethernet shield. Should work with other Arduinos and compatible Ethernet shields. Software: Developed using Arduino 1.0.3 software Should be compatible with Arduino 1.0 + References: - WebServer example by David A. Mellis and modified by Tom Igoe - Ethernet library documentation: http://arduino.cc/en/Reference/Ethernet Date: 7 January 2013 Author: W.A. Smith, http://startingelectronics.org --------------------------------------------------------------*/ #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) }
Important Note!
If an uninitialized SD card is left in the SD card socket of the shield, it can cause problems with code in the sketch that is accessing the Ethernet chip. This may cause symptoms such as the sketch running once or twice, then hanging up.
This is because both the Ethernet chip and the SD card are accessed by the Arduino using the same SPI bus.
If the SD card is not being used with an Ethernet application, either remove it from the socket or add the following code to disable the SD card:
void setup() { // disable the SD card by switching pin 4 high // not using the SD card in this program, but if an SD card is left in the socket, // it may cause a problem with accessing the Ethernet chip, unless disabled pinMode(4, OUTPUT); digitalWrite(4, HIGH); // other initialization code goes here... }
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.
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.
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.
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);
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.
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.
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.
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).
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 and other web page code is explained in the next part of this tutorial.