This instructable shows you how to build a Web-enabled tri-color LED based on an Arduino and the WIZnet Ethernet shield, controllable from any Web browser .

Because the LED is exposed through a simple RESTful web service running on the Arduino color changes can also be triggered by Pachube or other platforms offering Web hooks. Welcome to theWeb of Things ! The LED can of course be replaced by a motor or a high voltage switching relay to enable more interesting browser controlled applications, e.g. for home automation.

Publishing your Arduino through the Yaler relay server makes the Arduino accessible from everywhere even if it is hidden behind a firewall or a NAT and does not have a public IP address. A single Yaler relay server instance can host many Arduinos (and any other device with a TCP Socket library, e.g. a Sheevaplug or an Android phone) and is available at https://yaler.net/ (Disclosure: I'm a founder of Yaler)


  • Tri color LED [Adafruit | SparkFun]
  • Arduino Duemilanove ATmega 328 [Adafruit | SparkFun]
  • Arduino WIZnet Ethernet Shield [Adafruit | SparkFun]
  • Resistors [1 x 150 Ohm, 2 x 82 Ohm for the Adafruit LED or
    1 x 180 Ohm, 2 x 100 Ohm for the SparkFun LED]
  • RJ45 cable


  • Soldering iron
  • Helping hands
  • A / B USB cable


  • Internet access with DHCP, no public IP address needed for Arduino
  • (Optional: PC or Cloud Server with a public IP address, to run Yaler)

Step 1: Soldering Resistors and Wire to the Tri-color LED

(Note: All images show the Adafruit LED with the corresponding resistors and wire color)

  • Shorten all except for the longest leg of the LED
  • Solder the resistors to the LED legs as shown below
  • Shorten the remaining long leg
  • If you use the Adafruit LED, solder the red wire to it [as shown below]
  • If you use the SparkFun LED, solder the black wire to it

Step 2: Connecting the LED to the Ethernet Shield

  • Stack the Ethernet shield onto the Arduino
  • Connect the LED to the pins 3, 5 and 6 (red) of the Ethernet shield
  • If you use the Adafruit LED, connect the red wire with the 5V pin of the Ethernet shield
  • If you use the SparkFun LED, connect the black wire with the GND pin of the Ethernet shield

Step 3: Uploading the Arduino LED Test

To test the LED you can upload the following sketch to your Arduino. Reset the Arduino and make sure the colors show up in the exact same sequence as described in the code comments of the loop statement below. If you use the SparkFun LED uncomment the corresponding lines of code and delete the three analogWrites of the Adafruit LED. If the colors show up in another sequence you might have swapped some pins.

// HelloLed.pde

int redPin = 6;
int greenPin = 5;
int bluePin = 3;

void setColor (int red, int green, int blue) {
// SparkFun LED: write value for each color
//analogWrite(redPin, red);
//analogWrite(greenPin, green);
//analogWrite(bluePin, blue);

// Adafruit LED: write inverted value for each color
analogWrite(redPin, 255 - red);
analogWrite(greenPin, 255 - green);
analogWrite(bluePin, 255 - blue);


void setup () {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

void loop () {
setColor(0, 0, 0); // Off
setColor(255, 0, 0); // Red
setColor(0, 255, 0); // Green
setColor(0, 0, 255); // Blue
setColor(0, 255, 255); // Aqua
setColor(255, 255, 0); // Yellow
setColor(255, 0, 255); // Fuchsia
setColor(255, 255, 255); // White

Step 4: Editing and Uploading the Arduino LED Web Service

Once you made sure the LED works, you're ready to edit and upload the sketch for the LED Web service to your Arduino.

First, install the YalerEthernetServer.zip Arduino library (for details please see https://yaler.net/arduino) then download the YalerLedWebService.inosketch and open it in your Arduino IDE.

Then you have to carry over the changes made to setColor in the previous step. If you did change the pin numbers, carry those changes over as well.

You also have to set the MAC address of your Ethernet shield. It is possible to use the value from the source code, but be aware that address conflicts might arise if a device in your LAN is already using this same address. The MAC address is set in the line byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; and most of the time it is sufficient to change the last byte to another value, e.g. 0xAA.

The next step is to set your Yaler relay domain. You can get a free trial account at https://yaler.net/.

(If you run your own Yaler relay server instance, you'll also have to enter the appropriate host name.)

So, all that's left is to upload the sketch and connect your Arduino to the Internet with an RJ45 cable. In order for the service to run, the LAN must provide DHCP. It's possible to use a fixed IP, but this requires a few changes to the source code that go beyond the focus of this tutorial. To make sure there are no start up timing issues with the Ethernet shield, press the reset button once the Arduino is connected to the LAN.

Step 5: Accessing and Controlling the Arduino From the Web

If the Arduino is connected to the LAN and thereby to the Internet, and if the Yaler instance at the specified IP address is up and running, you should now be able to access the Arduino Web LED at http://{Yaler IP}/{Relay Domain}/led, e.g. http://gsiot-ffmq-ttd5.try.yaler.io/

You'll get an HTTP 504 Gateway Timeout if the Arduino is not running . Depending on your browser this is shown as a blank page or as "Gateway Timeout". In this case, make sure everything is tightly plugged in and try resetting the Arduino.

If everything works as intended, you should see a simple HTML page with three colored buttons . If you press a button, the Arduino LED should light up in the corresponding color.

Behind the scenes this works with a simple Javascript that sends an HTTP PUT request , e.g. PUT http://gsiot-ffmq-ttd5.try.yaler.io/led/ff0000 to the Arduino to set the LED's color. You can use Firefox with the Firebug add-on set to Net > XHR to see the PUT requests.

Note that the URL does not depend on the current location of the Arduino. No matter if it's attached to your home network or to the LAN at your office, the URL remains the same. Just plug in the Arduino and control it with your browser.

Because typing the URL can be cumbersome, you can make use of a QR-Code generator like http://qrcode.kaywa.com/ to get a QR-Code of your Arduino's URL (example below).

Print it, stick it to your Arduino, access it with a QR-Code reader like Lynkee (iPhone), Kaywa (Symbian, Java phones) or Quickmark (Windows Mobile) and there you have a switch-less, yet conveniently controllable Arduino.

That's it! Thanks for your time.

If you got any questions or trouble debugging your setup, please let me know in the comments.

<p>have any one make it as a wifi instead of ethernet </p>
Which WiFi shield / module are you using?
<p>I know this was posted very long ago but I'm trying it and I need some help. I connected everything as said and I pasted the code into the arduino sketch. I put the mac address of my arduino and its connected directly to my router through ethernet. When I uploaded the sketch and ran the serial monitor, it seems that it keeps timing out while everything is connected perfectly because it worked on the example code. This is what it says : </p><p>setup</p><p>connected</p><p>timeout </p><p>connected</p><p>timeout </p><p>Can someone please help me because I really want it to work! Thank you </p>
<p>Hi mhachem, the output looks fine. Did you try to access the URL? (Please reply to tamberg@yaler.net) Kind regards, Thomas</p>
<p>Hey Thomas, Thank you for replying! </p><p>I tried accessing the URL and it just shows me a blank page. </p><p>Everything is connected correctly because your example sketch worked the way it's supposed to. I really don't know what I could be doing wrong that is causing it to time out. </p><p>Please help =[ </p>
<p>Sent you an email reply. Kind regards, Thomas</p>
<p>I am trying a project and ran into NAT'd IP shutting me down. So, I like the idea of the yaler.org relay. what is an email address where I can reach someone about the service? The prices quoted are yearly? Is the 1GB of data for the maker plan yearly as well?</p><p>Thanks</p>
For info, please see https://yaler.net/ or contact tamberg@yaler.net
<p>hi I was wondering if this tutorial is doable with an uno or leonardo board ?</p>
<p>Yes, those should work as well.</p>
<p>Hi, I notice nedhallett2 already asked but got no reply. I would like to know if this would work with the Arduino Uno R3 ?</p>
Yes, it would. Cheers, Thomas
<p>Works great!! best internet controled arduino tutorial I have seen thus far.</p>
Hi, I am trying to reproduce the project using ARDUINO MEGA. I have created an yaler account and I am able to see the webpage with the 3 colored buttons. The problem is that nothing happens pressing the buttons. I added the <strong>following lines</strong> inside the code:<br> <br> if (yalerState == YALER_UPGRADED) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Serial.println(&quot;upgraded&quot;);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receiveRequest(client);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (state == DONE) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (isPut) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> Serial.print(&quot;&nbsp;&nbsp;&nbsp; led0=&quot;);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serial.print(led[0]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serial.print(&quot;&nbsp;&nbsp;&nbsp; led1=&quot;);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serial.print(led[1]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serial.print(&quot;&nbsp;&nbsp;&nbsp; led2=&quot;);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serial.println(led[2]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setColor(led[0], led[1], led[2]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sendPutResponse(client);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sendGetResponse(client);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br> &nbsp;&nbsp;&nbsp; } else {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Serial.println(&quot;timeout&quot;);<br> &nbsp;&nbsp;&nbsp; }<br> <br> &nbsp;I want to see what data is send to the PWM channels. The result from the Serial monitor is:<br> <br> <strong>&nbsp; &nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0<br> &nbsp;&nbsp;&nbsp; led0=0&nbsp;&nbsp;&nbsp; led1=0&nbsp;&nbsp;&nbsp; led2=0</strong><br> <br> &nbsp;That means - pressing the buttons does not effect the values for the LED intensity. Please suggest where the problem could be...
Hi, the parsing of the incoming HTTP request in this example is not very robust. There might be a broken offset or something similar in receiveRequest. Unfortunately I don't have an Arduino at hand to test anything before mid January. Regards, Thomas
Hi, <br> <br>I made changes to the code and everything. Now I'm trying to access the website but I can't. I tried{Relay Domain}/led and http://try.yaler.net/{Relay Domain}/led. Both of the lead to server error page. Am I missing something here?
Hi,<br><br>the server error page is likely HTTP Status 504 (Gateway Timeout). This is Yaler's response if no device is available at the given Relay Domain.<br><br>Reasons might vary from typos to memory overflow. Can you add some Serial output to your Arduino program to see if the program is running and if it get's the request from your browser?<br><br>Kind regards,<br>Thomas
Hi, <br> <br>Thanks for the reply. I uncommented all serial print commands in the code. It prints setup on the serial monitor which means it goes through void setup but nothing after that and I can't access the website. Am I using the correct web address here? I'm using arduino nano with ethernet shield btw if that makes any difference. <br> <br>Thank you.
If the shield works fine with other examples, maybe the Nano runs out of memory?
Hi, <br> <br>When you say &quot;you should now be able to access the Arduino Web LED at http://{Yaler IP}/{Relay Domain}/led&quot;, what is the Yaler IP?
Hi, if you use the hosted ervice the IP in the source code is fine.<br><br>Kind regards,<br>Thomas
hello sir,.can you upload the complete code???
Just sent you a message. Regards, Thomas
Hi tamberg, firstly congratz for this very useful post. I'm quite new with Arduino and Web of the Things staff, I'd like to implement the java apps directly on my google app engine account, I use Eclipse for that purpose, any suggestion? ReneX
He renexdon, Sounds great. Your Java App could call the Arduino via HTTP. Regards, Thomas
Are you planning to get your demo working again? I enjoy playing with it, it is my homepage
Glad you like it. Sometimes it's stuck and needs a reset. Will do that ASAP.
Great project, but it doesn't seem to work for me. Everything compiles and I can connect to the Arduino and see the colour select page, but when I click one of the boxes, it doesn't change on the Arduino. Any ideas? I get this output when I hit the page: <br> <br>n/led/ HTTP/1.1 <br> <br>And this when I click on the RED box: <br> <br> <br>n/led/led/ff0000 HTTP/1.1 <br>Host: try.yaler.net <br> <br>It looks like the &quot;isPut&quot; variable never gets set to &quot;true&quot; and so the pins never get set.
jaypozo, the code didn't work anymore due to a change on the relay. Please download the updated version from this Instructable. Regards, tamberg
Hi, from the output it seems the path is shorter than the code expects. Which URL are you using to access your Arduino? Kind regards, tamberg
This is the URL I'm using: http://try.yaler.net/gsiot-2fds-hkan/led/
Ok. Does it work if you use http://try.yaler.net/gsiot-2fds-hkan/led instead (without the final slash)? <br> <br>Regards, <br>tamberg
Just updated the ZIP downloads to reflect the new relay IP address and fix a parsing error.
ok i can get it to compile and everything but my network keeps showing it as expired on the lease.
Hi, according to this thread http://code.google.com/p/arduino/issues/detail?id=716 calling maintain() might help. Cheers, tamberg
I had a problem, when compiling the &quot;HelloTriColorLedYalerService.pde&quot; sketch, the result return with errors and the main error is &quot;cannot declare parameter 'c' to be of abstract type 'client'&quot; can i know why ? I've add the EthernetDHCP into libraries but still produce that error. TQ
Whanif, thanks for trying the code. Which Arduino model and Arduino IDE version did you use? And which version of the libraries? It's been some time since I wrote this code. Cheers, tamberg
Thank you for the reply, I'm now using Arduino Uno Revision 2 and the IDE is version 1.0, for the libraries, it is Version 1.0b4. Thanks in advance...
Ok. I don't have an Arduino Uno R2, but I can try to recompile the code with the new IDE and libraries this weekend. Sorry for the delay...
Ok, thank you for your help...
Looks like the Arduino libraries changed significantly with v1.0, as far as Ethernet is concerned. Upgrading the code might take some time. As a quick fix you can try to use Arduino 0018 (if that works with the Uno).
Just added a new version of the source code for Arduino 1.0. Please let me know if it works for you. Cheers, tamberg
I've patched my latest Arduino libraries to version 0018 and this error come up --&gt;<br><br>sketch_jan30a:-1: error: variable or field 'receiveYalerResponse' declared void<br>sketch_jan30a:-1: error: 'Client' was not declared in this scope<br>sketch_jan30a:-1: error: variable or field 'sendPutResponse' declared void<br>sketch_jan30a:-1: error: 'Client' was not declared in this scope<br>sketch_jan30a:-1: error: variable or field 'sendGetResponse' declared void<br>sketch_jan30a:-1: error: 'Client' was not declared in this scope<br>sketch_jan30a:-1: error: variable or field 'receiveRequest' declared void<br>sketch_jan30a:-1: error: 'Client' was not declared in this scope<br>In file included from C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Ethernet.h:5,<br> from sketch_jan30a.cpp:29:<br>C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Client.h:17: error: conflicting return type specified for 'virtual void Client::write(uint8_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Client.h:19: error: conflicting return type specified for 'virtual void Client::write(const uint8_t*, size_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:50: error: overriding 'virtual size_t Print::write(const uint8_t*, size_t)'<br>In file included from C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Ethernet.h:6,<br> from sketch_jan30a.cpp:29:<br>C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Server.h:20: error: conflicting return type specified for 'virtual void Server::write(uint8_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\libraries\Ethernet/Server.h:22: error: conflicting return type specified for 'virtual void Server::write(const uint8_t*, size_t)'<br>C:\Documents and Settings\User\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:50: error: overriding 'virtual size_t Print::write(const uint8_t*, size_t)'<br>sketch_jan30a.cpp: In function 'void setup()':<br>sketch_jan30a:217: error: redefinition of 'void setup()'<br>sketch_jan30a:2: error: 'void setup()' previously defined here<br>sketch_jan30a.cpp: In function 'void loop()':<br>sketch_jan30a:230: error: redefinition of 'void loop()'<br>sketch_jan30a:7: error: 'void loop()' previously defined here<br><br><br> any ideas ?
Assuming you are using the unchanged code from this Instructable it's hard to understand how those errors could result. Unfortunately my 0018 version of the IDE is broken in another way. I tried to verify the code on 0022 though, and there it works if you select the menu entry Include &gt; SPI before verifying the code.<br><br>Sorry for the trouble, <br>tamberg
Looks like try.yaler.net is down again. A very interesting project. Was planning something of the sort
Cvasantrao, the relay try.yaler.net is up and running (http://status.yaler.net/), but it happens that the Arduino goes offline (the current code needs a reset from time to time) which results in a 504 Gateway Timeout. Some browsers display this as an empty page or even an error. Cheers, tamberg
I have a similar project i'm working on, an alert light based on values in a database. I originally started this project thinking I would be making outbound requests to a webserver, on a timer, from Arduino and switching lights based on the returned values. <br><br>Am I better off having having the webserver send simple requests to my Arduino device or the other way around.
Hi amcelmon, interesting question. If you need real-time updates, the timer would probably be a bad idea, as the interval would have to be very low and thus a large number of requests (most of them in vain) would be sent from the Arduino. If a delayed update is fine, your solution would work and probably be simpler. But another question is how much of the logic you'd like to put on the Arduino. My example exposes just a very thin API layer above the hardware (i.e. the LED), which enables you to keep the application logic in the cloud (as a Web client) or even on your desktop (try cURL with my LED). This way (embedded device as a Web server) it's almost trivial to make mash-ups using different Web APIs. Cheers, tamberg
PS. In your case you can further decide to couple your DB Web Server tightly with the Arduino (by calling out directly from the DB Web server to the Arduino Web server) or loosely (by having a scripted Web client call both your DB Web server and the Arduino LED Web server).

About This Instructable




More by tamberg:Voodoo Sonic LoRaWAN-connected doll IoT Gauge with Arduino, Yaler & IFTTT Log Arduino output for days with a BeagleBone 
Add instructable to: