Driving a Blinkt! as an IoT device (HPR Show 2173)

Dave Morriss


Table of Contents

Introduction

I managed to buy a Raspberry Pi Zero when they first came out in December 2015. This was not easy since they were very scarce. I also bought a first-generation case from Pimoroni and some 40-pin headers. With the Zero this header is not pre-installed and it’s necessary to solder it onto the Pi yourself.

I have had various project ideas for this Pi Zero, but had not decided on one until recently. Within the last month or two Pimoroni produced a device called the Blinkt! which has eight APA102 RGB LEDs and attaches to the GPIO header. This costs £5, just a little more than the Zero itself.

My plan was to combine the two and turn them into a status indicator for various things going on that needed my attention.

Making an LED Indicator

The plan was to mount the Zero inside something where the LEDs could be clearly seen and to label them in some way so that the significance of their signal could be easily determined.

I found a small but fairly deep picture frame in IKEA in their RIBBA range and decided to use that. The one I picked up has external dimensions 12.5cm by 17.4cm and is 3.4cm deep. The internal size is 10cm by 15cm. It has a silvered finish. There is a piece of glass in it and behind that is a piece of hardboard1 with fixtures for hanging the frame or standing it on a flat surface.

I wanted to mount the Zero behind the hardboard, drilling holes in it to allow the lights to shine through. The Zero in its case was to be held on with new longer nylon bolts. As mentioned, the case is the early Pimoroni model and as a consequence the nylon bolts are M2.5 20mm, not an easy size to find. The later cases use M3 bolts.

I made a design in Inkscape which would act as a template for drilling the holes and could be placed in the finished frame to label each of the lights. The original plan was to use the paper the design was printed on to act as a light diffuser, since the LEDs are quite bright, and to provide space for the legends.

Getting everything in just the right position in the template turned out to be quite difficult, but I learned much more about Inkscape than I knew before while I was doing it.

The Inkscape SVG file is included with this show in case you want to use it (be aware that it contains a hidden layer I used to line things up).

Pictures of the Pi Zero

Pi Zero with Blinkt!
Pi Zero in a case, with Blinkt!, LED 6 on

Side view of Pi Zero upside down with Blinkt!
Pi Zero with Blinkt! fixed to the hardboard

Pi Zero mounted to picture frame backing
Pi Zero with wireless dongle bolted to picture frame backing

Front of backing plate
Front of backing plate (with not very well aligned holes)

Pi Zero on backing plate in frame
Pi Zero on backing plate, with power cable, mounted in the RIBBA frame

Front view of finished frame
Front view of finished frame

Experimenting with the Blinkt!

As usual with products from Pimoroni there are lots of great hints and tips on how to use them. The Blinkt! is probably best driven from Python, and there is a library to make it easier, which can be installed from the Pimoroni site.

Within the repository on GitHub there are many example Python scripts, most of which I tried out. These are a great resource for developing your own code, especially if (like me) you’re not experienced with Python.

A note about Pi security

I have never been happy about leaving my Raspberry Pi’s with the default “pi” username and “raspberry” password. Quite a few tools assume that you have done this. Also, it’s assumed that the pi account is enabled to run sudo without a password.

I normally disable the pi account and/or change its password. I also remove it from the /etc/sudoers (use visudo to do this).

I normally create a dave account with a complex password (generated with KeePassX), and give it sudo access, with a password.

When using the Blinkt! it is assumed that every script accessing the GPIO needs to run as root. The Blinkt! is attached to the GPIO of course. The GPIO device driver uses file system files under the directory /sys/class/gpio/ and these are owned by user root and group gpio.

I searched for ways in which I could access the GPIO without prefixing every command with sudo (and typing the password). I didn’t find a clear answer, but I had dealt with a similar situation when making one of my Pi’s a printer and scanner driver, so I tried giving my account dave membership of the gpio group:

sudo usermod -G gpio dave

This was the answer, and after that the need to use sudo had disappeared.

I would much prefer that this was standard practice and was well documented. Learning how to use the Raspberry Pi should also include learning some basic security practices I believe.

Note that user pi also has gpio group membership:

$ id pi | fold
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),
29(audio),44(video),46(plugdev),60(games),100(users),101(input),108(netdev),999(
spi),998(i2c),997(gpio)

I used the “fold” command (pre-installed in Raspbian) to wrap the long line to its default width of 80 characters in this example. I did this for these notes.

Communicating with the Pi Zero

So, knowing that I could control the Blinkt! with scripts on the Pi Zero, I next wanted to come up with a way to control it remotely. I was reluctant to design a communications infrastructure, write my own listener and make it accept remote commands, so I looked for alternatives.

My first point of reference was a queuing system called ZeroMQ which I had heard about from various places, and recently on the Changelog podcast. As I looked into this it seemed like overkill for this project.

I next looked at MQTT which is much more lightweight. I remembered I had been to a talk on this at OggCamp 2012 given by Andy Piper, and recalled mention of a system called Mosquitto in relation to this. This protocol (amongst others?) is being used in The Internet of Things apparently.

I soon found that I could install the mosquitto server and clients on the Pi Zero with very little trouble:

sudo apt-get install mosquitto mosquitto-clients

This gave me the Mosquitto server and some clients. The server was set up to run at boot time without any intervention on my part, and can be controlled as root with the service command. The clients consist of the commands mosquitto_sub and mosquitto_pub.

What MQTT does

The design of MQTT is based around a publish/subscribe or “pub/sub” model. This requires a message broker whose job is to pass messages from publisher to subscriber. It knows which messages to send where by filtering them based on an attribute called the topic.

A publisher might be a temperature sensor or a doorbell sending a message in response to an event, and a subscriber might be a heating system, or an audio or visual alert system receiving the message and performing an action. Thus the temperature sensor controls the room temperature and the doorbell makes a sound or flashes a light.

The Mosquitto broker is the server mentioned earlier, and the commands mosquitto_pub and mosquitto_sub are examples of a publisher and a subscriber interface.

A Python library paho-mqtt exists to allow scripts to be written to interface with this system. This can be installed thus:

sudo pip install paho-mqtt

Pimoroni provide an example script in their blinkt repository called mqtt.py which demonstrates the use of this library.

My first version listener script

I slightly modified the mqtt.py script from Pimoroni to do what I wanted.

I renamed it blinkt_client.py and modified it to connect to localhost where the Mosquitto broker is running. It is an MQTT subscriber so it needs to spend its time listening for messages. I left the topic as pimoroni/blinkt and used the standard port 1883.

The script is most simply run in the background, so I added a crontab entry which starts it up when the Pi is rebooted:

@reboot $HOME/blinkt_client.py&

This script uses the original Pimoroni design and expects messages of two forms (text extracted from mqtt.py):

rgb,<pixel>,<r>,<g>,<b> - Set a single pixel to an RGB colour. Example: rgb,1,255,0,255
clr - Clear Blinkt!

If the pixel value is ‘*’ then all pixels are set to the chosen RGB value.

My first publisher

For the first publisher using this system I imported a pair of scripts I had been running on my desktop machine to help with the moderation of comments on the HPR website. This pair consists of a Bash script which is run every 15 minutes from cron, called cronjob_comments. It runs a Perl script called scrape_comments which scrapes a page on the HPR website to detect if there are any new comments which require attention2. If the Perl script finds anything it tells the Bash script, which uses the following command:

mosquitto_pub -t pimoroni/blinkt -m "rgb,$LED,255,255,0"

This sends a message to the MQTT broker on the same machine with the pimoroni/blinkt topic. The message payload causes the pixel identified by $LED to turn on with a sort of yellowish colour (RGB #FFFF00).

If there is no work to do then the equivalent command is:

mosquitto_pub -t pimoroni/blinkt -m "rgb,$LED,0,0,0"

This turns the pixel off.

The next version listener script

At the time of recording I have not completed this. I want the next version to offer a similar interface but I’d also like to be able to blink an LED and change colour briefly and revert to the previous colour. Once I have finished this I might do another HPR show about it.

Other ways I’m using the notification system

Aside from the local web scraper plus notification already described I have a few other functions running and more planned.

New HPR shows

I have a web scraper running on my main desktop system, which I described in HPR show # 1971 about my BlinkStick. This lights the BlinkStick red when new shows have been sent in to HPR and alerts me to process the show notes. When the processing is done the checking script (which runs every 30 minutes) notices and clears the light.

I added the Blinkt! display to this script. I installed Mosquitto on the desktop and use the mosquitto_pub command to tell the Zero to make LED 0 red, and turn it off at the same time as the BlinkStick. I will probably stop using the BlinkStick for this task in due course.

Mail notification

I use Thunderbird to handle my mail on my desktop machine. I have several POP and IMAP mail accounts and use a large number of filters to move incoming mail into folders (or the SPAM bucket). I use a Thunderbird add-on called Mailbox Alert to alert me to mail that needs particular attention. This tool can perform various actions when mail arrives in a folder. I use a range of sounds from Freesound.org (many of which I have edited) for several folders.

The Mailbox Alert tool can also run a script. I have written a very simple one which uses mosquitto_pub to make LED 6 green. At the moment this only happens when I get email from my son.

Turning off the mail alert LED is a problem. I want to be able to do this when the message that turned it on has been read. I have written a Perl script which can scan a mail folder (which is a file in mbox format) for unread messages, and I am experimenting with running this from cron. It’s not a lightweight process, so I don’t want to run it too frequently. This is very much a work in progress.

Planned IRC notifier

I use weechat with IRC. This program has a powerful plugin capability. I am looking at the possibility of writing a plugin which will alert me to an IRC message by turning on an LED on the Blinkt!. This is just an idea at the moment.

Using MQTT with the BlinkStick

As I have said I installed Mosquitto on my workstation. I wrote another listener (based on an example on the BlinkStick website) which registers with the local message broker and drives the BlinkStick. I am using this as a development platform for my experiments in Python scripting. It required some work to bring up to date since it was written in 2013.

I am using this set-up in conjunction with the Pi Zero. Every 30 minutes the Zero runs a script under the control of cron which calls mosquitto_pub and tells the BlinkStick listener to flash the LED. This was because the Zero had been disappearing from the home WiFi network and I wanted reassurance that it was still alive!

Conclusion

I have very little interest in the Internet of Things when it requires access to a remote server to turn my lights on. However, I’m excited about the possibilities when I have full control over all of the components. I have found that MQTT in the shape of Mosquitto is simple to set up and use and has great potential for building communicating systems.

I have to admit that it’s slightly eerie if I have to get up in the night and I see the “New HPR comments” LED glowing brightly in the dark! It’s also quite cool though.

The various bits of code demonstrated here are not yet available on a Git repository. It is planned to release them at some point in the future.

Around the time I started messing with this project Jezra was also building an MQTT project. He is a much more experienced Python programmer than I am so checking out his blog might be worth your while.


  1. Apparently what is known as hardboard in the UK is called high-density fiberboard in the USA.

  2. I collect information about the comment status from the stats page