WebPlug: home automation using Arduino

Hi fellas.

Today, I’m going to show you one of the coolest things you can do with an arduino: controlling home appliances. We’re going, within a very few steps, dive into home automation. And when I say “appliances”, I mean your lights, your coffe machine…

Here’s the things you will need:

  • First, an Arduino. Any model will do the job. I will use an old Mega 1280 because it has a lot of  digital pins, but even the tiny Mini Pro from sparkfun can fit.

  • Secondly, an Ethernet Shield. I’m going to use the official Ethernet Shield, but then again there are many ones that can do the job perfectly.
  • Relay Boards. I got two opto-isolated 4 channels relay boards from YourDuino , they sell incredible stuff at incredible price, I strongly recommend them. $8.5 for a 4 relays board is quite an incredible deal 😉 They also got 8 relays boards.
  • Wires

We will need some other stuff to complete the project, but right now it’s enough.

Step 1: Setting up the shield.

First, we need to get the Ethernet shield to work. Assemble the arduino and the shield, then plug them.

Once done, upload the “WebServer” example from the Arduino IDE. Then, direct your browser to the IP specified at the very beginning of the code (should be 192.168.1.177):

Yay, Arduino’s responding! Now we can go to the next step.

Step 2: controlling pins on request

Now we need to control digital I/O using URLs. I found a very cool tutorial about this on bildr’s website. Basically, the goal here is to turn LEDs on and off. I slightly modified his code to fit my needs:

//ARDUINO 1.0+ ONLY
//ARDUINO 1.0+ ONLY

#include <Ethernet.h>
#include <SPI.h>
boolean reading = false;

const int DLY = 100;
const int RLY1 = 30;
const int RLY2 = 31;
const int RLY3 = 32;
const int RLY4 = 33;

byte ip[] = { 192, 168, 0, 177 };   //Manual setup only
byte gateway[] = { 192, 168, 0, 1 }; //Manual setup only
byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only

// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

EthernetServer server = EthernetServer(80); //port 80

void setup(){
  Serial.begin(9600);

  pinMode(RLY1, OUTPUT);
  pinMode(RLY2, OUTPUT);
  pinMode(RLY3, OUTPUT);
  pinMode(RLY4, OUTPUT);

  Serial.println("Testing relays...");

  for (int i=RLY1; i<=RLY4; i++) {
    digitalWrite(i, LOW);
    delay(DLY);
    digitalWrite(i, HIGH);
    delay(DLY);
    digitalWrite(i, LOW);
    delay(DLY);
  }

  Ethernet.begin(mac);
  //Ethernet.begin(mac, ip, gateway, subnet); //for manual setup

  server.begin();
  Serial.println(Ethernet.localIP());
}

void loop() {
  checkForClient();
}

void checkForClient(){

  EthernetClient client = server.available();

  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected()) {
      if (client.available()) {

        if(!sentHeader){
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          sentHeader = true;
        }

        char c = client.read();

        if(reading && c == ' ') reading = false;
        if(c == '?') reading = true; //found the ?, begin reading the info

        if(reading){
           switch (c) {
            case '1':
              Serial.println("RLY1 ON");
              triggerPin(RLY1, true, client);
              break;

            case '2':
              Serial.println("RLY2 ON");
              triggerPin(RLY2, true, client);
              break;

            case '3':
              Serial.println("RLY3 ON");
              triggerPin(RLY3, true, client);
              break;

            case '4':
              Serial.println("RLY4 ON");
              triggerPin(RLY4, true, client);
              break;

            case '5':
              Serial.println("RLY1 OFF");
              triggerPin(RLY1, false, client);
              break;

            case '6':
              Serial.println("RLY2 OFF");
              triggerPin(RLY2, false, client);
              break;

            case '7':
              Serial.println("RLY3 OFF");
              triggerPin(RLY3, false, client);
              break;

            case '8':
              Serial.println("RLY4 OFF");
              triggerPin(RLY4, false, client);
              break;
          }
        }

        if (c == '\n' && currentLineIsBlank)  break;

        if (c == '\n') {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }

    delay(1); // give the web browser time to receive the data
    client.stop(); // close the connection:
  }
}

void triggerPin(int pin, boolean on, EthernetClient client){
  if (on == false) {
    digitalWrite(pin, HIGH);

    client.print("Turning off relay ");
    client.println(pin);
    client.print("<br>");
  } else {
    digitalWrite(pin, LOW);

    client.print("Turning on relay ");
    client.println(pin);
    client.print("<br>");
  }
  delay(DLY);
}

Now, plug the relay board (pin 30 -> relay 1, pin 31 -> relay 2, pin 32 -> relay 3 and pin 33 -> relay 4) :

Upload the code and open Serial Monitor. You should hear the relay clicking. Here’s a video I made with a faster (DLY=10) version and using two relay boards:

And another one, this time using my phone to access remotely the relays. To achieve this you must setup your DSL modem in order to access it from the outside.

There you hame the main part of the project, now it’s time to create a nice enclosure!

  • steve

    Hi…
    Can i ask if we can connect two client to one server with the use of 2 arduino + ethernet shield?

    • deadbird

      I think it’s possible, yes.

  • Dave Sutherland

    Hi,
    I want to use this sketch on an UNO arduino.
    I edited my IP address and changes the relay pin numbers to 2,3,4 & 5.
    Uploads fine but I cannot ping device or access it from browser.
    Have tried uploading with the ether shield removed.
    testing ether shield with the example webserver sketch works fine.
    Any idea why it wont work ?
    Thanks Dave

    • deadbird

      You have to program tour ARduino to respond to the ping.

  • George

    Very interesting, however, an arduino plus ethernet shield is roughly twice the price of a raspberry pi, which is many time more powerful than this, and includes a full webserver.

    • deadbird

      Right! And for sure future developments will go toward Raspi rather than Arduino!

    • James Bryant

      A basic Arduino compatible ethernet module can be had from China on eBay for under $4 (£2.40/€3) and an Arduino Pro Mini 328 for under £2.70 (£1.60/€2) for a total of $6.70 (£4/€5). This is rather less than a Raspberry Pi. I’ve just ordered ’em and hope to be able to do this control function with ’em.