THE CHRISTMAS MACHINE
By: Christopher Wm
Tags: Raspberry Pi, Python, Automation, Christmas, Makers

MIDI

If you’re not familiar with MIDI, it stands for “Musical Instrument Digital Interface.” It’s a pretty straightforward system of sending data between compatible systems. For example, it lets you hook keyboards (music keyboards, not PC keyboards) up to synthesizers and control them. In its simplest form, it does so by sending encoded messages over a serial connection with timestamp, musical note information, and “note on/ note off” data. So if you put your finger on a middle-C note on a keyboard, your synthesizer will know to play a middle-C. And when you take your finger off that note, your synth will know to stop playing.

Monitor showing real-time MIDI data, captured in MIDI-OX

While MIDI is technically intended for music and not hardware control, it’s not hard to see that it has everything you might want for hardware control. By mapping notes to devices you’d like binary (on/off) control over, MIDI gives you a simple, low latency control protocol that can be quickly adapted to control lights.

Now, astute readers might be thinking that DMX is better suited for this, as DMX is a similar standard used specifically for lighting. Well, if you’ve noticed that, you’re not wrong. It’d probably be really easy to do this using DMX. I don’t know anything about DMX though, and I know and absolute shit ton about MIDI, so here we are. More importantly, my goal 12 years ago was to be able to sequence lights in time with WAV/MP3 audio, and using MIDI seemed like the most intuitive way to do that with software I already had. For this build of THE CHRISTMAS MACHINE, I’ve been using a music production software suite called Reason to sequence lights, and it looks something like this when I do so:

Light sequencing in Reason

In this image, you can see how I sequence the lights: each ‘note’ corresponds to a GPIO pin on the Raspberry Pi. There’s a WAV file of “Jingle Bells” in the top lane, and I basically just draw blocks in time to align with changes in the song. It’s a little bit tedious, but it’s better than coding time delays by hand in python. Also it’s an interface that I’m pretty comfortable with, so I could just have a few beers and get at it.

When I initially imagined using MIDI 12 years ago, my plan was to do it over a wired MIDI connection, basically taking MIDI output from my laptop (using a USB to 5 pin MIDI interface) to a hacked serial connection on something like an Arduino. It can be done that way, but then you have even more cabling that you need.

RTP-MIDI to the rescue

So like I’ve mentioned, it’s been 12 years. A lot has changed since then. We recently bought a house that has a lot of exterior decorating area. Also, if I start any fires with shoddy AC wiring, that’s my problem. I decided to revisit this project.

One thing that’s really nice about picking a nerdy technology project up after over a decade is that a lot of bottlenecks and constraints sort of solve themselves with the passage of time. When I first put this approach together, I was assuming I’d need to run a hardwired serial connection to handle MIDI, knowing full well that MIDI-over-network (RTP-MIDI) was a better choice. Back then, it would not have been cost effective to receive MIDI over network, and would basically need a dedicated computer to receive the signals. When I decided to pick this project back up again, I figured I’d poke around to see if there was an RTP-MIDI implementation for Raspberry Pi. Much to my delight, there was: pymidi. Being a super straightforward RTP-MIDI server implementation in python written specifically for Raspberry Pi, pymidi was exactly what I was looking for. It’s got a sample event handler packaged into that, and with a bit of sketchy python and gpiozero for pin control, I was able to map incoming note on / note off messages to pin on / pin off control.

From there, I installed rtpMIDI, a virtual MIDI driver that allows you to pipe any MIDI output from any Windows software MIDI-out to anything on your network with low latency. pymidi sits on the Raspberry Pi listening for MIDI data, and rtpMIDI sits on a Windows computer to route MIDI data to pymidi. It’s a nice coupling.

rtpMIDI — pipes your light sequences right to your Raspberry Pi

Note: Macs support network MIDI out of the box, so you don’t need to install rtpMIDI if you’re a Mac user. I’ve been trying to find and test a linux-compatible solution too, because I’d like to be able to get an end-to-end free solution going.

Hardware

I get some real heebie-jeebies when I work with AC power because I am fully aware that I am not very bright and have no attention span. To this end, I will suggest that you do not do anything that I did nor assume that anything I did is safe or reasonable. Making mistakes with AC power can kill you and burn down your house. Shit, even if you do everything correctly you can still kill yourself with AC power.

I doubt anything I did is to code or even legal.

But since you’ve made it this far, I’ll point out that I found this pretty detailed writeup that I used as a starting point:

Basically, I started with a Raspberry Pi 3b, a couple 8-relay boards, a ton of wire, and a box of AC receptacles and wired up the hardware side of this.

The first half of my build, eight channels.

The one difference between my build and those in the writeup I linked to is that I used terminal blocks for most of the wire connections, which reduced the number of sketchy wire nut connections I had to use and arguably make this easier to expand. I bought a couple sets of these blocks and jumpers from Amazon and basically used them to create a ground bus, a neutral bus, and a “hot” bus, making the AC connections a bit easier to manage and distribute to the various individual contacts they needed to hit:

Shot of my neutral bus — the four connectors on the left go to the neutral connectors on four of the receptacles. The red one on the right goes to the neutral line on the AC cord. The black jumper on top connects them all together.

Putting it all together

So basically I run Reason off of my desktop computer along with rtpMIDI. My Raspberry Pi picks up the MIDI data over wifi and fires off the relays to turn the outlets on and off. I got this working yesterday to individually control eight receptacles and I’m currently finishing up the expansion that will bring it up to sixteen receptacles. The way I built it using the terminal block buses, expanding from eight to 16 is pretty much just attaching three AC wires to a second set of receptacles / buses and then wiring the low voltage DC for the new relays to pins on the Raspberry Pi.

Here’s a short video of the near-finished product, firing off relays to test the low voltage parts right before I plugged the AC in:

Here’s another short video of the relays firing outside with some lights in the sockets to test the AC switching. It works, much to my surprise:

After I get the expansion done (hopefully), I’m going to mount it to boards and put it in a weather-sealed tub.

For the next couple nights I’ll be hanging lights around the house and sequencing lights to sync with WAV/MP3 audio. Then I’m going to pipe the audio through an FM transmitter and become a neighborhood nuisance.

Feel free to ask any questions!