Earlier this year, we showcased our Raspberry Pi Future Home, a fully connected LEGO smart house model with LEDs, weather sensors, and a realtime control dashboard.
And now, we’ll show you exactly how to build one (and give you all the code you need as well!).
We promised that we’d dig deeper into the individual hardware and software components of the Raspberry Pi smart home model. The house was constructed out of LEGO, and runs on a Raspberry Pi Model B+. It includes LEDs, temperature and humidity sensors, and a remote controlled door.
First, we’ll focus on the temperature and humidity sensors. We’ll walk through setting up the hardware, hooking it up with PubNub, and viewing the readings in realtime from our web UI. Then, we’ll show you how to remotely turn on and off the house LEDs, as well as control their brightness.
As always, our full project GitHub repository is available here.
Part One: Sensors and Web UI
Smart Home Concept
In our diagram, the house represents the Raspberry Pi house with the lights, sensors and door. Using PubNub, you can power bidirectional communication between the devices at home and your mobile/browser:
- Read the sensor values such as temperature and humidity on a realtime web UI.
(SENSOR/LIGHT —-> BROWSER/MOBILE DEVICE)
- Monitor the same devices, and send control messages to them, to turn them on/off, to check their state and to take any action on them.
(BROWSER/MOBILE DEVICE —-> SENSOR/LIGHT)
This information is sent from one device to the other, without having to open any ports on the devices, through firewalls and irrespective of the network they are on. PubNub is the key communication component between all the things in the Internet of Things, and in this case, our Pi house.
Hardware: Sensor 101
The DHT22 is a basic, low-cost digital temperature and humidity sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and spits out a digital signal on the data pin.
- The DHT22 sensor:
- 3 jumper wires
- Breadboard
- 4.7kΩ (or 10kΩ) resistor 5.Raspberry Pi B+ loaded with the Raspbian OS.
Set up the circuit according to the following figure:
which translates to:
Connect to the GPIO4 (pin7), pin 1 for the voltage (3v3) and pin 6 for ground. The resistor goes between the first two pins of the sensor. The third pin of the sensor doesn’t need to be connected to anything.
How do you read values from it?
We need to use Adafruit’s DHT library to be able to read the temperature values from the sensor.
Open LXTerminal, and download and install the followings:
Install Python:
pi@raspberrypi ~$ sudo apt-get install python-dev
Install pip:
pi@raspberrypi ~$ sudo apt-get install python-pip
Downloading the Adafruit DHT library:
pi@raspberrypi ~$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
pi@raspberrypi ~$ cd Adafruit_Python_DHT
Installing the library
pi@raspberrypi ~$ sudo python setup.py install
This should compile the code for the library and install it on your device so any Python program can access the Adafruit_DHT python module.
Software: PubNub 101
What is PubNub doing here?
The Raspberry Pi smart home is all about IoT, and IoT is all about the devices communicating with each other in realtime. PubNub powers that communication between devices. Whether it’s a mobile device or a web browser talking to embedded devices, sensors or any other device, PubNub glues them together.
In this specific example, we’ll use a web browser to communicate with the sensors and the Raspberry Pi, to collect and receive temperature and humidity values. The sensor measures them, and sends it back over PubNub, allowing you to visualize it on your browser in realtime.
Hardware Code Walkthrough
Step 1: Reading the sensor values
The code snippet below makes the Pi read the humidity and temperature values from the sensor and print it out.
h,t = dht.read_retry(dht.DHT22, 4) print 'Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(t, h)
At this point, our sensor is collecting temperature and humidity data, but not doing anything with it. We want to stream this data to a web browser and display it in realtime, reflecting changes as they happen.
Step 2: Installing PubNub
Install PubNub:
pi@raspberrypi ~$ sudo pip install pubnub
For an indepth tutorial on setting up PubNub with a Raspberry Pi, check out Raspberry Pi 101. Also, to get your unique publish/subscribe keys, you’ll first need to sign up for a PubNub account. Once you sign up, you can get your unique PubNub keys in the PubNub Developer Dashboard. Our free Sandbox tier should give you all the bandwidth you need to build and test your app with the PubNub API.
Make sure you import the right libraries needed for this program. You initialize an instance of PubNub by inputting your publish/subscribe keys. Your channel is where you publish the message to, so choose a unique name for that.
import os import time import sys from Pubnub import Pubnub import Adafruit_DHT as dht pubnub = Pubnub(publish_key='demo', subscribe_key='demo') channel = 'pi-house'
PubNub Publish/Subscribe
In order to view these readings on your web UI, you will need to publish them on a specific channel using PubNub. The browser will subscribe to the same channel, and hence receive the message.
Here we are formatting the data to two decimal places, forming a message to be sent over PubNub, and finally publish the message.
temp='{0:0.1f}'.format(t)
hum='{0:0.1f}'.format(h)
message = {'temperature': temp, 'humidity': hum}
pubnub.publish(channel=channel, message=message, callback=callback, error=callback)
Data Visualization: Web UI
Our web UI is the control station for the Raspberry Pi smart home. This is where we see our temperature and humidity readings, can check the status of connected devices, and can control and trigger action, all in realtime.
If you are running the Python script on the Pi, you’ll notice the changing temperature and humidity values from the sensors. The UI updates as the data changes.
PubNub Console
If you don’t want to build the UI, worry not! The PubNub Developer Console and Debugger is another way to view messages from PubNub. If you do not have a web page displaying your data, you can still control and receive messages from the house with the console. It’s an easy debugger, where once you input your keys and channel name, the sensor readings will stream (as seen in the image below).
That’s all for Part One! We’ve built our temperature and humidity sensors, and we’re streaming data between the sensors and the web UI in realtime. All the code for this part of the project is available here.
Part Two: Remote Control
In Part Two, we’ll cover remote control of the LEDs, including turning them on and off, and adjusting their dimness and brightness.
In this part, we’ll show you how to control the LEDs remotely from our web UI, including customizing LED brightness, as well as emulate a fireplace by flickering the LED (using Raspberry Pi’s digital signal with pulse width modulation (PWM)).
As always, our full project GitHub repository is available here.
What is Pulse Width Modulation (PWM)?
Unlike Arduino’s analog pins, Raspberry Pi’s GPIO pins are all digital pins, which only send and receive high/low voltage. That means the power state is either 1 or 0, and nothing in between! You can turn on and off an LED (see my previous article, Internet of Things 101: Getting Started with Raspberry Pi), however, if you want the “in-between” value like 0.6 (i.e. dimming the light!) you need some tricks, either use an analog PWM output, or simulate it with software.
Pulse width modulation is a technique controlling power. You can get analog results using a digital signal, which forms square waveforms that a signal is oscillating between on and off.
On-again, Off-again Relationship with Duty Cycle
Let’s say, the digital signal pulses rapidly between 0V and 5V. When you turn the LED on for 100% of the time, it is at full brightness, while when you turn it on 50% and off 50%, the LED will appear half as bright.
The total amount of time a pulse is ‘on’ over the duration of the cycle is called duty cycle, and by changing the value, you can change the brightness of the LED.
What’s the Frequency?
The pulsing width (= time duration) of each oscillating cycle needs to be extremely fast so the human eye can’t perceive the changing of the light. This is how we create different dimness percentages. For example, if the signal is oscillating 60 times per second ( = 1000 ms / 60 sec), it gives us a cycle duration of 16.667 milliseconds.
Frequency is the number of occurrences of a repeating event per unit time, and the the unit of frequency is hertz (Hz). So in this scenario, the LED frequency is 60Hz, which is the frequency of typical American TV.
Controlling LED Brightness and Flickering
In this tutorial, we’ll use software PWM. This means we’ll use Python to control duty cycle and frequency, so you are not using any extra hardware pieces to achieve the effect of LED brightness.
Building the Circuit
Let’s wire up a few LEDs. Connect the power rail of Raspberry Pi to the anode (+) and the pin to the cathode (-) of each LED, with appropriate resistor (I am using 100 Ohm per LED).
In this example, I am using three LEDs, “living room”, “porch”, and “fireplace.”
Changing Brightness with Duty Cycle
You are going to set the duty cycle value programmatically to control the brightness of LEDs.
Software PWM is available in the RPi.GPIO Python library 0.5.6+, so if you are running older python lib, upgrade it before getting started.
Let’s create a file pwm-led.py on your Raspberry Pi.
Include the libraries and set up the GPIO pin for “living room light” LED at GPIO 4:
import RPi.GPIO as GPIO import sys GPIO.setmode(GPIO.BCM) PIN_LIVING = 4 GPIO.setup(PIN_LIVING, GPIO.OUT)
Then initialize the software PWM on the pin at the given rate of, let’s fix it for now at 100 Hz.
living = GPIO.PWM(PIN_LIVING, 100) living.start(0)
Finally, give a duty cycle value between 0% and 100% to adjust the brightness:
dc = 50 living.ChangeDutyCycle(dc)
Side, if you’re familiar with our Raspberry Pi article, Triggering Raspberry Pi Hue LEDs from Android UI, you may have noticed the colors of the RGB LED were controlled in the same method – by reducing or adding duty level of each light.
Changing Flicker Level with Frequency
If you’ve seen those flameless candles, the flame looks realistic because the light flickers. The flickering effect is generated by reducing the frequency of PWM, and this is how we create our LED fireplace in the Raspberry Pi smart house.
Let’s set up a “fireplace” LED:
PIN_FIREPLACE = 27 GPIO.setup(PIN_FIREPLACE, GPIO.OUT)
Then let’s give the pin with rate of 30 Hz frequency:
fire = GPIO.PWM(PIN_FIREPLACE, 30) fire.start(0)
This should give the LED a flickering effect. To make the code run properly, add this clean exit at the end.
try: while 1: pass except KeyboardInterrupt: GPIO.cleanup() sys.exit(1)
Execute the code from a terminal.
$ sudo python pwm-led.py
Check out how our fireplace (the red LED in the Vine) flickers!
Remote Control LEDs
A core component of any smart house is the ability to remote control devices in the house. In this case, we want to be able to control our LEDs from a remote web UI in realtime. This includes turning on and off the LEDs, as well as controlling the brightness. In this part, we’ll:
- Create a JavaScript web UI.
- Modify the Raspberry Pi code to take the values from the web UI to control LEDs in realtime.
Sending Data from the Web UI
In this tutorial, we’ve created a simple home automation web UI that lets you control and monitor the devices and sensors in the Raspberry Pi house. You can view the whole source code with CSS styles on GitHub repo.
We’ll create the sliders for our web UI that can be used to control the brightness of the LEDs. For more on the temperature and humidity portion of the web UI, check out Part One of this tutorial.
First, don’t forget to include pubnub.js in the body of index.html:
<script src="http://cdn.pubnub.com/pubnub-3.7.11.min.js"></script>
<input id="lightliving" type="range" min="0" max="100" step="1" value="0">
Then add some input
elements with the HTML5 range
attribute. The min
setting is set 0 (Duty Cycle 0%, also means “light off”) and the max
is set 100 (Duty Cycle 100%). This markup gives the slider UI.
You can limit the range in the any way you want to, for instance, 0 to 10, but don’t forget to adjust the value to fit in Duty Cycle percentage in your JavaScript file or in Python on Pi. In your JavaScript, first instantiate a new PubNub instance:
var pubnub = PUBNUB({ publish_key: 'demo', subscribe_key: 'demo' });
Then take the value from a user input, and send it to PubNub Stream. When a user moves the slider (= change
event is triggered by changing the value the HTML input), publish the value:
function publishUpdate(data) { pubnub.publish({ channel: 'pi-house', message: data }); } var lightLiving = document.getElementById('lightLiving'); lightLiving.addEventListener('change', function(e){ publishUpdate({item: 'light-living', brightness: + this.value}); }, false);
You can check if your data is successful sent on PubNub debug console.
Receiving Data to Pi to Control LED
Whenever the value is changed by a user, browser sends data like {brightness: 10}
via PubNub, then a python code to talk to Pi to receive the data and control the LED (in this case, changing its brightness). Let’s modify the pwm-led.py. Include and initialize PubNub:
from pubnub import Pubnub pubnub = Pubnub(publish_key='demo', subscribe_key='demo')
Then subscribe the data from the channel, ‘pi-house':
pubnub.subscribe(channels='pi-house', callback=_callback, error=_error)
Then at the success callback (_callback
), change the duty cycle to change the brightness of LED:
def _callback(m, channel): print(m) dc = m['brightness'] if m['item'] == 'light-living': living.ChangeDutyCycle(dc) def _error(m): print(m)
The source code is on GitHub, so you can take a look at the entire python code. Once you are ready, open the HTML file in a browser and change the brightness slider. If you did everything correctly, you should see the brightening and dimming LEDs in action! I keep the flickering level constant for this demo, but of course you can tweak it in any way you want to!
Wrapping Up
And that’s it! We’ve now constructed our Raspberry Pi smart house, complete with temperature and humidity monitoring, as well as realtime control over our LEDs (and we can even adjust their dimness!).
How you architect the house is entirely up to you, but LEGO is a great (and fun) way to build your structure.
Comments