We use Arduino and bluetooth to wirelessly visualize music being played on PC. Arduino and its accessories are running from battery. In order to eliminate noise we analyze the music stream on PC and send frequency spectrum information to arduino via bluetooth.
Here is also some music playing in background and the box is open:
Comparison of Existing Solutions
There are few other arduino–based projects which visualize music in real time:
- Tiny Arduino Music Visualizer – compact standalone solution with microphone connected to arduino (no PC required). However it seems the device must be placed near speaker to avoid noise.
- Music Visualiser Table – based on the solution above
- Arduino Audio Spectrum Visualizer – audio input is provided to Arduino via 3.5mm jack
- This Is Your Brain On Music – audio is analyzed on PC, Arduino is connected to PC via USB cable.
|Project||Wireless?||PC backend needed?||Subject to noise?|
|Tiny Arduino Music Visualizer||Yes||Yes||Yes|
|Arduino Audio Spectrum Visualizer||No||No||No|
|This Is Your Brain On Music||No||Yes||No|
There is also plenty of non-arduino based cicuits to visualize music.
Aduino: Wiring and Software
Bill of Material
- Arduino (I use Uno)
- HC–06 Bluetooth Module
- Neopixel 8 Stick
- 1000uF+ capacitor
- 330 ohm resistor
- 3.7V Li–Pol battery
- Mini breadboard
I connect the 3.7V battery directly to Arduino UNO’s 5V input so that the whole circuit is running on 3.7V. LED stick and bluetooth module draw current directly from battery and not via Arduino board. When debugging and running the circuit from wall power instead of battery, you can connect the bluetooth and LED stick to draw current from Arduino unless you turn all the LED’s fully on. You can run the whole circuit on 5V or on 3.7V without any modifications.
The capacitor and resistor are there due to Adafruit recommendation. Be careful to properly connect the capacitor (polarity) and make sure bluetooth’s TX is connected to arduino’s RX and vice versa.
The Neopixel LED on schema below is actually Neopixel Ring 16 and not Neopixel 8 Stick as I was unable to find Neopixel 8 Stick schema for Fritzing.
Arduino source code
PC sends data and Arduino acts as receiver, there is no communication from Arduino to PC. Each message sent from PC to Arduino must obey this structure:
r1 is amount of red color to be mixed on led No.1 (from 0 to 255).
E.g., to turn led No.2 to purple colour (full blue, full red, no green) and turn all other leds off we send following string:
As you can see below, arduino source code is dedicated solely to turning leds on and off, there is no business logic related to music. This has the advantage that you can play with and adjust the led colours and visualization functions on your PC while the arduino is running (which is more comfortable than reprogramming the arduino each time you want to try new colours).
Load Souce Code To Arduino
I upload the source code to Arduino from Arduino IDE via USB. You need to power off (unplug) the bluetooth power pin to successfully upload the code to Arduino, because bluetooth module is connected to default Arduino’s TX and RX pins and will interfere with code upload procedure otherwise.
Pair Arduino’s Bluetooth Module with PC
Follow this tutorial to pair the devices.
Once done, you can use following simple ruby code to turn on a LED on your Arduino LED stick:
Now we are done with Arduino–side setup. We paired PC’s bluetooth with Arduino’s bluetooth. Next step is to launch the music analysis code on PC and periodically instruct arduino’s LED stick to alter the leds to visualize music.
We need GNU/Linux. Music frequency analysis code is based on this blogpost.
Download Processing, make sure you download version 2.2.*, because version 3.0 (beta) made some changes to API and will not work with the code below.
Install JRuby and Gems
We need JRuby (plain C-based Ruby will not work) because we will connect our ruby code to Processing which is written in Java.
- Install Java. I use OpenJDK (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.12.04.1)
- Install RVM (Ruby Version Manager).
- Install Jruby into RVM by
$ rvm install jruby. I use jruby v1.7.19.
- Make sure you use jruby by running
$ rvm use jruby(or set jruby as your default ruby implementation).
- Install ruby-processing gem
$ gem install ruby-processing
- Install rubyserial gem by running
$ gem install rubyserial
Get Familiar with Processing Ruby Code
Let us save the source code below into file named
Launch the Processing Code
First power on the Arduino circuit. Arduino’s bluetooth module should blink red. Once the Processing code will establish communication with arduino, bluetooth’s indicator LED should light steadily in red colour.
Run the processing code from shell:
$ rp5 run yaw.rb
Once started, following window with music visualization should appear:
and Neopixel LEDs on Arduino circuit should blink in the same manner.
yaw.rb Code Fails with RubySerial::Exception: ENOENT
This happens when Arduino’s bluetooth module is not properly bind to
/dev/rfcomm0 linux file device.
Make sure the device exists by running
ls -la /dev/rfcomm*. It may happen that the device name is
/dev/rfcomm1 instead of
yaw.rb fails with NameError: PApplet not found in packages processing.core; last error: cannot load Java class processing.core.PApplet
Check content of
~/.rp5rc file. The variable
PROCESSING_ROOT should point to the directory where Processing is kept, e.g.:
Music is Playing but Visualization Screen and LEDs are Dark
Open Pulse Audio Volume Control by running
$ pavucontrol. Click “Input Devices” tab on the bottom and select “Show: Monitors”. Make sure the input device is not muted (see icons on the right side).
Paper box consists of two parts (white top and blue bottom), here is SVG for blade cutter machine:
The Neopixel 8 Strip LED lights are diffused by a thin layer of transparent bubble foil.
To keep this tutorial as simple as possible we leave the bluetooth connection on default baud rate which is only 9600 bauds (
9600 bauds = 1200 bytes per second). Single LED status string usually occupies cca 60 bytes, but can grow up to 96 bytes when all LEDs are on (i.e. set to 255):
This string has 52 bytes:
This string has 96 bytes:
We send the LED status string every 50 miliseconds (i.e. 20 times per second).
60 bytes * 20 = 1200 bytes per second. If you experience the Arduino’s LED visualization is delayed against the actual visualization on PC, you may need to do one of the following:
- Downcrease the refresh rate in this line of code:
if(($t2 - $t1) > 0.05)
- Use only one colour channel
- Change the bluetooth’s module bandwidth to e.g. 57600 bauds
- Use some encoding/compression to downcrease size of the transmitted data
My multimeter tells that whole circuit draws cca
1000mA battery should last
1000/70 =~ 14 hours. Single Neopixel LED can draw up to 60mA when fully turned on (and there are eight of them), but usually most of the leds are dim for most of the time.