Raspberry Pi Smart House: Controlling Lights with PWM

6 min read Michael Carroll on Aug 4, 2015

Welcome to Part 2/2 of our tutorial on how to build a Raspberry Pi smart house, a fully connected LEGO smart house model with LEDs and temperature and humidity sensors, all controlled and monitored on a real-time web UI.

In Part One, we covered the basics, hooked up our temperature and humidity sensors, and streamed the data to our live-updating web UI. We recommend you start with that tutorial, then come back here when you’re finished those steps.

In this tutorial, 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.

how to build a smart house with raspberry pi

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.

LED PWM - Duty Cycle

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.

LED frequency

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.

Pi House LEDs

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.”

Pi LEDs circuit

LED cuircuit

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 on your Raspberry Pi.

Include the libraries and set up the GPIO pin for “living room light” LED at GPIO 4:

Then initialize the software PWM on the pin at the given rate of, let’s fix it for now at 100 Hz.

Finally, give a duty cycle value between 0% and 100% to adjust the brightness:

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:

Then let’s give the pin with rate of 30 Hz frequency:

This should give the LED a flickering effect. To make the code run properly, add this clean exit at the end.

Execute the code from a terminal.

$ sudo python

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 real time. This includes turning on and off the LEDs, as well as controlling the brightness. In this part, we’ll:

  1. Create a JavaScript web UI.
  2. Modify the Raspberry Pi code to take the values from the web UI to control LEDs in real time.

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. Web UI to control RPi 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:

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. HTML5 slider

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:

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:

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 Include and initialize PubNub:

Then subscribe the data from the channel, ‘pi-house’:

Then at the success callback (_callback), change the duty cycle to change the brightness of LED:


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 real-time 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.

When you build one yourself, send it over to us and we’ll feature it on the blog!