How to Use Arduino as a Web Server

Arduino Web Server Featured

When it comes to IoT projects, Arduino isn’t quite a household name, but maybe it should be. While Arduino boards are comprised of fairly modest hardware, they can get a whole lot done. These boards can power everything from weather stations to smart mirrors.

Arduino boards are also surprisingly good candidates for projects you might normally use a Raspberry Pi for. In this case, we’ll be looking at using one as a basic web server. This is a simple example, but it can scale up as well.

Before You Start

You’ll need a few things to get started. Obviously, you’ll need an Arduino board like the Arduino Uno. Then you’ll also need the Ethernet Shield for Arduino. Aside from this, you’ll need an Ethernet cable to connect to your network and a USB cable to power and program the board.

Arduino Web Server Arduino Uno

When it comes to writing and running the code, you’ll be best served by running the Arduino IDE. If you’re running Ubuntu, we have a guide to getting the Arduino IDE up and running.

Preparation

Before you do anything, you’ll want to connect the Ethernet Shield to your Arduino. To do this, simply mount the shield on top of your Arduino board. Now you can connect to your computer via the USB cable.

If you have an SD card you’re using with the Arduino, it can cause potential problems with this sketch. Either remove the SD card or add the following code in the setup() function in the next section:

pinMode(4, OUTPUT);
digitalWrite(4, HIGH);

The Code

There is already plenty of code available to get a basic web server running on the Arduino Ethernet Shield. We’re not going to reinvent the wheel here. Instead, the following code is taken from the Arduino website. Copy it into the Arduino IDE, compile it, and upload it to get your server running.

/*
   Web Server
 
  A simple web server that shows the value of the analog input pins.
  using an Arduino Wiznet Ethernet shield.
 
  Circuit:
  * Ethernet shield attached to pins 10, 11, 12, 13
  * Analog inputs attached to pins A0 through A5 (optional)
 
  created 18 Dec 2009
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe
  modified 02 Sept 2015
  by Arturo Guadalupi
  
  */
 
 #include <SPI.h>
 #include <Ethernet.h>
 
 // Enter a MAC address and IP address for your controller below.
 // The IP address will be dependent on your local network:
 byte mac[] = {
 &nbsp; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
 };
 IPAddress ip(192, 168, 1, 177);
 
 // Initialize the Ethernet server library
 // with the IP address and port you want to use
 // (port 80 is default for HTTP):
 EthernetServer server(80);
 
 void setup() {
 &nbsp; // You can use Ethernet.init(pin) to configure the CS pin
 &nbsp; //Ethernet.init(10); &nbsp;// Most Arduino shields
 &nbsp; //Ethernet.init(5); &nbsp; // MKR ETH shield
 &nbsp; //Ethernet.init(0); &nbsp; // Teensy 2.0
 &nbsp; //Ethernet.init(20); &nbsp;// Teensy++ 2.0
 &nbsp; //Ethernet.init(15); &nbsp;// ESP8266 with Adafruit Featherwing Ethernet
 &nbsp; //Ethernet.init(33); &nbsp;// ESP32 with Adafruit Featherwing Ethernet
 
 &nbsp; // Open serial communications and wait for port to open:
 &nbsp; Serial.begin(9600);
 &nbsp; while (!Serial) {
 &nbsp; &nbsp; ; // wait for serial port to connect. Needed for native USB port only
 &nbsp; }
 &nbsp; Serial.println("Ethernet WebServer Example");
 
 &nbsp; // start the Ethernet connection and the server:
 &nbsp; Ethernet.begin(mac, ip);
 
 &nbsp; // Check for Ethernet hardware present
 &nbsp; if (Ethernet.hardwareStatus() == EthernetNoHardware) {
 &nbsp; &nbsp; Serial.println("Ethernet shield was not found. &nbsp;Sorry, can't run without hardware. :(");
 &nbsp; &nbsp; while (true) {
 &nbsp; &nbsp; &nbsp; delay(1); // do nothing, no point running without Ethernet hardware
 &nbsp; &nbsp; }
 &nbsp; }
 &nbsp; if (Ethernet.linkStatus() == LinkOFF) {
 &nbsp; &nbsp; Serial.println("Ethernet cable is not connected.");
 &nbsp; }
 
 &nbsp; // start the server
 &nbsp; server.begin();
 &nbsp; Serial.print("server is at ");
 &nbsp; Serial.println(Ethernet.localIP());
 }
 
 
 void loop() {
 &nbsp; // listen for incoming clients
 &nbsp; EthernetClient client = server.available();
 &nbsp; if (client) {
 &nbsp; &nbsp; Serial.println("new client");
 &nbsp; &nbsp; // an http request ends with a blank line
 &nbsp; &nbsp; bool currentLineIsBlank = true;
 &nbsp; &nbsp; while (client.connected()) {
 &nbsp; &nbsp; &nbsp; if (client.available()) {
 &nbsp; &nbsp; &nbsp; &nbsp; char c = client.read();
 &nbsp; &nbsp; &nbsp; &nbsp; Serial.write(c);
 &nbsp; &nbsp; &nbsp; &nbsp; // if you've gotten to the end of the line (received a newline
 &nbsp; &nbsp; &nbsp; &nbsp; // character) and the line is blank, the http request has ended,
 &nbsp; &nbsp; &nbsp; &nbsp; // so you can send a reply
 &nbsp; &nbsp; &nbsp; &nbsp; if (c == '\n' && currentLineIsBlank) {
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // send a standard http response header
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("HTTP/1.1 200 OK");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("Content-Type: text/html");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("Connection: close"); &nbsp;// the connection will be closed after completion of the response
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("Refresh: 5"); &nbsp;// refresh the page automatically every 5 sec
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println();
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("<!DOCTYPE HTML>");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("<html>");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // output the value of each analog input pin
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int sensorReading = analogRead(analogChannel);
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.print("analog input ");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.print(analogChannel);
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.print(" is ");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.print(sensorReading);
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("<br />");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.println("</html>");
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
 &nbsp; &nbsp; &nbsp; &nbsp; }
 &nbsp; &nbsp; &nbsp; &nbsp; if (c == '\n') {
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // you're starting a new line
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentLineIsBlank = true;
 &nbsp; &nbsp; &nbsp; &nbsp; } else if (c != '\r') {
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // you've gotten a character on the current line
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentLineIsBlank = false;
 &nbsp; &nbsp; &nbsp; &nbsp; }
 &nbsp; &nbsp; &nbsp; }
 &nbsp; &nbsp; }
 &nbsp; &nbsp; // give the web browser time to receive the data
 &nbsp; &nbsp; delay(1);
 &nbsp; &nbsp; // close the connection:
 &nbsp; &nbsp; client.stop();
 &nbsp; &nbsp; Serial.println("client disconnected");
 &nbsp; }
 }

What the Code Is Doing

In the above code the MAC address is being set manually. The IP address is as well. While the MAC address should work fine on most networks, you may need to change the IP address to fit with the address conventions used on your network.

Arduino Web Server Arduino Ethernet Shield

The setup() function is, well, setting up the Ethernet connection and preparing to listen for incoming connections. It’s also handling any errors that may pop up at runtime.

The real meat of this sketch takes place in the loop() function. This listens for clients initiating connections, responds with header information, then serves HTML code which is rendered by the browser. The code then closes the connection once it has finished serving the data.

Conclusion

We’ve already mentioned what can happen when you have an SD card inserted but aren’t using it. What if you decided to load your web site off of the SD card instead? You can modify the above code to work this way, or you can use it as the basis for a larger project.

This web server can also serve as a small part of a larger IoT project. For an idea as to where you could potentially go from here, take a look at our roundup of some of the best Arduino IoT projects.

Subscribe to our newsletter!

Get the best of IoT Tech Trends delivered right to your inbox!

Kris Wouk

Kris Wouk is a writer, musician, and whatever it's called when someone makes videos for the web.