Hilfe bei VU Meter

Hallo, ich bin völlig neu in diesem Gebiet und habe meinen Arduino Uno nun den 2ten Tag.

Von Elektronik habe ich Grundkentnisse. Was eben der Kfz-Mechatroniker Beruf so mit sich bringt.

Nun zu meinen Projekt! Ich möchte einen Vu Meter bauen und habe diesen schon nach einer Anleitung im Internet begonnen. Sieht soweit alles gut aus bis auf einen Fehler. Immer wenn die Musik zu laut wird bzw das Signal zu stark bleibt er oben hängen so das alle LEDs brennen. Dies bleibt auch so selbst wenn man wieder leiser macht. Mit einem Reset funktioniert alles wieder. Da der Arduino fest eingebaut werden soll darf dies nicht passieren. Könnt ihr mir helfen?

int sound[4];
int soundav;
const int inputPIN =A5; //audio input pin, you have to amplify your output to max 5V
const int firstLED= 2; //first output pin for the leds
const int lastLED = 11; //last output pin for the leds
int leds;
int x;
int y;

void setup ()
{
pinMode (inputPIN, INPUT); // put input pin in input state
for (int a=firstLED; a <=lastLED; a++){ // loop through all the outputpins and put them in output state
pinMode(a, OUTPUT);
}
leds = (firstLED + lastLED) +1; //count how many leds you have connected + add 1 for all leds off
}

void loop ()
{
for (int num=0; num < 4; num++) {
sound[num]= analogRead (inputPIN);
if(num==3) {
soundav=(sound[0]+sound[1]+sound[2]+sound[3])/4; // average sound levels
x = map(soundav, 1, 255, 0,leds); // map the sound values from 0 to 20 because we have 21 levels. OFF & 20 leds.
y = firstLED + x; //get the correct led pin number where the led state changes
for (int b= firstLED; b < y; b++) { //loops through all the leds from firstLED to the level of the sound
digitalWrite(b,HIGH);
}
for (int c = y; c <= lastLED ; c++) { //loops through all the leds from lastLED to the level of the sound
digitalWrite(c,LOW);
}
}
}
}

leds = (firstLED + lastLED) +1;

erscheint mir

  1. falsch
  2. eigentlich auch eine Konstante, und sollte daher als
const int leds = lastLED-firstLED+1;

gleich am Anfang definiert sein.

Erklärt aber zugegeben nicht komplett deine Fehlerbeschreibung. Da helfen dann debug-Ausgaben ...

Mit normalen Einstellungen liefert analogRead() Werte zwischen 0..1023

Mir fällt dies auf

x = map(soundav, 1, 255, 0,leds);

Die Funktion erwartet damit Werte zwischen 1..255.
Der Atmel hat aber einen 10-Bit ADC Default.

IHMO würde ich das so versuchenx = map(soundav, 0, 1023, 0,leds);

Die map Funktion schaut so aus:

long map(long x, long in_min, long in_max, long out_min, long out_max)
{  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Damit alle Bereiche (sowohl Null als auch Voll-Ausschlag) gleich breit sind, empfiehlt sich eher

int x = map(analogRead(A0), 0 , [b]1024[/b], 0,[b] leds+1[/b]);

1023 ist dann der größte Wert, der auf x = leds gemappt wird aber auch einige Werte vorher ergeben schon den Wert leds.

Kann natürlich auch auf tatsächlich vorkommende Maximal-Werte ( < 1023 ) skaliert werden.

Dann ist evtl. auch die Funktion constrain sinnvoll.

VU Meter haben praktisch immer eine dB Anzeige d.h. log U statt U. Von daher wird map da nicht wirklich was bringen. Weiterhin wird normalerweise auch ein bischen über die Zeit integriert. Ansonsten wird das Teil zu unruhig.

@Udo Klein: Ich erkannte auch erst nach deinem Hinweiß das beim VU Meter keine lineare Funktion handelt.
Dazu kommt das Integrieren, wie das mit Formeln geht habe ich mal gelernt.

Wenn du mal Lust hast dazu hast, wie würde das in diesem konkreten Fall aussehen ?