Click here to Skip to main content
15,881,248 members
Articles / Internet of Things / Arduino

How to build an Arduino powered smart home

Rate me:
Please Sign up or sign in to vote.
4.98/5 (62 votes)
28 Jan 2015CPOL13 min read 177.4K   79   20
Connect a (laser-cut) model house to the internet and take control of it's lights and doors!

Table of Contents

Overview

Now you too can own a smarthome! In this tutorial you will laser cut your own model house, connect it to the internet, and build a mobile website to control it!

Image 1

Here’s a high level overview of our project. We'll be using PubNub so there's no need to program a webserver.

Image 2

The project is set up like this:

  • On the right we have a mobile website that sends messages to a PubNub channel.
  • On the left is an Arduino microcontroller with an internet connection. It connects to the same pubnub channel as the mobile website and listens for messages.
  • When the house receives a message from the channel it turns on a digital pin.
  • The digital pins on the Arduino feed into a chip which powers the LEDs and servos.
  • The extra chip provides resistance, grounding, and power to the servos.

Both the web app and the Arduino communicated over the PubNub network to send small message strings to each other using a publish/subscribe protocol.

Project Video

Check out this timelapse video of me building the first IOT house.

Image 3

The PubNub IoT Model House on Vimeo.

Prototype

Create the breadboard prototype.

Image 4

For the breadboard prototype you'll need:

Part Quantity Used Here Part
Arduino 1 Uno (Rev 3) Arduino Uno Rev 3
Ethernet Shield 1 Seedstudio Seed Studio Ethernet Shield V1
LED 4 Superbright white Linrose BCMD333UWC-5PK Brite White T1-3/4 LED
Servos 2 Plastic HOSSEN Mini SG90 Micro 9g Servo
Battery Holder 1   Philmore Four AA Battery Holder w/ Snap Connector
Batteries 4 Fry's Brand AA
Jumper Cables 20 Sparkfun Jumper Wires - 30 pack - Retail
RTL-11242 ROHS
Breadboard 1 Sparkfun

Breadboard - Translucent Self-Adhesive (Clear)
PRT-09567 ROHS Has 3D Model

I prototyped the circuit on a breadboard. This is a very simple circuit, the only thing that should stand out is the extra battery pack. Notice how it shares a ground with the Arduino!

Connect your jumper cables just as the diagram shows. You can test your setup with some simple code. Try the blink example and the servo example.

  1. Instead of the 9v shown above, we’ll power the Arduino over USB.
  2. No ethernet shield is depicted in the diagram. I used Ethernet Shield v2 from SparkFun but any version will work. You need to have an internet shield or your project won't be able to connect to the internet!
  3. Make sure you add resistors to your LEDs. The specific resistance will differ depending on what kind of LEDs you have, but you can use this handy calculator to figure out what resistance you need.
  4. If you don’t have a 4xAA battery pack, you can wire the servos directly to the 5v pin. However, when load is connected to the servos this won’t be enough power. You’ll have to add a battery pack later or the ethernet shield won’t have enough power.

Arduino Sketch

Image 5

Let's start coding. 

Below we include our libraries and start our main setup() function. This code is largely based off the PubNub Arduino example.

You’ll need to download the PubNub Arduino library and import it into your project. 

  • The PubNub library uses Ethernet.h but we don't need to use it much.
  • We also need to supply the PubNub library with publish and subscribe keys. For now we'll be using the default demo keys.

Next, we define a channel to connect to. In this case it's iot_house. This is the PubNub channel that our Arduino will listen for messages on.

#include <JsonArray.h>
#include <JsonHashTable.h>
#include <JsonObjectBase.h>
#include <JsonParser.h>
#include <Bridge.h>
#include <HttpClient.h>
#include <Servo.h>

HttpClient client;

Servo frontDoor;
Servo garageDoor;

int lightLeft = 11;
int lightRight = 10;
int lightRoom = 9;
int lightGarage = 8;
int servoDoor = 7;
int servoGarage = 6;

bool asyncdemo = false;

void setup() {
  // Bridge takes about two seconds to start up
  // it can be helpful to use the on-board LED
  // as an indicator for when it has initialized
  Bridge.begin();
  
  client.setTimeout(2000);
  
  pinMode(lightLeft, OUTPUT);
  pinMode(lightRight, OUTPUT);
  pinMode(lightRoom, OUTPUT);
  pinMode(lightGarage, OUTPUT);
  
  blink(300, 5);
  
  frontDoor.attach(servoDoor);
  garageDoor.attach(servoGarage); 

  reset();
  
}

A channel is like an IRC room, and once the Arduino sketch connects it can receive messages sent from any other device, like a computer, phone, or even another Arduino!

The loop

Image 6

The code uses a key value syntax to process messages. When it receives a message it fires a function with the same name as the key, and turns the value into a Boolean and sends it as the only parameter to the function.

Image 7

Every time the process loops, Arduino connects to PubNub over the internet and asks the PubNub API if there are any new messages. PubNub will respond if there are, but if not, the connection is left open. After a short timeout, PubNub will respond with an empty array and loop() will become unblocked and start again.

If there are messages, we process them as key value pairs. Check out the if/then statements at the bottom of our summarized loop statement here:

void loop() {
  
  Serial.println("subscribe called");

  String sub = "demo";
  String pub = "demo";
  String chan = "pubnub_iot_house";

  String url = "http://pubsub.pubnub.com/subscribe/" + sub + "/" + chan + "/0/" + timetoken;
  
  char sub_buff[200];
  char next_char;
  String thejson;

  Serial.println(url);
  client.getAsynchronously(url);
  
  // Wait for the http request to complete
  while (!client.ready()) {

    if(asyncdemo) {
      pingpong(1);
      off();
    }
  
  }
  
  while (client.available()) {
  
    next_char = client.read();
    
    Serial.print(next_char);
    
    if(String(next_char) == '\0') {
      break;
    } else {
      thejson += next_char;
    } 
    
  }
  
  Serial.println("the json is"); 
  Serial.println(thejson);
  
  int firstParen = thejson.indexOf('(');
  int lastParen = thejson.lastIndexOf(')');

  String thejson2 = "";
  
  for(int i = 0; i < thejson.length(); i++){
    if(i == lastParen) {
      Serial.println("last paren");
      break;
    }
    if(i > firstParen) {
      thejson2 += thejson[i];
    }
  }
  
  Serial.println(thejson2);

  thejson2.toCharArray(sub_buff, 200);
  
  JsonParser<32> parser;
  JsonArray root = parser.parseArray(sub_buff);

  if (!root.success()) {
    
    Serial.println("fail");
  
  } else {
    
    timetoken = root.getString(1);
  
    JsonArray messages = root.getArray(0);
    
    Serial.print("array len ");
    Serial.print(messages.getLength());
    
    Serial.println();
    
    if(messages.getLength() < 0) {
      Serial.println("no data");
    }
    
    for(int i = 0; i < messages.getLength(); i++){  
      
      JsonHashTable message = messages.getHashTable(i);
      
      if (!message.success()) {
        Serial.println("fail");    
      }
      
      String name = message.getString("name");
      String valueString = message.getString("value");
      
      Serial.println(name + ":" + valueString);
  
      boolean value = false;
      if(valueString == "1") {
        value = true;
      }
  
      if(name == "door") {
        door(value);
      }
  
      if(name == "garage") {
        garage(value);
      }
  
      if(name == "lightLeft") {
        light(lightLeft, value);
      }
  
      if(name == "lightRight") {
        light(lightRight, value);
      }
  
      if(name == "lightRoom") {
        light(lightRoom, value);
      }
  
      if(name == "lightGarage") {
        light(lightGarage, value);
      }
      
      if(name == "blink") {
        blink(100, valueString.toInt());
      }
      
      if(name == "pingpong") {
        pingpong(valueString.toInt());
      }
      
      if(name == "demo") {
        demo();
      }
      
      if(name == "async") {
        asyncdemo = value;
      }
    
    }
    
  }

  Serial.flush();
  
}

Here is the full code. Load this up on your Arduino.

Sending Messages to Arduino

Let’s try it out! Run the code and check your Serial output. If everything looks good, let's try sending messages to the Arduino.

We’ll be using the PubNub developer console to publish messages to our channel. Enter the same demo keys and the channel iot_house.

As you can see in the video, we'll use “garage:0” or “lightLeft:1” to close the garage and turn the left light on.

Image 8

Simple Mobile Website

Image 9

Now that we've got the Ardunio working, let's build the website. We'll build a UI to control the Arduino circuit. We’ll be using:

  • jQuery
  • jQuery mobile
  • PubNub Javascript SDK

This web app is pretty simple. Remember our key/value syntax from the breadboard? We’ll use that as the html id. The open and close buttons have value="" properties which act as the value we send to PubNub. 

<div class="ui-grid-a toggle" id="door">

  <legend class="ui-block-a">Front Door:</legend>

  <div class="ui-block-b">

    <button type="button" class="ui-shadow ui-btn ui-corner-all ui-btn-inline" value="1">Open</button>

    <button type="button" class="ui-shadow ui-btn ui-corner-all ui-btn-inline" value="0">Close</button>

  </div>

</div>

So our javascript will wait for a click on the button elements and broadcast the commands as key/value pairs.

For example, if you click on the button above, it would broadcast door:1 or door:0 depending on the button you clicked.

JavaScript
<script>

  $(function() {

     var channel = "iot_house";

     var pubnub = PUBNUB.init({

       publish_key: 'demo',

       subscribe_key: 'demo'

     });

     $('button').click(function(){

       var value = $(this).val();

       var module = $(this).parent().parent().attr('id');

       pubnub.publish({

         channel: channel,

         message: {

           name: module,

           value: value

         }

       });

     });

   });
</script>

Get the full code here. Once you’ve got all this hooked up, it’s time to laser cut the house!

 

Laser Cut the House Model

Image 10

Use this CAD file of a house from “The Simpsons.” It’s extremely well designed and only $15. The garage and front door are hinged which make it perfect for our project.

I took a 2 hour lesson here at ATX Hackerspace and learned how to use the laser cutter. You can find a laser cutter at your local hackerspace or TechShop.

  • I imported the laser file into inkscape and ran the laser at fairly powerful settings.
  • My supplied me with some extra Eucaboard, but it was very thick and difficult to cut.
  • This file is snap-fit.
  • You'll need to measure the height of the holes found in the roof and scale your project down until they match the thickness of your material. This specific laser model was designed with a  3mm thickness.

Image 11

I wasted half of the board because Corel Draw determines scaling settings when each file is opened. Apparently I cut all 4 laser files at different scales, so none of the pieces fit together!

Assemble and glue

Glue the smaller parts of the house, like the windows, chimney, and doors. I used Gorilla glue.

Image 12

It turns out gorilla glue is messy because it expands over time. This created a bunch of huge solid glue globs that completely ruined the aesthetics of the house. Use small amounts.

I used a dremel to cut away at the excess glue. It took me a while but I definitely leveled up my dremel skills.

Don't glue the entire project together just yet, we've still got work to do.

Solder the Prototype Board

Image 13

This part is easier than it seems. All we're going to do is make the breadboard we made earlier a little more permanent. It is exactly the same circuit as shown in the Arduino diagram above. 

Image 14

All we're going to do is use wires and solder to keep the board together. We're also going to add female headers on either side so we can swap out LEDs, servos, and disconnect the Arduino. Check out the diagram below. 

Image 15

Notice the female headers and the resistors on the opposite side. These female headers give us the ability to create "plugs" by soldering male headers onto our wires in the next step.

Image 16

The circuit could also be built upon an Arduino prototype board which would make the project more stable and elimante the need for our jumper cables.

Test the Prototype Board

Once the board is soldered, try integrating it into your circuit. Route the digital pins from the Arduino to the right side, and your LEDs and Servos on the left.

Here's a preview of what the board will look like when it's all hooked up. The Arduino is on the right (missing ethernet shield) and our prototype board on the left.

Image 17

Once you're sure it works, takea hot glue gun and completely engulf the soldered points with glue. This will keep them from wearing. Don't worry, if things do go wrong, it's easy to cut away at the glue and start over.

Build Wires

You may be wondering, why did we build an assemble the house before the circuit was complete? Wires is why. We built the house so we could have an idea of how long our wires will need to be. 

Think about where you want to put your LEDs and servos. Measure out a little more wire than you need.

Image 18

You'll want to use wire with a small guage. I like to color code and braid mine.

Strip the wire ends and solder header pins onto both sides.

Image 19

You can crack your header pins off on the corner of a table to get the required number.

Image 20Image 21Image 22

These are some of the wires I created. The first is a simple LED wire with power and ground.

The second is a servo extension wire with power, digital, and ground. This allows us to reach the servo by the garage.

Ther last is called a "double header pin" and we just plug it into the female server plug. This allows us to plug the servo directly into the prototype circuit board. The front door is close enough to the board that we won't need to do any custom wiring.

You can solder the LEDs directly to your wire. Wrap them with electrical tape and feed a strip between the exposed wires so they won't short. 

Once you've built some wires, test them out. Attach them to the breadboard and see if they work. If they do, continue onto the next step!

Mount the LEDs

Using a dril bit that matches the size of your LED, drill a hole into the house walls. I was able to find some handy plastic LED mounts at my local Fry's electronics, so I used those to keep the LEDs steady.

The LED mounts are Linrose B4304MC 1/4" Mounting Clip For 1/34" (5mm).

Image 23

Image 24

The LED mounts fit right into the hole, and the LEDs snap into the mounts. Awesome!

Mount the Servos

For the garage door servo, I used tiny nails commonly used for moulding to mount the plastic servo arms to the garage door. I chopped off the hinge on the garage door with the idea being that the servo arm would replace it.

Image 25

You can see the wood starting to split a little, but it'll hold.

Image 26

Then use a dremel or drill to cut out a hole on the right side of the house to fit the servo in. Once the hole was big enough to fit through the hole, try connecting the garage door and adjust until it rotates smoothly.

Image 27

I was able to use a similar approach on the front door as the garage. I glued the servo arm to the door, then simply stuck the servo in! The servo is loosely taped to the inner wall. See the above GIF.

Build Windows

We'll need to diffract light from the windows in order to make the lights in the house look realisitc. I used clear acrylic from a poster frame. I'm not sure where to source this as it was something I had lying around.

Cut the acrylic into squares and glue it onto the back of the window structures. I used super glue here.

Take some tissue paper and cut small squares. Drop a tiny drop of super glue into each corner of the paper. This will adhere it to the plastic. Now we have realistic windows!

Image 28

Check out how the light is refracted in this gif.

Image 29

Mount Prototype Board

Mount the prototype board to the back of the house. I used longer screws and glued some foam material inbetween the board and the wall to keep it snug.

I used a flexible screwdriver to reach inside the house.

Image 30

Mount Arduino Board

Use small screws to mount the Arduino to the house. I mounted it the back corner of the large room and I drilled holes to access the ports. Make sure you can still reach all the buttons on the Arduino and Ethernet ports.

Image 31

Also notice the routing holes above the Arduino. This is to feed wires through. Decide where these go before mounting the board.

Mount Battery Pack

Find a good place to mount the battery pack. I chose the small room on the right side. Wire the battery pack to prototype board and fill it with juice!

Image 32

Final Assembly

Test the mobile website and the house one more time! Then, take everything apart so we can glue it together without messing anything up.

Image 33

Trace the edges of the house with glue. I used Gorilla glue again.

Clamp it all together and wait a couple hours and remove excess glue with a dremel.

Congratulations! You've got your very own IOT house.

Image 34

FAQ

One of the LEDs does not turn on

Follow the LED wire and find the plug. Make sure it is connected properly and the ground wire (black) is at the top.

Unplug another LED that is confirmed to work and plug the bad LED into it’s plug. If the LED turns on, the fault is not in the wire or LED. The included multimeter can come in handy here.

Check the jumper cables. Make sure they start at 11 and go to 6 and are properly plugged in.

If the jumpers check out the fault is in the prototype (yellow) circuit board. Unplug everything and unmount the board from the house using the included flexible screwdriver. Cut away at the hot glue with the included pliers to expose the soldered elements. Press on elements to try and determine if any connection is loose. If it is, use the included soldering iron to fix the connection.

One of the servos doesn't work

Follow the servo wire. Make sure the servo is plugged in with the ground wire (black) on top. Debug in a similar fashion to LEDs as found in the previous paragraph.

Feel the servo. If it vibrates when receiving a command but fails to turn, it is either a) already in the correct position or b) jammed. It is possible to unjam the servo by using a servo mount to force the servo gears. 

Otherwise replace the servo

Both of the servos don't work, but the LEDs do.

Make sure you put batteries into the AA battery compartment. If they are present, try replacing them - they may have died. Confirm the power plug makes a solid connection from the battery pack to the bottom of the prototype (yellow) board.

Is that the Simpsons house?

Yes it is.

What material did you use?

Eucaboard.

The Servos are clicking loudly or getting hot.

The servo is under too much load. Try repositioning the servo. Make sure the servo is in a “closed” state before mounting as described in the video. See “One of the servos does not work.”

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDownload links for the Libraries Pin
Member 1354377827-Nov-17 3:59
Member 1354377827-Nov-17 3:59 
QuestionDownload links for the Libraries Pin
Member 1354377827-Nov-17 3:59
Member 1354377827-Nov-17 3:59 
GeneralMy vote of 5 Pin
Slacker00720-Oct-16 23:56
professionalSlacker00720-Oct-16 23:56 
QuestionWifi Pin
Member 1254724425-May-16 21:29
Member 1254724425-May-16 21:29 
Questionsoftware requirement Pin
kareemo15-May-16 10:19
kareemo15-May-16 10:19 
QuestionThis is awesome.... Pin
Swagat Parida21-Feb-16 18:21
Swagat Parida21-Feb-16 18:21 
GeneralMy vote of 5 Pin
teng33887-Dec-15 14:57
teng33887-Dec-15 14:57 
PraiseGreat article I have really enjoyed a lot... Pin
Suvabrata Roy19-Nov-15 22:50
professionalSuvabrata Roy19-Nov-15 22:50 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun9-Nov-15 18:43
Humayun Kabir Mamun9-Nov-15 18:43 
QuestionModel not available Pin
dxider24-Apr-15 11:15
dxider24-Apr-15 11:15 
QuestionMy vote 5 Pin
Nelson Kosta Souto29-Jan-15 4:09
professionalNelson Kosta Souto29-Jan-15 4:09 
GeneralMy vote of 5 Pin
DrABELL18-Jan-15 12:17
DrABELL18-Jan-15 12:17 
QuestionMy Vote of 5! Pin
Karthickeyan.k14-Jan-15 17:11
Karthickeyan.k14-Jan-15 17:11 
GeneralMy vote of 5 Pin
Agent__00730-Dec-14 16:52
professionalAgent__00730-Dec-14 16:52 
GeneralMy vote of 5 Pin
Ranjan.D25-Dec-14 7:38
professionalRanjan.D25-Dec-14 7:38 
QuestionGood article. Pin
JustJimBean23-Dec-14 20:06
JustJimBean23-Dec-14 20:06 
GeneralMy vote of 5 Pin
DaveAuld22-Dec-14 7:22
professionalDaveAuld22-Dec-14 7:22 
Excellent project, sure it kept you busy for a while!
GeneralThanks for entering! Pin
Kevin Priddle22-Dec-14 4:19
professionalKevin Priddle22-Dec-14 4:19 
GeneralRe: Thanks for entering! Pin
ianjennings22-Dec-14 6:43
ianjennings22-Dec-14 6:43 
GeneralMy vote of 5 Pin
roscler21-Dec-14 19:20
professionalroscler21-Dec-14 19:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.