Thursday 15 December 2022

Slack/Whatsapp controlled colour-changing and morse code Christmas lights

Several years ago I made some Christmas lights that could be controlled via Slack and WhatsApp, and every year since I find that I need to update the interface to these platforms to account for the changes that they make during the year. 

Usability updates

This year whilst I was doing that, I took the opportunity to add a few new features and simplify the interface.

Now it responds to some key words – all, top, bottom, half, alternate, led, and allows the user to specify certain colours by word and all colours by hex code.

Additionally I refined the serial interface to speed things up.

Moving to a single-board computer

 
For my home implementation of this, previously I would just run a USB extension lead from my desktop. 


I have now migrated the code to a PCDuino2 single board computer. This is a 1Ghz Allwinner A10 chip SBC, which also contains Arduino pin headers.


The board is discontinued (I bought this one from Maplin years ago during their closing down sale), and as a result there is little in the way of official repositories or archives for the Ubuntu variant distribution that it runs. Plus it looks like there’s some sketchiness around the official firmwares around the allwinner chip that powers it.


I found a version of Armbian linux for this platform and burnt it to a micro SD card.
This allowed me to get the PCDuino to boot to Armbian.


Unfortunately it looks like there is no real support for installing Armbian to the NAND storage which is on the PCDuino. However, leaving it on the micro SD has some advantages such as easily being able to image and back up the install.


Then it was simply a case of connecting it to the network and updating it, enabling SSHD for ease of maintenance going forward, and installing required tools for the Christmas lights server (JDK and Arduino).


As the PCDuino is not a typical Arduino development board it needs its own board definition to be used with the Arduino IDE, so for now I decided to continue using an externally connected Arduino.

 

Implementing morse code

 
One of the downsides to the set up the I currently have is that the serial data transmission can be disrupted by the update process transferring data from the Arduino to the lights.


The changes I have made reduce the amount of data that is transmitted via serial and so minimize the problem.


However there is additional functionality that I wish to add that will require further data to be transmitted – that is to have a set of lights which flash similarly to regular Christmas lights, but instead of a standard or random pattern, they blink out morse code, based on a message input from the control application.


Rather than cram more functionality into the WS2812 lights that I am currently using, I plan to leave them be and use a regular set of plain white fairy lights for this. Typically I have always decorated our Christmas trees with a multi colours set and a plain white set, so this fits with what I would typically do anyway.

The lights I used are powered from 3xAA batteries (4.5v), which can easily be substituted for USB and powered from a USB hub. To toggle their on and off state, I have used an optocoupler which will be toggled from the PCDuinos GPIO pins.


The ‘arduino-style’ pins of the PCDuino board can be reached in be linux file system via GPIO – similar to the way I toggled an output pin on the frequency switch project.


Seeing is this makes it quite easy to simply toggle a pin on and off, I should be able to use this for the morse code without having to depend on the rather outdated and no longer supported PCDuino board definitions.

Finding the pin reference

 
A ‘gotcha’ about using the sysfs GPIO interface is that the pin numbers as they may have silk screened on the board do not necessarily correlate to the pin numbers in the file system.


The first thing to do is figure out what the pin identifier would be. In this instance, I found some config files for the PCDuino on GitHub.


There lists the PCDuinos GPIO pins and there corresponding identifier, summarised below.

GPIO PinPin ID
0PI19
1PI18
2PH07
3PH06
4PH08
5PB02
6PI03
7PH09
8PH10
9PH05
10PI10
11PI12
12PI13
13PI11
14PH11
15PH12
16PH13
17PH14
18PH15
19PH16

I’d decided to use GPIO 8, so the relevant ID is H10

The Sunxi wiki demonstrates how to calculate the relevant GPIO number from that ID

(position of letter in alphabet - 1) * 32 + pin number

so with H10, H is the 8th letter so

(8-1)*32 + 10 = 234


So with that number calculated, we can export the pin with

echo 234 > /sys/class/gpio/export

which will make ‘gpio234’ available under /sys/class/gpio.

From there we can make it an output, and change the ownership so of it’s value file so that a regular user can write to it.

echo out > /sys/class/gpio/gpio234/direction

chown -R ant:ant /sys/class/gpio/gpio234/value


Then to switch the lights on,

echo 1 > /sys/class/gpio/gpio234/value

and

echo 0 > /sys/class/gpio/gpio234/value

to turn them off


A demo video is below, and as usual the source is available on GitHub.

Merry Christmas!