Selbstgebautes VU-Meter

Selbstgebautes VU-Meter

 

Hallo und willkommen zu einem neuen und spannenden Blog. Heute begeben wir uns in die Niederfrequenz-Welt und bauen wir uns ein eigenes VU-Meter. Für alle, die die aus den 80ern bekannte Messgerät nicht mehr kennen: Ein VU-Meter (vu steht dabei für englischen Begriffe Volume Units, also in etwa „Lautstärkeneinheiten“) ist ein Aussteuerungsmesser, also ein Messinstrument zur Beurteilung der Signalstärke in der Tontechnik. Dabei wird die Signalstärke eines eingespeisten Audiosignals in seinem elektrischen Äquivalent gemessen.

Wir brauchen folgende Hardwareteile aus dem Shop um das VU Meter aufbauen zu können:


Damit wir ein Audio Signal mit unserem Arduino vermessen können, müssen wir zuerst einige Vorüberlegungen anstellen. Die wichtigste zuerst: Das Audiosignal ist eine arbiträre Wechselspannung im KHz Bereich, die um den Nullpunkt schwingt. Zur Messung dieses Signals eignet sich somit kein Digitaleingang. Auch ein Analogeingang unseres Mikrocontrollers für die Messung des Musik Niederfrequenzsignals ist ohne externe Beschaltung nur bedingt geeignet, da dieser nur positive Spannungswerte im Bereich von 0 bis 5 Volt bei einer Auflösung von 10 Bit messen kann. Um dies zu visualisieren zeige ich nachfolgend mit dem Oszilloskop aufgezeichnete Audio NF Schwingungen, so wie diese auch an einem Lautsprecher anliegen.

Abbindung: NF-Signal am Lausprechereingang, ungefiltert

Abbindung: NF-Signal am Lausprechereingang, ungefiltert

 

Wir bereiten daher im ersten Schritt unser Analoges NF Musik Signal mithilfe einer kleinen externen Widerstands-Kondensator Schaltung so auf, dass es mit einem Offset von 2,5 Volt in den positiven Spannungsbereich gehoben wird. Der Nulldurchgang in den negativen Bereich wird somit vermieden:

 

Abbindung: Gleiches NF Signal mit einem Gleichspannungsoffset.Abbindung: Gleiches NF Signal mit einem Gleichspannungsoffset.

 

 

Dies bewerkstelligen wir mit den in der Schaltungsplan zu sehenden zwei 10 KOhm Wiederständen und einem 10uF 63 Volt Elektrolytkondensator, dessen Kathode zu unserem Mikrocontroller zeigt. Bauen wir nun das VU Meter wie auf folgender Abbildung zu sehen komplett auf:

 

VU Meter Aufbau Steckplatine

 

Wichtig ist, dass das 64 Led Panel seine Stromversorgung durch das Power-Modul MB102 bezieht und NICHT durch den Arduino Nano, da im Betrieb bis zu 2,5 A durch den U64-LED Panel in der Spitze verbraucht werden. Diese Stromstärke würde, falls diese durch den Arduino bereitgestellt werden müsste, unweigerlich die Spannung zusammenbrechen lassen, bzw. den Spannungsregler auf dem Nano beschädigen. Auch die Dimensionierung des Netzteils sollte entsprechend gewählt werden.

 

#include <Adafruit_NeoPixel.h>

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN     13
// How many NeoPixels are attached to the Arduino?
#define LED_COUNT  64

// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 100

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

#define analogPinLeft A5 // Left Audio Channel, connected to analog pin A5

int val_left_old = 0;  // variable to store the value read from Channel Left
int Base_Left = 0;   // 0 Basis

void setup()
{
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)
  Base_Left = analogRead(analogPinLeft);
  Base_Left += analogRead(analogPinLeft);
  Base_Left += analogRead(analogPinLeft);
  Base_Left += analogRead(analogPinLeft);
  Base_Left = Base_Left / 4;
  colorWipe(strip.Color(255, 0, 0), 5); // Red
  colorWipe(strip.Color(255, 255, 0), 5); // yellow
  colorWipe(strip.Color(0, 255, 0), 5); // Green
  rainbowFade2White(1, 1, 1);
}

void loop()
{
  Left_VU_Meter(64, 100);
  delay(40);
}

void Left_VU_Meter(byte Level_Max_Pixels, int sensitivity)
{
  int val_left = 0;
  val_left = analogRead(analogPinLeft);  // read the input pin
  val_left += analogRead(analogPinLeft);  // read the input pin
  val_left += analogRead(analogPinLeft);  // read the input pin
  val_left += analogRead(analogPinLeft);  // read the input pin
  val_left = val_left / 4;
  int Signal_Strength = val_left - Base_Left;
  if (Signal_Strength < 0) {
    Signal_Strength = - Signal_Strength;
  }
  byte VU_Led_Level =  map(Signal_Strength, 0, sensitivity , 0, Level_Max_Pixels);
  for (int i = 0; i < Level_Max_Pixels; i++) {
    strip.setPixelColor(i, 0, 0, 0);  // Clear pixel's color (in RAM)
  }
  for (int i = 0; i < VU_Led_Level; i++) { // For each pixel in strip...
    uint32_t hue = map(i, Level_Max_Pixels - 1, 0, 0, 21800);
    uint32_t rgbcolor = strip.ColorHSV(hue, 255, BRIGHTNESS); // Hue to RGB Conversation
    strip.setPixelColor(i, rgbcolor);         //  Set pixel's color (in RAM)
  }
  strip.show();   //  Update strip to match
}

void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

void rainbowFade2White(int wait, int rainbowLoops, int whiteLoops) {
  int fadeVal = 0, fadeMax = 100;
  // Hue of first pixel runs 'rainbowLoops' complete loops through the color
  // wheel. Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to rainbowLoops*65536, using steps of 256 so we
  // advance around the wheel at a decent clip.
  for (uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops * 65536;
       firstPixelHue += 256) {
    for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      uint32_t pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the three-argument variant, though the
      // second value (saturation) is a constant 255.
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue, 255,
                                           255 * fadeVal / fadeMax)));
    }
    strip.show();
    delay(wait);
    if (firstPixelHue < 65536) {                             // First loop,
      if (fadeVal < fadeMax) fadeVal++;                      // fade in
    } else if (firstPixelHue >= ((rainbowLoops - 1) * 65536)) { // Last loop,
      if (fadeVal > 0) fadeVal--;                            // fade out
    } else {
      fadeVal = fadeMax; // Interim loop, make sure fade is at max
    }
  }
  for (int k = 0; k < whiteLoops; k++) {
    for (int j = 0; j < 256; j++) { // Ramp up 0 to 255
      // Fill entire strip with white at gamma-corrected brightness level 'j':
      strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
      strip.show();
    }
    for (int j = 255; j >= 0; j--) { // Ramp down 255 to 0
      strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
      strip.show();
    }
  }
}

 

 

Jetzt können wir ein NF Analogsignal eines Lautsprechers an die Audiobuchse anschließen. Line-In Level reichen hierbei NICHT aus, um unser VU Meter zu betreiben. Der Audio Eingang werden daher direkt mit dem Leistungsausgang der Audioquelle (max 30 Watt Peak) verbunden.


In den nächsten beiden Teilen dieser Reihe bauen wir einen zweiten Kanal, um auch Stereosignale mit dem VU Meter anzeigen zu können, und fügen einige Einstellungsmöglichkeiten, wie zB. Empfindlichkeit und Helligkeit hinzu.
Schreibt eure Fragen oder Wünsche wie immer in die Kommentare.

Ich wünsche viel Spaß bei Nachbau des VU Meters und bis zum nächsten Mal.

Letzter Artikel Stereo VU Meter
Neuer Artikel Nutzung des ESP32 Deep Sleep Modus für unsere Katzenklappe

Kommentar

Tobias - Oktober 11, 2019

Hallo Nils,
Du liegst richtig, die virtuelle Nullinie wird zum Startzeitpunkt des Arduinos eingelesen. Zu diesem Zeitpunkt sollte demnach noch kein Signal anliegen, da diese sonst ggf. verfälscht werden könnte. Dies ist nötig, da die Toleranzen der Bauteile selbst bei nur 1% Abweichung dazu führen könnten, das nach dem Start die eine oder andere VU Led dauerhaft leuchtet. Dies sieht sehr unschön aus. Daher diese Lösung der virtuellen Nullinie. Man könnte aber auch alternativ einmalig die Nullinie beim ersten Start einlesen, und ins EEPRom schreiben, wenn einen das stört.

Tobias - Oktober 8, 2019

Hallo Heiko,

Eine berechtigter Punkt. Jedoch steckt bei der Wahl der MB102 Breadboard Spannungsversorgung die Überlegung dahinter, das das VU Meter zunächst als auf dem Breadboard als TEST aufgebaut wird und später im festen Dauerbetrieb noch mal neu dauerhaft auf eine Platine gelötet wird. Für den festen und gelöteten Einsatz als Modul sollte dann passend dimensioniertes externes 5 Volt-Netzteil verwendet werden. Die MB102 Breadboard Spannungsversorgung ist, wie der Name schon vermuten lässt für den Breadboardeinsatz konzipiert.
Dennoch reicht die MB102 Breadboard Spannungsversorgung für den ersten Aufbau und Test der hier vorgestellten Schaltung aus, denn die 2,5 Ampere beziehen sich auf eine Helligkeitsaussteuerung von 100 % und eine Aussteuerung der LED’s von 100%. Bei dem og. Aufbau ist jedoch die Helligkeit der LED’s auf 39% der maximalen Helligkeit beschränkt, was den Stromverbrauch entsprechend reduziert. 39% von 2,5 A = 0,97 A bei Vollaussteuerung. Im mittleren Betrieb sollen darüber hinaus nur 50% der LED’s aktiv sein, d.h 0,97 A / 2 = 0,48 A. Somit unter den 0,7 Ampere des Moduls.
Zum testen der Schaltung also ausreichend. Im Festbetrieb sollte das Modul, wie du schon schreibst, durch ein normales Netzteil ersetzt werden.
Viele Grüße
Tobias

niko_at - Oktober 8, 2019

Meiner Meinung nach ist der Elko falsch gepolt, d.h. Kathode (Minus) muss an die Lautsprecherbuchse. And der LS-Buchse haben wir im Mittel 0V und am Mikrocontroller (Widerstandsteiler 2x 10kOhm) haben wir U/2 => +2,5V

Zudem fehlen Schutzdioden, dass am Mikrocontroller Eingang nicht Spannungen weit über Ub (5V) und nicht weit unter 0V gehen können!
Z.B: Mikrocontrollereingang über 10 kOhm (ggf. auch kleiner) und 2 Dioden (1N4148) jeweils in Sperrichtung gegen V und 0V. So kann die SPannung max. 0,7V üver V+ und 0,7V unter 0V gehen.

Nils - Oktober 8, 2019

Moin,
cooles Projekt! Verstehe ich das richtig, dass im Setup der Base_Left eingelesen wird, um das virtuelle Null-Niveau (Nulllinie) zu ermitteln. Das funktioniert aber nur richtig, wenn beim Einschalten noch kein Audio Signal am Analog-Pin anliegt. Alternativ könnte man 2 1% Widerstände zum Teilen der Spannung nehmen und dann die Nullinie einfach mit 2.5V (also 512) definieren.
Eingangsspannungen kleiner 0V oder größer 5V am analogen Pin werden nicht richtig gemessen, können eventuell den Arduino sogar beschädigen? Vielleicht mit 2 Dioden das Signal auf GND und +5V klemmen?

Dirk - Oktober 8, 2019

Hi, cooles Projekt, da ich im Moment ein VU Meter suche.
Kann man die LED Module hintereinanderschalten? Ich stelle mir vor, 3 Module zu nehmen.
Oder gleich eine komplette LED Matrix 64×32.
Ein Modul mit den 8 LED’s sind zu wenig Auflösung.
Und natürlich muss das mit den Line IN/OUT Signalen funktionieren.
Mann sollte das VU Meter auch kalibrieren können.
Am Lautsprecherausgang macht es für mich keinen Sinn, da sich da die Laustärke ständig ändert.
Danke und Grüße

Heiko Schütz - Oktober 8, 2019

Frage: Im Beitrag steht, dass “im Betrieb bis zu 2,5 A durch den U64-LED Panel in der Spitze verbraucht werden”. Laut Datenblatt ist die MB102-Spannungsversorgung bis 700 mA ausgelegt. Hält die Spannungsversorgung diese Spitzen von 2,5 A ohne Schaden zu nehmen aus – das ist ja keine Dauerbelastung? Oder wäre es nicht besser (sicherer), gleich ein passend dimensioniertes externes 5 Volt-Netzteil zu verwenden (wie man es z.B. auch zum Betrieb von längeren Neopixel-Streifen benötigt)?

(Datenblatt: https://cdn.shopify.com/s/files/1/1509/1638/files/MB102_Breadboard_Kit_Datenblatt.pdf)

Gerrit - Oktober 8, 2019

Es wäre schön das VU-Meter einmal in einem kurzen Video im Betrieb zu sehen, um entscheiden zu können ob sich der Nachbau für einen persönlich lohnt.

Gerhard Langner - Oktober 7, 2019

Hallo. Nicht neu aber cooles projekt. Ich denke eine leicht abgeänderte Vorschaltung wäre auch für die leute wie mich interesant die sowas lieber im linepegel haben möchten.

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe