Have Yourself a Matrix LED Christmas

Making an interactive Christmas jumper

Tech the Halls!

What’s Involved?

  • Some sort of wearable display that can be attached to a jumper
  • A microcontroller to change the graphic on the display that can fit inside a jumper
  • A device to listen for Christmas songs
  • A music recognition service
  • A way to get the recognised song to the microcontroller
  • A battery

The Display

A basic representation of a pixel display
The individual RGB LEDs in the dress
Addressable RGB LED strip
Pockets in fabric ready for each LED strip
A 16 x 16 array of RGB LEDs

The Microcontroller

Adafruit_NeoPixel strip = Adafruit_NeoPixel(
NUM_LIGHTS,
PIN,
NEO_GRB + NEO_KHZ800 //NEO_GRB or NEO_GRBW
);
Showing the flexibility of the LED Array

Jingle Fails

Sending an image to the array

Oops, I soldered the LED strip together in a bizarre direction
// slice the array up into 16ths (chunkSize = 16)
(chunkSize) => {
for (var i = 0; i < arr.length; i += chunkSize)
chunked.push(arr.slice(i, i + chunkSize));
return chunked;
}
// reverse the order of every other line (arraySize = 16)
(arraySize) => {
for (var i = 0; i < arraySize; i++)
if (i % 2 == 0) {
chunked[i].reverse();
}
return chunked;
}
A santa hat and a candycane in snake mode mode, represented with CSS Grid

Recordin’ Around the MediaStream…

Listening for Christmas Music

function startRecording(recorder) {
recorder.ondataavailable = (e) => storeChunks(e, recorder.stream);
recorder.start();
window.setTimeout(() => {
recorder.stop();
startRecording(recorder);
}, 15 * 1000);
}
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(function(stream) {
const mediaRecorder = new window.MediaRecorder(stream);
startRecording(mediaRecorder);
})
.catch(function(err) {
console.log(`The following error occurred: ${err}`);
}
}

API Wish it Could be Christmas Everyday

Music recognition

Do They Node it’s Christmas?

Uploading the audio recordings

var request = require("request");var data = {
'url': url_from_blob_storage,
'return': 'timecode',
'api_token': your_api_token
};
request({
uri: 'https://api.audd.io/',
form: data,
method: 'POST'
}, function (err, res, body) {
console.log(body);
});

We’re makin’ a list, we’re checkin’ it twice

Mapping song titles to RGB value arrays

key_value_pair images[] {
{
"default",
{{255, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, ...
},
{
"tree",
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 255, 0}, ...
{
"santa",
{{0, 0, 0}, {185, 27, 24}, {185, 27, 24}, {185, 27, 24}, ...
},
...
const map = {
"jingle bell rock": "bell",
"let it snow! let it snow! let it snow!": "snow",
"rockin' around the christmas tree": "tree",
"santa claus is coming to town": "santa",
"deck the halls": "holly",
"we wish you a merry christmas": "pud",
...
};

Let it show, let it show, let it show!

  • The app can record music from its surroundings,
  • It can send that recording to azure and get a url back,
  • It can send that url to audD and get a song title back
  • It can look up the relevant image name to match the song title
  • It can put that image name on an endpoint
  • Which the arduino can do a get request on
  • The arduino can then look up which RGB values to display based on the icon name it receives and send them to the LEDs

And it can illuminate the jumper!

We wish you a Merry Christmas and an API New Year!

--

--

Lead Developer Advocate

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store