Building a Voice Controlled Home Automation Model — Part 3— Arduino Code

Timi Ajiboye
chunks of code*
Published in
5 min readNov 7, 2016

This is the third part in the Building a Voice Controlled Home Automation series. You can find the first part here.

At the end of the second part, we loaded some code (this Gist) unto our Arduino, to test if our LEDs and servos are working. Today however, we’ll be adding to that code, to make it subscribe to a Pubnub channel and act on instructions sent to the channel (via the Android application).

Test Code Overview

Before we proceed, I want to go over some of the methods in the Gist, because it’s those same methods we’ll use to turn on the lights or close the doors.

1. Arduino default methods

I mentioned these in the last post but they’re worth copying and pasting here:

The entire functionality of an Arduino happens in two functions, namely: void setup() and void loop().

setup() is where you write code that you want to happen only once, after each power up or reset of the Arduino board.

loop() keeps getting called repeatedly for as long as the board is on and functional. It is in this function that all the magic happens. In this function, you can keep checking if there’s a new message from our Android application and then turn on/off the appropriate LED.

2. Libraries

If you look at the top of the file/gist, you’ll see the following line of code.

#include <Servo.h>

The first line is pretty easy to understand, we want to include the Servo library so that we can use it’s classes and methods to interact with our servos.

You can read more about the Servo Library here.

Add Servo library

You can add libraries as in the image above. If the library you want isn’t listed, you can click on “Add Library…”, then navigate to the folder that the library was downloaded to.

3. Variables

Below that first line, we created some variables

Servo frontDoor;
Servo garageDoor;
int lightDining = 11;
int lightOutside = 10;
int lightKitchen = 9;
int lightLivingroom = 8;
int servoDoor = 7;
int servoGarage = 6;

Another worthy copy and paste:

…It has numbered output ports running along each side. So if, for example, you connect an LED to 11, and you want to turn it on, you simply write code to send a HIGH signal to 11like so:

digitalWrite(11, HIGH);

Now we can easily write digitalWrite(lightDining, HIGH) to turn on the LED at the dining room and that saves us the stress of having to remember port numbers.

4. Methods: light(), door(), garage().

Finally, there were three convenience methods created to further ease out development.

void light(int ledPin, bool on) {
Serial.println("led");
if (on) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}

}

This method makes it easy to switch on or off an LED; light(lightKitchen, true) will turn the kitchen light on.

void door(bool open) {

Serial.println("door");

if (open) {
frontDoor.write(80);
} else {
frontDoor.write(20);
}

}
void garage(bool open) {

Serial.println("garage");

if (open) {
garageDoor.write(150);
} else {
garageDoor.write(80);
}

}

door(true) will open the house door and garage(false) will close the garage door.

Note: The angles 80, 20, 150 I chose are dependent on the positioning of my servos in your my house model. You might have to experiment with different angles before finding ones that work as suitable open and close states for your door and garage.

Complete Arduino Code

The complete sketch for the Arduino can be found here. It’s very tempting to copy the code and paste it in — in fact, that’s what I initially did. After a while, I decided to read it all line by line to understand everything and you should too.

In fact, the gist I keep talking about above is a truncated version of this code, but I don’t think I would have been able to create and explain it without understanding the complete thing first.

I don’t plan to leave you unassisted, however, I’ll try to explain some of the things I think are important:

1. ArduinoJson

At the very top of the iot_house.ino file, you can see a couple of included files that have “Json” in them. They’re from the ArduinoJson library. What might not be immediately apparent is that this code uses v1.o of the library. So you have to download that and import the files into your project. ArduinoJson is a lightweight, JSON parser for Arduino. We’re going to be making API calls (to Pubnub) and we need to be able to parse the JSON response to detect if a new instruction has been sent to the channel or not.

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

The other imports can be imported/included without any other consideration.

2. Some of the other libraries

  • HttpClient is used for making http calls (to PubNub).
  • The Bridge, well, that does a lot of things. Further reading can/should be done here, here and here.

3. The loop function

Remember the loop() function? It keeps getting called repeatedly. So obviously, this is where our logic should be. Below is a high level overview of what’s happening in loop(). It’s (relatively) a lot of code, so this should help.

Arduino loop() function

Basically, we’re hitting the subscribe endpoint,

...
Serial.println("subscribe called");
String sub = "demo";
String pub = "demo";
String chan = "my_channel_2234";
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);
...

Checking if there’s any message with an instruction and then carrying it out.

...
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);
}
...

Then doing it again and again and again…till the end of time.

You can test this by sending messages to your channel by using the Pubnub Debug Console.

Remember to change the Pubnub keys and channel variables to the ones you get after creating an application on Pubnub.

That’s all for today.

In the next post in this series, we’ll create an application on Wit.ai to help with all the voice control magic.

--

--

Timi Ajiboye
chunks of code*

I make stuff, mostly things that work on computers. Building Gandalf.