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!
Here’s a high level overview of our project. We'll be using PubNub so there's no need to program a webserver.
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.
The PubNub IoT Model House on Vimeo.
Prototype
Create the breadboard prototype.
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.
- Instead of the 9v shown above, we’ll power the Arduino over USB.
- 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!
- 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.
- 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
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.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
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.
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);
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.
Simple Mobile Website
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.
<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
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.
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.
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
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.
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.
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.
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.
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.
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.
You can crack your header pins off on the corner of a table to get the required number.
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).
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.
You can see the wood starting to split a little, but it'll hold.
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.
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!
Check out how the light is refracted in this gif.
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.
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.
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!
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.
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.
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.”