Go Down

Topic: Led stereo VU-meter (Read 190 times) previous topic - next topic

Plushy

Hi,
I've been working on a project to get a VU meter to work using the arduino (I know I can just buy an IC).
I have been working on the code for a while know. And I finally tought I had a working code until I fully tested it out. I myself don't see any problem with the code and why it doesn't work. So here is my question if any of you guys got an idea on what I did wrong with coding and how I can fix it?
The problem seems (what I think) is that the values of the input get read to fast in and displayed on the leds.
I hope you guys can help me out. :)
Code: [Select]
int led[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int led1[10] = {20, 22, 24, 26, 28, 30, 32, 34, 36, 38};
int leftChannel = A0; //ingang links kanaal
int rightChannel = A1; //ingang rechts kanaal
int left;
int right;


void setup()
{
for (int i = 0; i < 10; i++)
pinMode(led[i], OUTPUT);
for (int e = 0; e < 10; e++)
pinMode(led1[e], OUTPUT);
}


void loop()
{
left = analogRead(leftChannel); //lees het rechtse kanaal
right = analogRead(rightChannel); //lees het linkse kanaal
left = (int) (left /102.3); //aanpassen gevoeligheid linkse kanaal
right = (int) right /102.3; //aanpassen gevoeligheid rechtse kanaal
//left = 1500; //doe de schuine streepjes weg om de linkse leds te testen
//left = 0; //doe de schuine streepjes weg om te testen dat de linkse leds ut zijn zonder muziek
//left

if (left == 0) //als het volume 0 is zet alle leds uit
{
delay(40);
for(int i = 0; i < 10; i++)
{
digitalWrite(led[i], LOW);
}
}
else
{
for (int i = 0; i < left; i++) //leds worden aangezet aangepast aan het volume van de muziek
{
digitalWrite(led[i], HIGH);
}

for (int i = left; i < 10; i++)
{
digitalWrite(led[i], LOW);
}
}


//right
if (right == 0) //als het volume 0 is zet alle leds uit
{
for(int e = 0; e < 10; e++)
{
digitalWrite(led1[e], LOW);
}
}
else
{
for (int e = 0; e < right; e++) //leds worden aangezet aangepast aan het volume van de muziek
{
digitalWrite(led1[e], HIGH);
}
for (int e = right; e < 10; e++)
{
digitalWrite(led1[e], LOW);
}
}
}

PaulS

Quote
The problem seems (what I think) is that the values of the input get read to fast
Why do you think that? The code does something that we can not see. You expect it to do something that you've kept a secret.

Quote
I hope you guys can help me out.
Sure thing. Which way did you come in?
The art of getting good answers lies in asking good questions.

Plushy

What do you mean with 'the code does something that we can not see'. I'm just here trying to learn from people that are more advanced in programming then me.

hammy

#3
May 24, 2019, 03:41 pm Last Edit: May 24, 2019, 03:44 pm by hammy
It's tough love on this forum ...

You need something to turn one or more leds off depending on the input signal
- as it is now it turns leds on, but never off unless the input is zero.

Swap your < for <=

Also worth printing out values as it runs so you can see what is actually happening, and see if your scaling is correct .

You don't need to redefine a variable once you've done it

This is wrong : int z =int(z/120) or whatever you wrote

Not sure if this fixes it , a few thoughts, but adding print lines so you can debug the codes is always a good move.

Plushy

Thanks for the response!
I'll try to change up the code until it works. :)

PaulS

What do you mean with 'the code does something that we can not see'. I'm just here trying to learn from people that are more advanced in programming then me.
Don't you think that would work better if you said "My code is making the Arduino do the hokey-pokey, but I want it to do the macerana"?

If you tell us what the code actually does, and how that differs from what you want, it is a lot more likely that you'll get help.
The art of getting good answers lies in asking good questions.

KrisKasprzak

...agree with a comment above. There are some helpful people mixed with useless comments on this forum.

have you tried outputting your led array to the serial plotter?

add to setup()

Serial.begin(115200);

then in your for loop add

Serial.println(ledl);

access serial monitor from tools, the talk (or hum a constant level) into you mic. Maybe the mics output voltages are too small to detect.
Thanks,

Kris

DVDdoug

#7
May 24, 2019, 05:37 pm Last Edit: May 24, 2019, 05:40 pm by DVDdoug
What kind of connection/hardware to you have?  
What kind of readings are you getting?  (Use the serial monitor like the Analog Read Serial Example.)

If you are using a microphone board the output should be biased (so you can read the negative half of the audio signal) and silence should read ~512.    If you are using a line-level or headphone-level connection you need to add a bias circuit.*

Quote
The problem seems (what I think) is that the values of the input get read to fast in and displayed on the leds.
Yes...  I think you main problem may be that you are sampling a WAVE so even with a constant tone you readings will jump-around "randomly".  If you don't understand that, the Audacity Website has a little tutorial about how audio is digitized (sampled).

One common technique is to read in a fast-loop and find the peak every 50 - 100 milliseconds or so.  I do this with my World's Simplest Lighting Effect.**   Or, you can calculate a moving average of the absolute value (after subtracting the bias), or calculate the average of the positive values, or you can calculate the RMS.



*The Arduiono can be damaged by negative voltages and/or you can "damage" (distort) the audio signal.  My World's Simplest Effect has a schematic for the bias circuit.   But, my real-world effects actually use a Peak Detector.   With the peak detector I don't need the bias, plus I can sample at about 10 times per second instead of thousands of times per second.   And, without the bias I can switch to the optional 1.1V reference for more sensitivity.

**I use a 20 second moving average as my reference.    I use a similar technique for a VU meter effect  so the meter sensitivity adjusts automatically for lots of "meter action" with loud or quiet signals.    So obviously, it's uncalibrated and it's not a real meter, it's just an effect.  

Go Up