
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.

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

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.