Introduction: LED Audio Visual Display
[ WARNING: FLASHING LIGHTS IN VIDEO ]
RGB LED matrices are a common project for hobbyists who want to experiment with light displays, but often are either expensive, or restrictive in their size and configuration. The aim of this project was to create a reconfigurable display that could work as its own stand alone piece or as an interactive display controlled by a console using an assortment of Joysticks and Buttons. The display could be arranged in a variety of layouts from a matrix formation to a more static decorative linear strip.
By attaching an assortment of Audio Sensors, Buttons and Joysticks the display could be switched between interactive and automatic modes, with configurable colours, effects, modes, speeds, brightness and patterns.
Users can switch between modes and configurations using the MODE and CONFIG buttons, using the Joystick and SELECT button to make their choices. The users current choice is shown on the 16x2 LCD screen at the center of the console.
This project involved a LED strip comprised of 250 LEDs but the code can be easily altered to allow for a strip of any size.
Modes
- Games: Games can be played using the led matrix as a screen
- Noise: LEDs light up according to environmental noise volume and frequency.
- Colour: LEDs used as a light displaying a predefined colour palette.
- Rain: Falling Rain Light Effects
Mode Configurations
- Colour - Sets color palette of strip
- Pride Flag - Rainbow
- Trans Flag - Blue, Pink, White
- Fire - Red, Orange, Yellow
- Light - White
- Style - Sets strip display effect
- Block - If in mode color, the colours of the LEDs remain constant, in mode noise, it causes all LEDs to be set the most recent noise colour value, creating a flashing effect.
- Shimmer - Alternate LEDs oscillate, fading between on and off.
- Track - If in mode colour, the colour scheme for the LEDs moves across the strip. In mode noise it causes the noise colours to travel across the strip as a moving wave.
- Rain Effect - How the rain patterns are generated
- Random - New rain stripes are randomly positioned, and the pattern varies.
- Constant - The rain pattern repeats.
- Game - Which game can you play on the matrix
- Snake - Viva la Nokia, only playable when the strip is in matrix configuration
- Effect Color - What source for color do the effects use?
- Color Set - Effects (e.g. rain) take a random colour from the set colour palette.
- Noise Freq - Effects when generated take the colour corresponding to the current noise freq.
- Noise Vol - Effects when generated take the colour corresponding to the current noise volume.
- Size - How is the display arranged?
- 250x1 Strip
- 50x5 Matrix
- 25x10 Matrix
Speed and Brightness
Controlled via turnable analog potentiometers, to change the brightness of the LEDs and the rate the display updates. This largely impacts the intensity of the light effects and difficulty of the games.
Strobe & LED Status
The consoles upper left Switch allows the LEDs to be turned off, as an option for when the display is being configured. The lower left Switch turns on the Strobe Effect, flashing the display at the set speed.
Step 1: Requirements
Components:
- BreadBoard ~ £5
- StripBoard ~ £10 for set 5
- Arduino Mega (any clone will do) ~ £20
- 2x 1M potentiometer resistors
- 300 RGB Individually Addressable Strip ~ £30
- Pin Headers ~ £5
- 10x 10K, 1x 300 Resistors
- I2C LCD Module ~ £5
- 4-Switch Joystick ~ £10
- Audio Sensor ~ £5
- 1x 1μF, 1x 10μF, 1x 100nF Capacitors
- 3x (Momentary) Buttons. Recommendations: Arcade, Mini ~ £3
- 2x Switches. Recommendations: Toggle ~ £5
- Power Jack
- Box ~ 20x20x15cm - Cardboard is easiest, but if you have access to a laser cutter, you do you.
My Joystick/Button recommendations were purely stylistic choices, after an arcade theme; momentary switches of any nature will do. Cheaper joysticks can be obtained that report their position via analog signals produced using 2 potentiometers (one for each axis). If you are prepared to alter the code, you can use thumb Joysticks like such.
While I used a minimal percentage of the Arduino Megas I/O pins, it was selected for it's larger dynamic and program memory size, for which the Arduino Uno proved insufficient.
LEDStrip Choice
The LEDstrip I used was a 300 RGB individually addressable WS2813 LED flexible strip. an upgraded version of WS2812, This format while a little more expensive, improves on the WS2812 with dual signal transmission which means if one LED stops working, the rest of the strip after it still functions. As such it has 4 pins: 5V, GND, DI (data input) and BI (backup input).
Total Cost: ~ £100
Equipment:
- Soldering Iron + Solder
- Multimeter (optional, but recommended)
- Wire cutters and strippers
- Wire: preferably single core, flexible (LOTS)
- Scalpel
- Ruler/Pencils
- 1x 5V Power Supply
- Manual screwdrivers
- Printer A to B USB Cable
Software:
- Arduino IDE
Skills:
- Soldering
- Some Arduino Experience all but absolutely necessary
Step 2: Schematic & Code
This project consisted of 2 Potentiometers, 1 Audio Sensor, 1 LED Strip, 3 Momentary Buttons, 1 Joystick (4 Momentary Buttons), 1 LCD Module and 2 Switches.
I recommend ensuring you understand the wiring and setting up the basic circuitry on a breadboard, before soldering the electronics to the stripboard in the next step for long term durability. You should at the very least be able to connect the various Arduino pins to default HIGH(5V)/LOW(GND) values and experiment with differing the original settings of the LEDStrip in the code (this is marked - see code step) to see some of the preliminary light effects.
Audio Circuit
The audio circuit is discussed in the next step and only necessary if you desire audio effects, else you can simply connect the AUDIO analog input pins A0, A1 to GND via a pull down resistor (~300 Ohm). This circuitry seeks to extract the measured sound's Frequency and Volume, giving two different input values to control the audio visualisations e.g. height(vol amplitude) and color(frequency).
LED Strip
I have attached the datasheet for the WS2813 strip, this features the ideal wiring. The BI pin can be pulled down through a resistor to the ground and a capacitor should be connected between the GND and +5V and placed close to the strip. This smooths sudden changes in the strip's current demand, for example if there is a sudden large increase when all the LEDs switch on, the capacitor using its stored charge can quicker supply this than the Arduino, reducing the strain on the boards components.
The strip is controlled using the FASTLED library (see code step for more detail) and connected to pin 5.
LCD Module
The LCD module I have recommended uses an internal circuit so that it only requires 2 input pins, this greatly reduces the complexity of soldering it into the circuit. It is connected to the SCL, SDA pins.
Potentiometers
Potentiometers are variable resistors, which allow you to control the voltage measured at the internal pin, the Arduino can read this as an analog value. I used these as an interactive way to manually control the speed and brightness of the display and they are connected to analog input pins: A3, A2.
External Power
For smaller projects ( < 20 LEDs) the Arduino can be powered via USB alone, but for this larger use case (250 LEDs), due to the large current demand an external +5V power source is required. I powered the Arduino through an external jack connected to the Arduino's GND and VIN. When powered only via USB, the colours of the LEDs will be warped and the LCD screen will not fully illuminate.
Buttons/Switches/Joystick
In neutral position, the buttons' INPUT pins are pulled down to GND and the Arduino reads digital LOW, but when pressed, the pins are connected to +5V reading digital HIGH. See here for a typical Arduino button example. These read values can be used as conditional boolean values for the program, causing the execution of different segments of code. The Buttons/Switches are connected to the following digital input pins: Mode/Config: 3/2. Joystick L/R/U/D: 10/11/13/12. Select: 9.
Attachments
Step 3: Audio Effects
The most complicated part of the circuitry was the Audio Voltage - Frequency Converter. I followed the schematic shown above ( See here for more info ). Some alteration of the capacitor, resistance values may be required depending on the strength of your audio signal. The example given, used an alternating 12V signal, I found good results by using 3.3V as the supply voltage, and feeding 5V into the audio sensor.
The two signals I extracted from this circuit were the frequency (VOUT) and volume (V2 +).
Helpful Notes
Larger Capacitors (threshold roughly around above 1µF, non-ceramic) are polarised, these include Electrolytic Capacitors, current flows in them from + to - side. On the diagram I've noted the direction they should be arranged.
The transistor used in this circuit is PNP, these transistors allow current to flow from the emitter to the collector when a negative polarity is applied to their base relative to the emitter.
Sadness #1
Originally I tried to feed the audio into the circuit using an audio jack, the dream being to connect the audio directly from my phone. Unfortunately the signal this produced appeared too weak, and after a week of struggling to get it to work, I resorted to using a sound sensor module. I am sure there are amplification techniques I could have used, and this is definitely the main issue with my project I would seek to correct in the future.
Step 4: Console Design & Creation
My console design was inspired by old school arcades, with retro Joystick, buttons and toggle switches. I constructed it using an old cardboard headphones box, (hoarding has its uses); this was highly effective as the box had a foam inner lining, so once turned inside out it produced a nice polished effect.
- Sketch the general layout of the console you want.
- Measure out and mark the positions of the different components on top of the box. Ensure you take the inner measurements of the buttons/switches/joysticks as you want the gaps just large enough to press the components through but still have their outer edges catch on the cardboard. I recommend using a scalpel to cut these holes, but sharp scissors in combination with screwdrivers for circular holes should do the trick. Cut slowly, attempting to fit the component through and gradually growing the holds in size, do one component at a time.
- For the larger components such as the joystick and LCD display, I recommend screwing some nuts/bolts through the console top to hold them securely in position.
- Cut three holes in bottom of the back of the console, these will be for the power input, USB input to optionally program the Arduino and LEDStrip output connector.
Top Tips
I recommend pre-soldering each of the component metal connectors before placing them in the console for ease of access and to reduce the risk of burning the cardboard.
Step 5: Solder Schematic
You'll need a piece of strip board at least 25 rows by 20 cols in size. However by picking one that's larger you'll be able to blue-tack your Micro-Controller onto the Stripboard next to the wires, this means the only non-stable connections will be those between the Stripboard and the components attached to the consoles surface. What is essential at every step of this process is where possible reducing the strain any wiring could be under to ensure a long lasting final product.
I used pin headers to cleanly organise the wires into groups and connect them to the Arduino in a way that can be easily detached for debugging.
I partially supported the Stripboard holding the heaviest circuitry by using some string/wire to connect it to the cardboard box's inner wall.
The main power and LEDStrip wires that exited the console had midwire connectors which could be detached, this meant the wires could be threaded through holes at the bottom of the console and still allow the box to open.
Soldering Tips
A clamp to hold the Wires/Stripboards while soldering will make the process much easier.
Always pre-solder each wire before trying to connect them.
Layout Tips
All outwires (going towards the Arduinos pins) are located at the edge of the board.
If possible using different coloured wire in nearby rows helps avoid wiring confusion.
GND, +3.3V, +5.5V should always be placed at the edge rows, for easy identification, placing GND and +3.3/5V at opposite edges helps prevent potential shorting but personally I didn't bother and placed them in the top 3 rows. The layout of the console can partly determine the ordering of the wire rows, nearby components map to nearby rows, the PIN numbers in the Arduino IDE can always be rewritten.
By soldering all +5V pins of the buttons/resistors together on the back of the console to each other in a daisy chain, only one +5V wire is needed between the Stripboard and the console top, massively reducing the number of vulnerable connecting wires. For example for the 4 switches of the joystick I connected all of their 5V terminals together.
Be generous in the length of wires that extend between the Stripboard and console, far easier to reduce later, than try to increase.
If possible use flexible wire between the Stripboard and console components, this makes it easier to open and debug the console later.
Step 6: Extension 1: LED Matrix
By connecting the LED Strip as is to the console, the majority of the rain, colour, strobe and noise effects can be displayed, but the visualisation form is limited. The code allows the display to be further configured into 250x1, 50x5, and 25x10 arrangements, this allows for matrix visualisations. Noise can be shown as moving waves, games can be played on the matrix like a low resolution screen. The choice of a 25 pixel individual strip length was a personal one, and you can choose this yourself and set it in the code. What I wanted above all was flexibility, so that whatever graphic effect I decided to code at a later date, I could assemble the HW into the required arrangement.
Sadness #2
I had a dream, and it was to use a conductive ink to paint circuit connections onto cardboard, which could be pressed against the adjoining ends of the LED strips.
Benefits:
- Looks super cool, and I could use pretty different coloured cardboard
- I get to draw circuits
- Ultimate customising, think of a new arrangement, just draw it.
Drawbacks:
- It didn't work.
- Not even a little bit.
- Why would you be able to draw by hand an accurate enough wiring and then apply a precise and consistent enough pressure to a compressable material such as cardboard?
I maintain had it worked it would have been really cool and I only partially regret the 2 hours allocated to this endeavour.
Actual Solution
I decided to use a system of pluggable male/female headers, similar to those used to connect the Stripboard wires to the Arduino. By placing M/F alternatively at each end, the individual strips can be optionally plugged into eachother recreating the original uncut strip. Or intermediate flexible wire connectors can be used so strips can be folded back on themselves to form a matrix, or any other spacial configuration.
- Cut the Led Strip into segments, I chose 10 strips of length 25, leaving 50 LEDs spare for another project
- Solder each of the copper connections at each end of the strip. Be careful not to melt the plastic, if you bought one with waterproof covering, you will have to cut a small top section away at each end.
- My LEDStrip had 4 connectors at each end, and 10 strips so I cut 10 male, 10 female headers segments each of length 4. For each strip I soldered male to one end and female to the other. Make sure the same ends are male/female for each strip, this will allow you to connect them in a daisy chain like fashion.
- Test the connections by plugging the 10 strips together, correct with more soldering if necessary.
- We now need the wire connectors, these will be used to connect the individual strips together into flexible arrangements, whether achieving distance from eachother or assembling a matrix is the goal. Their length will determine how far apart you can place each continuous section of LEDStrip; cut the wire a little longer than you want it as some length will be lost when connecting the wires. Cut another 10 male, 10 female header segments of length 4. Cut 40 pieces of wire (ideally multicoloured, flexible), strip each end and pre-solder.
- To create a wired connection, first take 4 wires (ideally different colours to enable identification of which wire connects to which pin) and solder them to a male header. You then want to braid these 4 wires, this keeps the wiring neat. Once braided (sufficient is the quality we're looking for here), you can solder the other ends to the female connector. Make sure the same wires are soldered to the same pins. If all your wire is the same colour, make markings or use a multi-meter to determine which wire is which, as after braiding it won't be clear. Repeat this process for each wired connection you need.
- Test the connections again, by connecting all the strips by the wired connections, play around with the console size setting and arrange the LEDStrips in different matrix formations. It is better to break and identify weak connections earlier rather than later.
You now have 10 individual strips, that can be directly plugged into eachother to recreate a long single strip, or rearranged into matrix formations.
Step 7: Configuration & Setup
The latest version can always be found on my github: rs6713/leddisplay/, feel free to fork it/download and play around.
Install Arduino IDE
In the miraculous event you somehow completed this tutorial with no prior Arduino Experience, the Arduino IDE can be downloaded here. Simply install and open the code in the IDE, plug the board via the printer cable into the computer. (You may have to install a driver for the computer to recognise the Arduino Board, but this should happen automatically the first time you plug an Arduino into your computer). Select the board type, and select the active COMM Port the Arduino is plugged into.
Configuration
To change the various settings of the display doesn't require sophisticated programming knowledge.
Areas in the program susceptible to configuration are marked with /*** CONFIGURE ME ***/
You can easily alter/configure the following areas of the program:
- The pins the components are connected to
- The size of the individual LEDStrips
- Total number of LEDs in the strips overall
- The modes you want to allow for the program
- The length of the raindrops for the rain effect.
The pins, and total number of LEDs are essential to get right to make the code work with your version of the electronic circuit discussed in the previous steps. It is also useful so that you can test different display modes by setting them during code initialisation rather than having to construct and connect all the joystick, mode and configuration buttons.
Upload
Once you've set the correct PIN numbers for the components, Strip size and number of LEDs, you can upload the program to the Arduino by pressing upload. Hopefully you've already done this by this point as a matter of course during testing. Plug in the external 5V power supply and you should be good to go.
Debugging
If the LEDStrip/Console are not functioning as expected there are a number of potential causes.
The LEDStrip is completely/partially off:
- Check the LEDStrip Switch is set to on,
- If you extended the strip, and the last several end segments of the LEDStrip do not illuminate, this is likely due to a faulty connection. Check your connections for dry joints and resolder, try switching the order of the strips, and if it is a wired connection, try switching one wired connection for another.
The LCD Screen brightness is low/ LEDStrip colours are wrong:
- Check the external power connection is on/properly connected. When power is low not all colours of the RGB LEDs consistently light up and the LCD screen struggles to illuminate itself.
- The colours can also be wrong if the size configuration e.g. 250x1 of the program does not reflect the real life LED arrangement.
- Worst case scenario you can change the program to reduce the number of strips illuminated.
Random Terribleness
As a last resort, commented out Serial.prints have been left throughout the code, uncommenting them will give you feedback on various component and inner program states.
A likely situation is that an input that should be grounded, has become disconnected and is left floating, this will create false event triggers (randomly oscillating pin reading between FALSE and TRUE) and unpredictable program behaviour.
Program Alterations
Further areas of possible alterations are marked with /** CHANGE ME **/
These areas are prime examples where you can add your own customisations:
- Add new colour palette options
- Add new effects e.g. shimmer
- Add new games
These are merely suggestions, feel free to change the code however you wish.
Step 8: Extension 2: OpenProcessing
** At the time of writing, this feature remains unimplemented, so this step is meant to highlight future plans/manifestations of this project and to highlight the significance of extending the LEDStrip to allow for matrix displays. **
One of the reasons I was so excited that extending the LEDStrip allowed it to be arranged as a matrix, was that having a screen display opens up many opportunities to map 2D visualisations from other software to the Arduino HW.
OpenProcessing is a community of 2D interactive graphics based on the Processing language. By using a simple Serial Print function, the appearance of each frame can be transmitted pixel by pixel to the Arduino. Therefore there can be a future mode for the console, where the Arduino just listens to the Serial connection and just updates the LED Matrix frame by frame according to the animation specified by the Processing program. This has many advantages in that Processing is a language specialised for the visual arts and is easy to learn, making it very quick to create complex art visualisations. It also moves the memory and processing complexity to your computer with the comparatively memory/processing power limited Arduino only having to handle the information passed over the Serial.
By outsourcing your LED Display visualisations to a pre-existing library of 2D Graphic Effects, the possibilities are endless. Check out the openprocessing.org catalogue for inspiration.