Einstellbares Stereo VU Meter - AZ-Delivery

Hola y bienvenidos a la última parte de la serie "VU-Meter".

 

En esta parte, responderemos a algunas de sus solicitudes de mejora y agregaremos nuevos ajustes a nuestro medidor de VU. Con la ayuda de un total de 4 nuevos potenciómetros rotativos, el brillo de la pantalla ahora se puede ajustar en un amplio espectro, así como la sensibilidad para cada canal individual, así como en todo el control!

Sin embargo, también le pedimos que entienda que no todo el mundo puede ser prestado atención a sus grandes ideas y sugerencias de mejora, ya que tenemos otras grandes ideas para los proyectos que queremos presentarles.

Comencemos con las extensiones de hardware de hoy para nuestro medidor DE VU. En primer lugar, un potenciómetro de 2 KOhm está conectado en serie en los dos canales de audio R y L. Juntos, estos forman un controlador de sensibilidad separada grueso y ajustado individualmente para ambos canales. Además, tenemos un excelente controlador de sensibilidad de 10 KOhm que captura ambos canales como una opción de configuración independiente compatible con software. Se recomienda ejecutar los dos controladores de entrada como potenciómetros de impresión, que permanecen configurados una vez en la carcasa del medidor DE VU. El controlador de sensibilidad fina, por otro lado, debe ajustarse desde el exterior con una perilla giratoria.

Por último, nos falta una opción de ajuste para el brillo de la pantalla de 1-100%. Hasta ahora, hemos definido estáticamente el brillo en el código, también para mantener la carga actual bajo control. Dado que esto ya no es necesario con nuestra nueva fuente de alimentación más potente (5 voltios, 2,5 a min), también liberamos este parámetro al exterior a través de un potenciómetro de 10 KOhm para ajustar. Recomiendo que también instale este potenciómetro desde el exterior con una perilla giratoria.

Para la última parte de la serie, los siguientes resultados de la sublista final: 

  • 1x Arduino Nano (con FTDI)
  • 1x U64 LED Panel
  • 2x 10 KOhm Retames 1%
  • Resistencia 2x 680 Ohm 5%
  • 1x 5 Voltios, min 2.5 Amperio fuente de alimentación
  • 2x 10 uF 64 Volt Condensador Electrolítico
  • 1x conector jack estéreo de 3,5 mm hembra
  • 2x 5.1 Volt Zener Diodo
  • Potenciómetro giratorio 2x 10 KOhm (brillo, sensibilidad de ajuste fino)
  • Potenciómetro rotativo de impresión 2x 2 KOhm (sensibilidad de ajuste áspero R / L)

Ahora conectamos los componentes del siguiente esquema:

 

Medidor esquemático VU Parte3

 

Después de haber configurado o actualizado completamente el circuito, ahora podemos cargar el código personalizado a nuestro Arduino:

 

 

#include <Adafruit_NeoPixel.H>

¿Qué pin del Arduino está conectado a los NeoPixels?
En una baratija o Gemma sugerimos cambiar esto a 1:
#define LED_PIN     13
¿Cuántos NeoPixels están conectados al Arduino?
#define LED_COUNT  64

Declare nuestro objeto de tira NeoPixel:
Adafruit_NeoPixel Tira(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Argumento 1 - Número de píxeles en la tira de NeoPixel
Argumento 2 - Número de pin de Arduino (la mayoría son válidos)
Argumento 3 - Marcas de tipo de píxel, agregue nade según sea necesario:
NEO_KHZ800 transmisión de bits de 800 KHz (la mayoría de los productos NeoPixel con LEDs W/WS2812)
NEO_KHZ400 400 KHz (clásico 'v1' (no v2) píxeles FLORA, controladores WS2811)
NEO_GRB píxeles están cableados para la corriente de bits GRB (la mayoría de los productos NeoPixel)
NEO_RGB los píxeles están cableados para el flujo de bits RGB (v1 píxeles FLORA, no v2)
NEO_RGBW los píxeles están cableados para el flujo de bits RGBW (productos NeoPixel RGBW)

#define analogPinLeft A5 Canal de audio izquierdo, conectado al pin analógico A5
#define analogPinRight A4 Canal de audio izquierdo, conectado al pin analógico A4
#define analogPinBrightness A3 Potenciómetro de brillo 10 K, conectado al pin analógico A3
#define analogPinSensivity A2 Potenciómetro de sensibilidad 10 K, conectado al pin analógico A2

#define Left_Channel_Deviation  5
#define Right_Channel_Deviation 5
#define Led_Brightness_Deviation 5
#define VU_Sensivity_Deviation 7

Int val_left_old = 0;  variable para almacenar el valor leído desde Channel Left
Int Base_Left = 0;   0 Base
Int val_right_old = 0;  variable para almacenar el valor leído desde Channel Left
Int Base_Right = 0;   0 Base

Int leftDropTime, rightDropTime;
Int dropDelay = 4;                                        tiempo de espera antes de dejar caer los leds
Int Led_Brightness = 512;  50% Led Led_Brightness por defecto
Int Led_Brightness_old = 512;
Int GlobalSensivity = 512; Init con mínima sensibilidad

Byte LedRun_Brightness = 255;  Led_Brightness 100% máximo
Int VU_Sensivity = 0;
Int VU_Sensivity_old  = 0;
Flotador dropFactor = .98;

Vacío Configuración()
{   Serial.Comenzar(9600);   Tira.Comenzar();           Objeto de tira INITIALIZE NeoPixel (requerido)   Led_Brightness = analogRead(analogPinBrightness);   Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro   Tira.Mostrar();            Apagar todos los píxeles lo antes posible   VU_Sensivity = analogRead(analogPinSensivity);   VU_Sensivity += analogRead(analogPinSensivity);   VU_Sensivity += analogRead(analogPinSensivity);   VU_Sensivity += analogRead(analogPinSensivity);   VU_Sensivity = VU_Sensivity / 4;   Base_Left = analogRead(analogPinLeft);   Base_Left += analogRead(analogPinLeft);   Base_Left += analogRead(analogPinLeft);   Base_Left += analogRead(analogPinLeft);   Base_Left = Base_Left / 4;   Base_Right = analogRead(analogPinRight);   Base_Right += analogRead(analogPinRight);   Base_Right += analogRead(analogPinRight);   Base_Right += analogRead(analogPinRight);   Base_Right = Base_Right / 4;   Serial.Comenzar(9600);   colorWipe(Tira.Color(255, 0, 0), 5); Rojo   Led_Brightness = analogRead(analogPinBrightness);   Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro   Tira.Mostrar();   colorWipe(Tira.Color(255, 255, 0), 5); Amarillo   Led_Brightness = analogRead(analogPinBrightness);   Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro   Tira.Mostrar();   colorWipe(Tira.Color(0, 255, 0), 5); Verde   Led_Brightness = analogRead(analogPinBrightness);   Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro   Tira.Mostrar();   rainbowFade2White(1, 1, 1);   Led_Brightness = analogRead(analogPinBrightness);   Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro   Tira.Mostrar();   Serial.println("Init completo. Zerolines virtuales:");   Serial.Impresión("Izquierda : ");   Serial.println(Base_Left);   Serial.Impresión("Derecha: ");   Serial.println(Base_Right);
}

Vacío Bucle()
{   Left_VU_Meter(LED_COUNT / 2, GlobalSensivity);   Right_VU_Meter(LED_COUNT / 2, GlobalSensivity);   Read_External_Parameters();   Tira.Mostrar();   Actualizar tira para que coincida
}


Vacío Read_External_Parameters()
{   Led_Brightness = 0;   Led_Brightness = analogRead(analogPinBrightness);   Led_Brightness += analogRead(analogPinBrightness);   Led_Brightness = Led_Brightness / 2;   Si ((Abs(Led_Brightness - Led_Brightness_old) > Led_Brightness_Deviation))   {     Led_Brightness_old = Led_Brightness;     Serial.print("Nuevo brillo LED: ");     Serial.println(map(Led_Brightness, 0, 1023, 1, 255));     Tira.setBrightness(Mapa(Led_Brightness, 0, 1023, 1, 255)); Ajuste BRIGHTNESS según potenciómetro     Tira.Mostrar();   }   VU_Sensivity = 0;   VU_Sensivity = analogRead(analogPinSensivity);   VU_Sensivity += analogRead(analogPinSensivity);   VU_Sensivity =  VU_Sensivity / 2;   Si ((Abs( VU_Sensivity - VU_Sensivity_old) >  VU_Sensivity_Deviation))   {     VU_Sensivity_old =  VU_Sensivity;     GlobalSensivity = Mapa(VU_Sensivity, 0, 1023, 30, 512);     Serial.print("Nueva sensibilidad VU: ");     Serial.println(GlobalSensivity);   }
}

Vacío Left_VU_Meter(Byte Level_Max_Pixels, Int Sensibilidad)
{   Int val_left = 0;   Bool Sobrecarga = Falso;   uint32_t Rgbcolor;   uint32_t Hue;   Int Signal_Strength = 0;   Byte VU_Led_Level = 0;   val_left = analogRead(analogPinLeft);  leer el pin de entrada   val_left += analogRead(analogPinLeft);  leer el pin de entrada   val_left += analogRead(analogPinLeft);  leer el pin de entrada   val_left += analogRead(analogPinLeft);  leer el pin de entrada   val_left = val_left / 4;   Si (!(Abs(val_left - val_left_old) > Left_Channel_Deviation)) {     val_left = val_left_old;   }   Si (val_left < val_left_old)   {     leftDropTime++;     Si (leftDropTime > dropDelay)     {       val_left = val_left_old * dropFactor;       leftDropTime = 0;     }     Más     {       val_left = val_left_old;     }   }   val_left_old = val_left;   Signal_Strength = val_left - Base_Left;   Si (Signal_Strength < 0) {     Signal_Strength = - Signal_Strength;   }   VU_Led_Level =  Mapa(Signal_Strength, 0, Sensibilidad , 0, Level_Max_Pixels);   Si (VU_Led_Level > Level_Max_Pixels)   {     Sobrecarga = Verdad;     VU_Led_Level = Level_Max_Pixels;   } Más {     Sobrecarga = Falso;   }   Para (Int  = 0;  < Level_Max_Pixels; ++) {     Tira.setPixelColor(, 0, 0, 0);  Borrar color del píxel (en RAM)   }   Para (Int  = 0;  < VU_Led_Level; ++) { Para cada píxel en la tira...     Hue = Mapa(, Level_Max_Pixels - 1, 0, 0, 21800);     Si (Sobrecarga) {       Rgbcolor = Tira.Color(255, 0, 0);   Tono a la conversación RGB     } Más {       Rgbcolor = Tira.ColorHSV(Hue, 255, LedRun_Brightness);     }     Tira.setPixelColor(, Rgbcolor);         Establecer el color del píxel (en RAM)   }
}

Vacío colorWipe(uint32_t Color, Int Esperar) {   Para (Int  = 0;  < Tira.numPixels(); ++) { Para cada píxel en la tira...     Tira.setPixelColor(, Color);         Establecer el color del píxel (en RAM)     Tira.Mostrar();                          Actualizar tira para que coincida     Retraso(Esperar);                           Pausa por un momento   }
}

Vacío Right_VU_Meter(Byte Level_Max_Pixels, Int Sensibilidad)
{   Int val_right = 0;   Bool Sobrecarga = Falso;   uint32_t Rgbcolor;   uint32_t Hue;   Int Signal_Strength = 0;   Byte VU_Led_Level = 0;   val_right  = analogRead(analogPinRight);  leer el pin de entrada   val_right  += analogRead(analogPinRight);  leer el pin de entrada   val_right  += analogRead(analogPinRight);  leer el pin de entrada   val_right  += analogRead(analogPinRight);  leer el pin de entrada   val_right  = val_right / 4;   Si (!(Abs(val_right - val_right_old) > Right_Channel_Deviation)) {     val_right = val_right_old;   }   Si (val_right < val_right_old)   {     rightDropTime++;     Si (rightDropTime > dropDelay)     {       val_right = val_right_old * dropFactor;       rightDropTime = 0;     }     Más     {       val_right = val_right_old;     }   }   val_right_old = val_right;   Signal_Strength = val_right - Base_Right;   Si (Signal_Strength < 0) {     Signal_Strength = - Signal_Strength;   }   VU_Led_Level =  Mapa(Signal_Strength, 0, Sensibilidad , 0, Level_Max_Pixels);   Si (VU_Led_Level > Level_Max_Pixels)   {     Sobrecarga = Verdad;     VU_Led_Level = Level_Max_Pixels;   } Más {     Sobrecarga = Falso;   }   Int ColorVector = 0;   Para (Int  = LED_COUNT - Level_Max_Pixels;  < LED_COUNT; ++) {     Tira.setPixelColor(, 0, 0, 0);  Borrar color del píxel (en RAM)   }   Int StartVector = LED_COUNT - VU_Led_Level;   Para (Int  = LED_COUNT - Level_Max_Pixels;  < LED_COUNT; ++) { Para cada píxel en la tira...     Hue = Mapa(ColorVector, Level_Max_Pixels - 1, 0, 21800, 0);     ColorVector++;     Si (  >= StartVector)     {       Si (Sobrecarga) {         Rgbcolor = Tira.Color(255, 0, 0);   Tono a la conversación RGB       } Más {         Rgbcolor = Tira.ColorHSV(Hue, 255, LedRun_Brightness);       }       Tira.setPixelColor(, Rgbcolor);         Establecer el color del píxel (en RAM)     }   }
}

Vacío rainbowFade2White(Int Esperar, Int rainbowLoops, Int whiteLoops) {   Int fadeVal = 0, fadeMax = 100;   Tono del primer píxel ejecuta 'rainbowLoops' bucles completos a través del color   Rueda. La rueda de color tiene un rango de 65536, pero está bien si damos la vuelta, así que   sólo contar de 0 a rainbowLoops *65536, utilizando pasos de 256 por lo que   avanzar alrededor de la rueda en un clip decente.   Para (uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops * 65536;        firstPixelHue += 256) {     Para (Int Ⅰ. = 0; Ⅰ. < Tira.numPixels(); Ⅰ.++) { Para cada píxel en la tira...       Desplazamiento de tono de píxel en una cantidad para hacer una revolución completa de la       rueda de color (rango de 65536) a lo largo de la longitud de la tira       (pasos strip.numPixels():       uint32_t pixelHue = firstPixelHue + (Ⅰ. * 65536L / Tira.numPixels());       Tira. ColorHSV() puede tomar 1 o 3 argumentos: un tono (0 a 65535) o       opcionalmente añadir saturación y valor (brillo) (cada uno de 0 a 255).       Aquí estamos usando sólo la variante de tres argumentos, aunque el       segundo valor (saturación) es una constante 255.       Tira.setPixelColor(Ⅰ., Tira.gamma32(Tira.ColorHSV(pixelHue, 255,                                            255 * fadeVal / fadeMax)));     }     Tira.Mostrar();     Retraso(Esperar);     Si (firstPixelHue < 65536) {                             Primer bucle,       Si (fadeVal < fadeMax) fadeVal++;                      desvanecerse en     } Más Si (firstPixelHue >= ((rainbowLoops - 1) * 65536)) { El último bucle,       Si (fadeVal > 0) fadeVal--;                            desvanecerse     } Más {       fadeVal = fadeMax; Bucle provisional, asegúrese de que el desvanecimiento esté en máx.     }   }   Para (Int K = 0; K < whiteLoops; K++) {     Para (Int J = 0; J < 256; J++) { Rampa de hasta 0 a 255       Llene toda la tira con blanco en el nivel de brillo corregida por gamma 'j':       Tira.Llenar(Tira.Color(0, 0, 0, Tira.gamma8(J)));
strip.show();
}
}
}

 

 

La primera calibración de la sensibilidad debe realizarse en los reguladores gruesos R/L separados. Se debe tener cuidado de ajustar el control deslizante de sensibilidad fina a "mínimo". Además, se debe tener cuidado de asegurarse de que la línea cero virtual se lee durante el encendido del medidor VU y el juego de la introducción. Para que esta calibración funcione correctamente, es importante no crear una señal de audio durante la fase de encendido. Sólo cuando las animaciones de inicio están terminadas se puede crear una señal analógica.

 

Te deseo mucha diversión escuchando música y recreándola.

 

Hasta la próxima.

 

Addendum: se han agregado las líneas que faltan en el código fuente. Gracias a Denis por la pista!

Für arduinoProjekte für fortgeschrittene

7 comentarios

Tobias

Tobias

Hallo Marco,

Richtig erkannt .. Leider hat sich ein kleiner Fehler in die Bauteileliste eingeschlichen. Tatsächlich werden 4 statt 2 10 KOhm Wiederstände, wie im Schaltplan gezeigt benötigt. Diese werden für die Anhebung des Stereo-Audiosignals aus dem Minusbereich verwendet-

Tobias

Tobias

Hallo Jürgen,

Damit ich dir helfen kann, währe es hilfreich, wenn du die Fehlermeldungen präziser benennen könntest. Der Code ist prinzipiell getestet und funktioniert auf einem Prototypen, bevor er veröffentlicht wird.

Viele Grüße

Tobias

Tobias

Hallo Denis,

Strip Show wird nicht am ende gemacht, sondern in der Main Loop Schleife nach Read_External_Parameters(); . also von daher fehlen dieses Zeilen nicht ;)

Marco

Marco

Mhhm, also irgendwie passt der Fritzing-Schaltplan auch nicht so ganz zur Bauteilliste.
Okay, vielleicht ist der einfach von der Version davor.

Gut, die Trimmer werden also wohl von 5kΩ auf 2kΩ reduziert, die zwei Widerstände 980Ω auf 680Ω.

Nur welche zwei 10kΩ Widerstände fallen denn jetzt weg?

Denis

Denis

Am ende des Sketch fehlen 4 Zeilen.
strip.show();
}
}
}

Jürgen

Jürgen

Hmmm, code kopiert aber es hagelt an Fehlermeldungen, kann das sein?

Telemachos

Telemachos

Leider habe zu wenig Zeit, diese und viele in anderen Blogbeiträgen gezeigten Ideen nachzubauen. Die Ideen inspirieren und machen AZ-Delivery sympathisch. Wenn ich wieder Zeit habe, dann weiß ich wo ich die Bauteile ordere. Weiter so, bitte!

Deja un comentario

Todos los comentarios son moderados antes de ser publicados