A while ago, I showed you how to setup an internet control system for your Arduino - but it had to stay connected to a computer through USB in order to maintain the internet connection. If you have an Ethernet shield though, that's not necessary  Today we're going to look at setting up an Arduino as a basic webserver so we can host our own device control website.

You will need:

  • An Arduino, or Arduino clone as detailed here
  • Ethernet Shield (~$35) - make sure you get a version that matches your Arduino as they aren't all compatible
  • Spare port on your router or switch, and Ethernet cable
  • The WebServer example provided in the Arduino application

Setting up

The Ethernet shield uses pins 10 through 13 for controlling the network connection, so leave those out of your project; pin 4 is also used for the SD card, but we won't be using that today.

First things first - open up the File->Examples->Ethernet->WebServer that's provided within the Arduino IDE. Find the lines referring MAC and IP address.

arduino web server

The MAC address for mine was found on the box - yours may be on the shield itself. Adjust the first line of values - you need to leave the preceding 0x bit though. Technically speaking, it doesn't really matter what you put here so long as you don't have any conflicting values on your subnet - but even so, this was the addressed assigned by the manufacturer, so we should probably stick with that. Just know that if you get it wrong, it will still work.

arduino webserver example

Next up is the IP address. We want a specific fixed address so we can setup port forwarding properly - the shield is capable of getting an address from DHCP, but that's only useful if it's merely going to be used as a client, not a server. Fill in an IP address that's unused and memorable on your local network, your router IP, and 255.255.255.0 (the subnet). If none of this is making sense to you, go read our free and thorough guide to home networking.

Port Forwarding

Edit the line that says EthernetServer server(number), and change the number to 8081. This will setup our server to listen on port 8081 in case your ISP is blocking web traffic on the traditional port 80.

Upload the demo at this point and test it out from a local machine. You will of course need to plug in the Ethernet cable too. Keep the USB plugged in too, as we need it for power - you can replace that with a 9V power supply later, but we're still testing.

Noob-tip: if you get this error, it means you've mistakenly put a capital O instead of a 0 in the MAC address area. There is no O in hex-values! If you really are new, it may be worthwhile checking out our beginner's Arduino guide!

arduino webserver example

To access the Arduino, type in the address and port number directly from a browser.

arduino webserver example

You should see something like that - so far so good. Unfortunately, this is only accessible on the local network right now, so head on into your router's port configuration page to set up a redirect from port 8081 to the same port on your Arduino's IP (See: What is port forwarding?)

arduino web server tutorial

Test this out from a mobile 3G internet device with Wifi disabled; remember to use your public IP address, not your local network address. Your router should be able to tell you this, or just ask Google "what is my ip".

arduino web server

Understanding the output

The page being served in the demo is reading values from the analog pins - but since there's nothing connected there, you're going to get nonsense. Try connecting a light sensor (photo resistor) to port A0 and +5v, with a 10k resistor also on A0 and gnd (this is a voltage divider, since the analog pins can only read voltage, and not resistance) just to confirm the server is actually reading values. Notice that when light intensity changes, the values on the other pins actually change too - this is because they're all unconnected.

Getting Interactive

Reading these values is all well and good, but making the jump to controlling an Arduino from here is quite a leap, and outside the scope of this tutorial today. Instead of re-inventing the wheel, I'll point you towards Arduino forum user hari who wrote a basic API for interacting with digital pins. Using this code (I've modified it to work with the latest Ethernet library), connect the long lead of an LED (anode) to pin 8, and the short lead to pin 7 (with a suitable resistor). You can then use URLs of the form http://ip:port/digitalWrite/8/1 to turn on the LED, and http://ip:port/digitalWrite/8/0 to turn it off, and read analog values with analogRead/0.

This example from bildr will also teach you how to control a sequence of LEDs by reading the GET request.

https://www.anrdoezrs.net/links/7251228/type/dlg/sid/UUmuoUeUpU61000/https://vimeo.com/24849170

You might also like to checkout this example which outputs a form on the page to control a blinkm RGB LED, though you could easily adapt it for an RGB  strip such as the dynamic ambient lighting project we built a while back.

Well, I had fun building these, so I hope you did too. If you've made a library which makes serving up pages and controls simple, please do get in touch in the comments.