After Pi Switch, here comes Pi Dimmer, a level up the IoT Control ladder. We are going to build an LED dimmer with Raspberry Pi and Grandeur. The Raspberry Pi will control the led based on the data we send from our web app. We will use the Grandeur platform to help us communicate data between our app and our RPi over internet.
Why are we using Grandeur?IoT is the union of of the physical and the software world. It is about connecting pieces of hardware to the internet, which then enables us to control and monitor our things and systems with softwares. It opens a whole new spectrum by introducing automation in otherwise complex physical word. But with opportunity come unique challenges. In order to make the connectivity happen between the hardware and the software, we need solid and scalable backends. A backend works like a relay of information. So without it, you can't send data from the hardware to the apps or vice versa. Similarly, backend helps us in collecting and persisting data from the hardware world. This data can help us in building analytics. These insights can further help us better understand our systems.
Whereas our apps and hardware determines the end user experience, the backend is a commodity. But backend is extremely difficult to build. It takes both time and investment. That's one of the major reason why so many IoT startups fail. Grandeur solves this problem.
Grandeur is a backend as a service platform for IoT. So now it takes a single signup and then we can use the SDKs to add features into hardware and apps. For example, all it takes is a single function call from hardware to send data from hardware to apps and to persist it. Similarly, you can add authentication into apps with a single function call. This way, not only does this platform abstract away the backend complexities, but it also helps by making integration a lot more easier. Without this platform, we would either be building it all on our own or alternatively we would need to integrate several services together to build a backend that would solve all aspects of our IoT dev.
With Grandeur, it is like the dev process is on steroids.
Let's dive into the project.
Step1: Getting StartedFirst of all, we are required to setup the Raspberry Pi if it isn't already. For this purpose we will use the Pi Imager to install lite version of the Raspbian OS on an SD card. An official tutorial of this process can be find here (plus we also documented it in Pi Switch tutorial).
Since we want to run our program on Raspberry Pi, we need SSH access to Raspberry Pi (the lite version of Raspbian don't comes with a GUI — but that's the point: we don't need one). To enable SSH, first the Raspberry Pi should be accessible on our local network. To connect the Raspberry Pi to WIFI, just create wpa_supplicant.conf
file inside the SD card and add the following content to it:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=<Insert 2 letter ISO 3166-1 country code here>
network={
ssid="YOUR-WIFI-SSID"
psk="YOUR-WIFI-PASSWORD"
}
So now on boot, the Pi will automatically connect to the WiFi using the configurations that you provide in this file. (checkout the official tutorial for more info on connecting Pi to network).
Finally create an empty file named ssh
inside the SD card. This will enable the SSH on boot. After which you can use the terminal or command prompt of your computer (connected to same WIFI) to get access to the Raspberry Pi
ssh pi@raspberrypi.local
The default password of pi user is raspberry
.
Since we will be writing our device-side program in python, after sshing inside RPi from our desktop terminal, we need to install it using apt-get.
sudo apt-get update
sudo apt-get install python3 python3-env
Let's create a new project on Grandeur to begin integrating our Pi and web app together. Follow the following screencast for this:
Copy the API key of your project from the access page of the console. We will use it in our app and device programs. Then go to devices page and register a new device as shown below:
Copy this device Id and token somewhere too. We'll need this in our device program.
For the app side, we will create a new user:
and then we will pair the device that we registered earlier with this user. Without pairing the device, the device won't be able to get access to the project.
Now we are ready to write the code for hardware and build the app.
Step2: Hardware DesignThe hardware design for this project is very simple. We will hook an led to GPIO 12 and GND of Pi (don't forget to use a >300 ohm resistor because Pi can't source more than 16mA current). For reference, use the following pinout:
We are using GPIO 12 because it can alternatively map to PWM0. Pulse width modulation (PWM) is a technique that we use for controlling power output. To control the brightness of an LED we can vary the power sent to the LED from RPi, for example by using a potentiometer (variable resistor). The more power the LED receives, the brighter it shines, the lesser, the dimmer. Here we can use the PWM because Raspberry Pi is a microcontroller/computer which works on digital signals (which means they can only produce either a high state or low state, a 1 or a 0 on its pin). In PWM, we control the power output by oscillating the GPIO state at a fixed frequency.
So for example, if an led is connected to a GPIO and if, over a short duration of time, we turn the GPIO on for 50% and off for 50%, the LED will appear half as bright since the total light output over the time duration is only half as much as 100% on. Generally the frequency of this oscillation is really fast, or else the LED will appear blinking to an observer. The %age of duration for which we keep the GPIO on is called the width of pulse (also known as duty cycle). So for instance, if we are oscillating the GPIO at 1k frequency (1ms is the duration of one oscillation) in which it is staying on for 0.5ms and staying off for 0.5ms, then the duty cycle is 50% (0.5/1 * 100). Similarly, if the GPIO is staying on for 0.3ms and staying off for 0.7ms — the duty cycle is 30% (0.3 / 1 * 100).
We can vary the power output by controlling the duty cycle — more the duty cycle, more the power output, more the brightness (because the LED will stay on for proportionally longer duration, so it will appear to be brighter).
We will start with setting up a virtual environment for the code in Pi.
python3 -m venv "Pi Dimmer"
Then we will activate the virtual environment.
source Pi\ Dimmer/bin/active
We will use two packages here: the gpiozero
package will help us in controlling the GPIO of Pi. The other is the python SDK of Grandeur platform, which will help us connect to our project and get live stream of data from our app.
We can install the packages with pip
.
pip install grandeur gpiozero RPI.GPIO
(gpiozero
depends upon the additional RPI.GPIO
library).
We will create a new file and open it an editor to write the program.
touch hardware.py
nano hardware.py
Here's our python program code: 🤖
The overall logic of the code is fairly simple. We are starting with importing the PWM package form gpiozero
and device
package from grandeur. Using the PWM package, we will start the PWM on GPIO 12. We start the connection setup by calling grandeur.init
function with our API key and device token, that we copied before. Then will place event handler on the connection status of SDK. The handler method provided to project.onConnection
will be called when the RPi gets successful in establishing a secure connection with the backend.
Then we will obtain a reference to the device through project.device
by using the device Id that we copied earlier. Finally, we will place an event handler on the data of the device using device.onParms
. The handler provided to this function will be called every time the data of the device gets an update. This way we can control the led brightness through our app in realtime.
The while 1
loop prevents the program from exiting. You can write in here the code that you want to repeatedly execute — like reading a GPIO after every 5 seconds.
What this program does is when it's run, it starts establishing realtime communication channel with the backend. When the connection is fully established, it gets the device data from the backend for initializing RPi's LED pin with value of the state
variable (see handleParms
function). Calling onParms
makes it listen for any future updates in data of device. As soon as any such update occurs, the backend sends it to our RPi which updates the state of its LED pin (see handleParmsUpdate
function).
The real magic happens on the app side. First of all, we will use standard CSS and HTML to create the UI of the app. Then we will use the Javascript SDK of Grandeur to add features to our app like:
- We will use it to build authentication into our apps. A user can sign in to control the devices paired to his account.
- List the devices paired to the account of a user.
- Update the device data (which implies that we will control the hardware
state
).
The code of the app is as below (plus the entire code can be found from the repo linked in the code section of the project).
The JS file is the soul of this application. That's where we will init
the SDK using the API key and access credential. You can generate your access key and token as shown below:
Now we can run the app locally with Grandeur cli. It can be downloaded to your local computer and we can run a local server with it through grandeur serve
command (follow this for more detail). Grandeur naturally rejects all requests coming from unknown origins for security, therefore we need to add localhost:3000 to project's allowed origins list.
Then we run the hardware program and done 👏.
python hardware.py
This is how bombastic does it look like 💥.
So in this tutorial we created a Internet dimmer using Raspberry Pi. We built an app through which we sent data to our RPi and controlled the brightness of an LED attached to it through PWM technique. Now you can extend it in so many ways, like you can connect an H-bridge circuit to control the speed of a motor in realtime with the app and you can combine it with the power monitoring aspect (checkout the tutorial here). I hope it went well but if there is some kind of confusion, you can always reach me out.
Here's Grandeur's website, just in case you want to give them a shot. You can checkout their similar projects here. Do let me know about your feedback in comments.
Till next time.
Comments