Symphony Hack Lab — How to Make Light Cubes
We’re really excited to be involved in a fun collaboration with the National Arts Centre Orchestra, the Canada Science and Technology Museum, Artengine and Maker Faire Ottawa to present “Symphony Hack Lab”, a concert taking place on Feb 3 & 5, 2018. This will be a chance to experience the symphony “with audacious new explorations of sound and symphonic classics through science and technology”. There will be a number of pieces that will be reimagined by exploring our other senses and with new instruments and playing techniques. pHacktory will be co-hosting the concert and we will be experimenting with the piece Les offrandes oubliées by Olivier Messiaen.
This piece is of particular interest because Messiaen was known to have synaesthesia — he perceived specific colours when he heard musical chords. In fact, he used this phenomenon to aid his compositional process. During the development process, this point seemed like a nice opportunity to create a simple project to convert sound into light. We will be demonstrating a light installation during the performance of Les offrandes oubliées in which different sound frequencies will be converted into light. Below, we detail the process of making this installation and provide the code so that you can even make it yourself! A full parts list is available at the end of this post including links to any relevant parts that need to be 3d printed. Finally, the control code is available on our GitHub.
The instructions below require a beginner to intermediate level of skill in basic electronics, microcontrollers (ie. Arduino and Teensy) and coding. To build this yourself, you should already be comfortable coding in the Arduino IDE, working with WS2812b LEDs (aka neopixels) and following best practices when it comes to working with electronics and live power. Keep in mind that the LEDs used in this project are extremely bright and proper eye-safety precautions should be taken. Instructions are provided as-is, without warranty and the user is responsible for ensuring their own safety. When in doubt, ask an expert! If you have not worked on a project like this before, we strongly recommend visiting your local makerspace to find a community of people who will be able to help.
The Guts — Electronics
The first step in converting sound into light is to break down a sound source into frequency bands. There are a lot of ways to do this! But since we had a tight timeline we decided to accomplish this by using an MSGEQ7 chip which takes any incoming audio source and breaks it down into seven frequency bands centred at 63Hz, 160Hz, 400Hz, 1kHz, 2.5kHz, 6.25kHz and 16kHz. This will allow us to visualize sound in the bass, mids and treble parts of the sound spectrum. We used a MSGEQ7 module from DF Robot to make it easy to send the data to a microcontroller (tutorial here). The module spits out the amplitude (or volume) of sound in each of the frequency bands. This data is then sent to a Teensy 3.6 microcontroller which is used to control the lighting. In this case we decided to assign the sound frequencies (from high to low) to seven different colours of light (red, orange, yellow, green, blue, violet and indigo). In order to visualize the sound, the brightness of each colour was mapped according to the volume of a specific frequency band.
To control the mapping, a Teensy 3.6 microcontroller was chosen instead of an Arduino because it is able to control thousands of LEDs at high speed. The Teensy was mounted on an nice accessory (the Octo2811 Adapater) which makes it easy to wire up to eight different sets of lights (Note: The Teensy 3.6 requires extra long headers to be installed in order to mount to the Octo2811 adapter). The Octo adapter also has several pins broken out which make for easy connections to the MSGEQ7 (We use Pin 0, 1 & 23 — see wiring diagram below).
Importantly, the Octo adapter uses CAT5/6 wiring to send data and ground signals to the LEDs (instructions). We connected the wiring from the CAT cable to seven 3.5mm audio jacks in order to send lighting data and grounds to each of the seven LED panels. Finally, a few control momentary buttons were used to switch between different lighting modes (Off, Test, Ambient, Spectrum). The GND pins on each button were connected to each other and ground while the signal pins were wired to Pin 17, 18, 19 & 22 on the Octo adapter. These different modes will be discussed in more detail below. All the electronics were mounted inside of a box and wired up according to the diagram below making sure to connect all grounds together as well as grounding the box). Power to the electronics is supplied at 5VDC/2A.
The create the coloured lights, we used the popular WS2812b LEDs. These are nice LEDs as each one is individually addressable, any colour is assignable and the light quality is intense and rich. Adafruit has published a very nice tutorial for working with these LEDs if you are new to them. WS2812b LED strips (144 LEDs/m) were used to construct the panels. Seven light panels with 204 LEDs were created. Each panel consists of the LEDs mounted on a steel backing (12 rows with 17 LEDs each) and a 3D printed frame. We had lots of extra heat sinks lying around so several were attached to the back of the panels with Gorilla glue to help keep them cool during operation. Each panel also had 75cm of wire connected to a power jack (5VDC/5A) and an audio jack (data and ground). Again we were careful to connect all the grounds together. The power line contains a 1000uF/25V capacitor to suppress voltage spikes and a 300ohm resistor was soldered in-line on the data pin of the audio jack. We used 3m long audio cables with 3.5mm male jacks to send data and grounds between the control box and each cube (see wiring diagram above).
The Cubes — Structure and Design
Each LED panel now needs to be installed in some sort of structure which will “glow” with the assigned colour. For this element we worked with our friends at Ecotonos Design and Manufacturing to create the light cubes. Anthony Dewar (co-founder) came up with a very lightweight and simple design in which eight steel rods were welded to create and internal frame over which a dacron fabric could be stretched. The back is left open to allow for wiring, air flow and natural cooling. The ends of the steel rods were capped with a 3d printed piece which ensured all the edges of the cube would be rounded when the fabric was pulled tight. The final cube size is about 75cm on all sides.
The final product is extremely light and easy to move around. As well, without the cloth covering, the frames all sit inside one another which enables easy storage and shipping. Finally, the 3d printed LED panel frames were designed with four small notches so that they could be easily clipped into the steel rods in order to enable easy mounting.
The Code — How it all works
The control code for this installation was written in the Arduino IDE and can be found on our GitHub. You can feel free to download, modify and use it however you wish but please provide credit! We made use of several open source libraries and codes developed by others (full credits in the sketch) for working with the MSGEQ7, the LEDs and creating light patterns.
The Code has several important blocks which are worth discussing here.
- Libraries Used: Some libraries will need to be installed as they do not come with the IDE by default. These include the Bounce2 library and the Adafruit Neopixel library. We also created a library called “neopatterns.h” which is based on the tutorial for utilizing interrupts with neopixels. This library can be found on our Github along with our code for this project. You will need all three libraries for the code to work.
- User Input: There are several variables that the user can vary. These include: The number of frequency bands (NUM_BANDS) which also correspond to the number of light cubes; The number of LEDs on each light panel (NUM_LEDS); The default brightness of the panels (defaultBrightness); Any averaging of data (numReads); Baseline noise level (baseline); and any delay in the lighting updates (ie. slow down the update time by increasing the variable loop_dlay.
- Spectrum Mode: There are four modes available to operate the light cubes. Spectrum mode converts any incoming audio into a light display in real time by lighting up the cubes. This is the main mode of operation and is the default when the installation is turned on.
- Test Mode: This mode is for testing the light cubes and connections. It sequentially lights each cube for 750ms and then turns it off. The sequence starts with the lowest frequency cube and ends with the highest frequency cube. After this sequence, all cubes are lit up and fade through the colours of the rainbow. This is a tool for ensuring all cubes are connected and powered properly.
- Ambient Mode: In this mode, all LEDs are turned to blue and slowly fade in brightness values. Each cube fades at a different speed.
- Off: Turns everything off.
- 1x Teensy 3.6
- 1x OctoWS2811 Adapter
- 28x extra long headers
- 1x MSGEQ7 Module
- 10x WS2812b LED strip(144 LEDs/m)
- 1x Power rocker switch
- 8x 2.1mm DC plug
- 15x 3.5mm audio jacks
- 1x CAT cable (cut in half and stripped)
- 7x 3m audio cable with 3.5mm male ends
- 20m of 20 awg wire for power
- 7x 1000uF electrolytic capacitors
- 7x 300 ohm resistors
- 4x momentary panel mount buttons
- 1x enclosure (at least 7.5" L x 4.5" W x 2.5" H)
- 1x 5V/2A DC power supply (for control box)
- 7x 5V/5A DC power supply (for each cube)
- 3D printed parts (link to files coming soon)
- Basic electronic supplies and tools: wire strippers, snips, pliers, soldering iron, multimeter, heat gun, drill, screwdrivers, helping hands, 24 awg solid core wire, dupont jumper cables, solder, flux, heat shrink, etc.
This section will be updated soon with pictures from the final installation at the concert. Take a look at some video of the cubes being tested before the concert: