#MAKE
06/14/14
A very easy project which is also very cool
This project was created accidentally by doing some tests with RGB LEDs and and TLC5940s, between various combinations and strange color effects tests, we had the idea to connect the audio jack to the microcontroller to try to synchronize the music with colors. The result immediately seemed great, even without filtering or amplifying the audio signal, and we were surprised by how this project was so easy to make and at the same time very beautiful and interesting.
Finally we could publish this tutorial for all the people who in the last two years, after watching our videos on YouTube, have asked us how this object works and how to make it.
The way our ThunderVUmeter works is extremely simple: the microcontroller reads the analog values of the two audio channels and turns on a number of LEDs in proportion to the measured value.
Actually, in order to beautify it, we also added a color management that complicates a little program, in fact, using the library leOS2 of Leonardo Miliani we added a function that runs in parallel to update the color values of the LEDs.
As already mentioned, the hardware is very simple, the only complication is that there are many components to put together.
So, let's see what are the parts we used: an ATtiny84; three TLC5940; 64 RGB LEDs common anode; a medium size capacitor to stabilize the voltage which, in our case, comes from an old ATX power supply and that has a little ripple; and five resistors, referring to the diagram below, R1 and R2 are 10k, and R3, R4 and R5 are 1.5k.
Looking at the circuit we see that the audio jack (JP1) is connected in order to have a common ground with the rest of the circuit and the two channels are connected to the first two analog inputs.
To control the TLC5940 from ous small ATtiny84 we only need 3 signals, 2 of them are in common to all TLCs while one, the SIN, enter the first TLC which processes it and then sends it to the next TLC, the SOUT.
The last important thing to notice is that the resistors R3, R4 and R5 are used to set the maximum current that the TLC5940 will allow to flow on its outputs, for more information about that see the datasheet.
So, let's describe the part of the code used to handle as mentioned earlier. First of all we need to have the library leOS2 of Leonardo Miliani (not the leOS because in the ATtiny there isn't the TIMER 2) and the library which allows us to control TLC5940s with ATtiny84 and ATtiny85. This library was originally created by the user of the forum Arduino "Fungus" and modified by us to use it with ATtiny84 and this one can be downloaded from here.
Let us now examine some of the key points of the code, starting from the function to send data to the TLC5940 "tlc5940.update()", which we have already explained in the project HeartThrob, and which has the peculiarity that lasts about a millisecond and that only during this period the LEDs are turned on.
Another thing to notice in the code is the code used to do the auto-scale function according to the volume of the music. This process works in a very simple and intuitive: if the read value is higher than the full scale, it increases the full scale value; if, instead, the values read do not come close to the full scale for a long time, in our case two seconds, then the full scale value is reduced.
#include <Arduino.h> #include <Tiny_TLC5940.h> #include <leOS2.h> leOS2 OS; #define MIN 20 //Minimum value to autoscale #define K 1365 #define K2 819 #define T 3 unsigned long time=0; byte ds=0; unsigned int red=0, green=0, blue=4095, x=MIN; unsigned int c[8][3]={0}; byte s=0; void setup(){ tlc5940.init(); //Initialize TLC5940s tlc5940.clear(); tlc5940.update(); for(byte er=0;er<8;er++) //Set initial color values colors(); OS.begin(); OS.addTask(colors, T, SCHEDULED_IMMEDIATESTART); //Update color values every T*16 milliseconds x=MIN; time=0; } void loop(){ if(millis()-time>2000){ //Auto-scale for lower values function x=(x-x/20<=MIN)?MIN:x-x/20; time=millis()-1700; } byte right = read(1); //Read values byte left = read(0); tlc5940.clear(); //Clear old values byte er=8-right; for(byte re=8-right;re<8;re++){ //Set the new values for right channel tlc5940.set(re*3, c[er][2]); tlc5940.set(re*3+1,c[er][0]); tlc5940.set(re*3+2,c[er][1]); er++; } er=7; for(byte re=8;re<8+left;re++){ //Set the new values for left channel tlc5940.set(re*3, c[er][2]); tlc5940.set(re*3+1,c[er][0]); tlc5940.set(re*3+2,c[er][1]); er--; } tlc5940.update(); //Send data to TLC5940 } byte read(boolean channel){ unsigned int a=analogRead(channel);//Read the value of a channel while(a>x+x/9){ //Auto-scale for higher values function x+=x/18; time=millis(); } a=a>x?x:a; return map(a,0,x,0,8); //Calculate how many LEDs to turn on and return that value } void colors(){ //Update color values for(byte er=0;er<7;er++){ c[er][0]=c[er+1][0]; c[er][1]=c[er+1][1]; c[er][2]=c[er+1][2]; } switch(ds){ case 0: if(red==4095)ds=(ds+1)%6; else red+=K2; break; case 1: if(blue==0)ds=(ds+1)%6; else blue-=K2; break; case 2: if(green==4095)ds=(ds+1)%6; else green+=K2; break; case 3: if(red==0)ds=(ds+1)%6; else red-=K2; break; case 4: if(blue==4095)ds=(ds+1)%6; else blue+=K; break; case 5: if(green==0)ds=(ds+1)%6; else green-=K; break; } c[7][0]=red; c[7][1]=green; c[7][2]=blue; }
These are some videos of the project described in this page and also some tests done earlier (in reverse chronological order):
At the moment we don't have an office,
we are often between Padua and Vicenza.
If you need to meet us, contact us
and we will organize it.
We usually reply quickly, if you don't
get any answer just resend the email
or try another method.
Info@VicenzaThunders.com
Attention: if you need to call us,
we suggest you to send us an email or an
SMS first because we aren't always available.
You can also use Whatsapp if you want.
+393484808073
+393494548359
You can find us on many social networks,
when we have free time we like to share
our works and experiences!