Bonjour et bienvenue dans la dernière partie de la série "VU-Meter".
Dans cette partie, nous répondons à certaines de vos demandes d'amélioration et fournissons à notre VU Meter de nouvelles options de réglage. Avec l'aide d'un total de 4 nouveaux potentiomètres rotatifs, la luminosité de l'affichage peut maintenant être réglée dans une large plage, et la sensibilité de chaque canal individuel peut également être réglée dans son ensemble!
Cependant, nous vous demandons de comprendre que toutes vos bonnes idées et suggestions d'amélioration ne peuvent pas être prises en compte, car nous avons d'autres excellentes idées de projets que nous voulons vous présenter.
Voyons d'abord les extensions matérielles d'aujourd'hui pour notre VU-mètre. Tout d'abord, un potentiomètre de 2 KOhm est connecté en série dans les deux canaux audio R et L. Ensemble, ceux-ci forment un contrôleur de sensibilité séparé, efficace, rugueux et réglable individuellement pour les deux canaux. De plus, nous avons un fin contrôleur de sensibilité de 10 KOhm, qui capture les deux canaux, en tant qu'option de réglage prise en charge par logiciel. Il est conseillé de concevoir les deux contrôleurs d'entrée comme des potentiomètres d'impression qui, une fois réglés, restent réglés dans le boîtier du VU-mètre. Le régulateur de sensibilité fine, d'autre part, doit être fixé et réglé de l'extérieur à l'aide d'un bouton rotatif.
Enfin, il nous manque encore une option de réglage pour la luminosité de l'écran de 1-100%. Jusqu'à présent, nous avons défini la luminosité statiquement dans le code, également pour maintenir la charge actuelle dans les limites. Comme cela n'est plus nécessaire avec notre nouvelle alimentation plus puissante (5 volts, 2,5 A min), nous libérons également ce paramètre à l'extérieur via un potentiomètre de 10 KOhm pour le réglage. Je recommande d'installer ce potentiomètre de l'extérieur avec un bouton réglable.
Pour la dernière partie de la série, la liste partielle suivante résulte:
- 1x Arduino Nano (avec FTDI)
- 1x Panneau LED U64
- 2x résistances 10 KOhm 1%
- 2x 680 ohms résistance 5%
- 1x alimentation 5 V, min 2,5 A
- 2 condensateurs électrolytiques 10 uF 64 volts
- 1x connecteur jack stéréo prise 3,5 mm
- 2x diode zener 5,1 volts
- 2x potentiomètres rotatifs 10 KOhm (luminosité, sensibilité de réglage fin)
- 2x potentiomètres rotatifs 2 KOhm (sensibilité de réglage approximatif R / L)
Nous câblons maintenant les composants du schéma de circuit suivant:
Après avoir complètement construit ou mis à jour le circuit, nous pouvons maintenant télécharger le code personnalisé sur notre Arduino:
#include <Adafruit_NeoPixel.h> // Quelle broche de l'Arduino est connectée aux NeoPixels? // Sur un bijou ou Gemma, nous suggérons de changer cela en 1: #define LED_PIN 13 // Combien de NeoPixels sont attachés à l'Arduino? #define LED_COUNT 64 // Déclarez notre objet bande NeoPixel: Adafruit_NeoPixel bande(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); // Argument 1 = Nombre de pixels dans la bande NeoPixel // argument 2 = numéro de broche Arduino (la plupart sont valides) // Argument 3 = drapeaux de type pixel, additionnez au besoin: // NEO_KHZ800 800 KHz bitstream (la plupart des produits NeoPixel avec LED WS2812) // NEO_KHZ400 400 KHz (pixels FLORA classiques 'v1' (pas v2), pilotes WS2811) // Les pixels NEO_GRB sont câblés pour le flux binaire GRB (la plupart des produits NeoPixel) // Les pixels NEO_RGB sont câblés pour le flux binaire RVB (v1 pixels FLORA, pas v2) // Les pixels NEO_RGBW sont câblés pour le flux binaire RGBW (produits NeoPixel RGBW) #define analogPinLeft A5 // Canal audio gauche, connecté à la broche analogique A5 #define analogPinRight A4 // Canal audio gauche, connecté à la broche analogique A4 #define analogPinBrightness A3 // Potentiomètre de luminosité 10 K, connecté à la broche analogique A3 #define analogPinSensivity A2 // Potentiomètre de sensibilité 10 K, connecté à la broche analogique A2 #définir Left_Channel_Deviation 5 #définir Right_Channel_Deviation 5 #définir Led_Brightness_Deviation 5 #définir VU_Sensivity_Deviation 7 int val_left_old = 0; // variable pour stocker la valeur lue depuis le canal gauche int Base_Left = 0; // 0 Base int val_right_old = 0; // variable pour stocker la valeur lue depuis le canal gauche int Base_Right = 0; // 0 Base int leftDropTime, rightDropTime; int dropDelay = 4; // attente avant de laisser tomber les leds int Led_Brightness = 512; // 50% Led Led_Brightness par défaut int Led_Brightness_old = 512; int GlobalSensivity = 512; // Init avec une sensibilité minimale octet LedRun_Brightness = 255; // 100% maximal Led_Brightness int VU_Sensivity = 0; int VU_Sensivity_old = 0; flotte dropFactor = .98; néant installer() { En série.commencer(9600); bande.commencer(); // INITIALIZE NeoPixel strip object (REQUIS) Led_Brightness = analogRead(analogPinBrightness); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); // Désactiver tous les pixels dès que possible 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; En série.commencer(9600); colorWipe(bande.Couleur(255, 0, 0), 5); // Rouge Led_Brightness = analogRead(analogPinBrightness); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); colorWipe(bande.Couleur(255, 255, 0), 5); // Jaune Led_Brightness = analogRead(analogPinBrightness); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); colorWipe(bande.Couleur(0, 255, 0), 5); // Vert Led_Brightness = analogRead(analogPinBrightness); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); rainbowFade2White(1, 1, 1); Led_Brightness = analogRead(analogPinBrightness); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); En série.println("Init complete. Virtual Zerolines:"); En série.impression("La gauche : "); En série.println(Base_Left); En série.impression("Droite: "); En série.println(Base_Right); } néant boucle() { Left_VU_Meter(LED_COUNT / 2, GlobalSensivity); Right_VU_Meter(LED_COUNT / 2, GlobalSensivity); Read_External_Parameters(); bande.spectacle(); // Mettre à jour la bande pour correspondre } néant Read_External_Parameters() { Led_Brightness = 0; Led_Brightness = analogRead(analogPinBrightness); Led_Brightness += analogRead(analogPinBrightness); Led_Brightness = Led_Brightness / 2; si ((abdos(Led_Brightness - Led_Brightness_old) > Led_Brightness_Deviation)) { Led_Brightness_old = Led_Brightness; // Serial.print ("Nouvelle luminosité LED:"); // Serial.println (carte (Led_Brightness, 0, 1023, 1, 255)); bande.setBrightness(carte(Led_Brightness, 0, 1023, 1, 255)); // Réglez la LUMINOSITÉ selon le potentiomètre bande.spectacle(); } VU_Sensivity = 0; VU_Sensivity = analogRead(analogPinSensivity); VU_Sensivity += analogRead(analogPinSensivity); VU_Sensivity = VU_Sensivity / 2; si ((abdos( VU_Sensivity - VU_Sensivity_old) > VU_Sensivity_Deviation)) { VU_Sensivity_old = VU_Sensivity; GlobalSensivity = carte(VU_Sensivity, 0, 1023, 30, 512); // Serial.print ("Nouvelle sensibilité VU:"); // Serial.println (GlobalSensivity); } } néant Left_VU_Meter(octet Level_Max_Pixels, int sensibilité) { int val_left = 0; bool Surcharge = faux; uint32_t rgbcolor; uint32_t teinte; int Force du signal = 0; octet VU_Led_Level = 0; val_left = analogRead(analogPinLeft); // lire la broche d'entrée val_left += analogRead(analogPinLeft); // lire la broche d'entrée val_left += analogRead(analogPinLeft); // lire la broche d'entrée val_left += analogRead(analogPinLeft); // lire la broche d'entrée val_left = val_left / 4; si (!(abdos(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; } autre { val_left = val_left_old; } } val_left_old = val_left; Force du signal = val_left - Base_Left; si (Force du signal < 0) { Force du signal = - Force du signal; } VU_Led_Level = carte(Force du signal, 0, sensibilité , 0, Level_Max_Pixels); si (VU_Led_Level > Level_Max_Pixels) { Surcharge = vrai; VU_Led_Level = Level_Max_Pixels; } autre { Surcharge = faux; } pour (int je = 0; je < Level_Max_Pixels; je++) { bande.setPixelColor(je, 0, 0, 0); // Effacer la couleur du pixel (en RAM) } pour (int je = 0; je < VU_Led_Level; je++) { // Pour chaque pixel de la bande ... teinte = carte(je, Level_Max_Pixels - 1, 0, 0, 21800); si (Surcharge) { rgbcolor = bande.Couleur(255, 0, 0); // Conversation de teinte à RVB } autre { rgbcolor = bande.CouleurHSV(teinte, 255, LedRun_Brightness); } bande.setPixelColor(je, rgbcolor); // Définit la couleur du pixel (en RAM) } } néant colorWipe(uint32_t Couleur, int attendez) { pour (int je = 0; je < bande.numPixels(); je++) { // Pour chaque pixel de la bande ... bande.setPixelColor(je, Couleur); // Définit la couleur du pixel (en RAM) bande.spectacle(); // Mettre à jour la bande pour correspondre retard(attendez); // Pause un instant } } néant Right_VU_Meter(octet Level_Max_Pixels, int sensibilité) { int val_right = 0; bool Surcharge = faux; uint32_t rgbcolor; uint32_t teinte; int Force du signal = 0; octet VU_Led_Level = 0; val_right = analogRead(analogPinRight); // lire la broche d'entrée val_right += analogRead(analogPinRight); // lire la broche d'entrée val_right += analogRead(analogPinRight); // lire la broche d'entrée val_right += analogRead(analogPinRight); // lire la broche d'entrée val_right = val_right / 4; si (!(abdos(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; } autre { val_right = val_right_old; } } val_right_old = val_right; Force du signal = val_right - Base_Right; si (Force du signal < 0) { Force du signal = - Force du signal; } VU_Led_Level = carte(Force du signal, 0, sensibilité , 0, Level_Max_Pixels); si (VU_Led_Level > Level_Max_Pixels) { Surcharge = vrai; VU_Led_Level = Level_Max_Pixels; } autre { Surcharge = faux; } int ColorVector = 0; pour (int je = LED_COUNT - Level_Max_Pixels; je < LED_COUNT; je++) { bande.setPixelColor(je, 0, 0, 0); // Effacer la couleur du pixel (en RAM) } int StartVector = LED_COUNT - VU_Led_Level; pour (int je = LED_COUNT - Level_Max_Pixels; je < LED_COUNT; je++) { // Pour chaque pixel de la bande ... teinte = carte(ColorVector, Level_Max_Pixels - 1, 0, 21800, 0); ColorVector++; si ( je >= StartVector) { si (Surcharge) { rgbcolor = bande.Couleur(255, 0, 0); // Conversation de teinte à RVB } autre { rgbcolor = bande.CouleurHSV(teinte, 255, LedRun_Brightness); } bande.setPixelColor(je, rgbcolor); // Définit la couleur du pixel (en RAM) } } } néant rainbowFade2White(int attendez, int arc-en-ciel, int whiteLoops) { int fadeVal = 0, fadeMax = 100; // La teinte du premier pixel parcourt les boucles complètes de «rainbowLoops» à travers la couleur // roue. La roue chromatique a une plage de 65536, mais ce n'est pas grave si nous retournons, donc // il suffit de compter de 0 à rainbowLoops * 65536, en utilisant des pas de 256 pour que nous // avance autour de la roue à un clip décent. pour (uint32_t firstPixelHue = 0; firstPixelHue < arc-en-ciel * 65536; firstPixelHue += 256) { pour (int je = 0; je < bande.numPixels(); je++) { // Pour chaque pixel de la bande ... // Décalage de la teinte des pixels d'une quantité pour effectuer une révolution complète du // roue chromatique (gamme 65536) sur toute la longueur de la bande // (étapes strip.numPixels ()): uint32_t pixelHue = firstPixelHue + (je * 65536L / bande.numPixels()); // strip.ColorHSV () peut prendre 1 ou 3 arguments: une teinte (0 à 65535) ou // ajoutez éventuellement la saturation et la valeur (luminosité) (de 0 à 255 chacune). // Ici, nous utilisons uniquement la variante à trois arguments, bien que le // la seconde valeur (saturation) est une constante 255. bande.setPixelColor(je, bande.gamma32(bande.CouleurHSV(pixelHue, 255, 255 * fadeVal / fadeMax))); } bande.spectacle(); retard(attendez); si (firstPixelHue < 65536) { // Première boucle, si (fadeVal < fadeMax) fadeVal++; // fondu } autre si (firstPixelHue >= ((arc-en-ciel - 1) * 65536)) { // Dernière boucle, si (fadeVal > 0) fadeVal--; // disparaître } autre { fadeVal = fadeMax; // Boucle intermédiaire, assurez-vous que le fondu est au maximum } } pour (int k = 0; k < whiteLoops; k++) { pour (int j = 0; j < 256; j++) { // Passez de 0 à 255 // Remplissez la bande entière de blanc au niveau de luminosité corrigé gamma 'j': bande.remplir(bande.Couleur(0, 0, 0, bande.gamma8(j)));
strip.show ();
}
}
}
Die erste Kalibrierung der Empfindlichkeit sollte an den getrennten R / L Grobreglern vorgenommen werden. Es sollte dabei darauf geachtet werden, dass der Fein Regler für die Empfindlichkeit auf „Minimum“ eingestellt wird. Weiterhin sollte darauf geachtet werden, dass während des Einschaltens des VU Meters und dem Abspielen des Intros die virtual Nulllinie eingelesen wird. Damit diese Kalibrierung korrekt ablaufen kann, ist es wichtig, während der Einschaltphase noch kein Audio Signal anzulegen. Erst wenn die Startanimationen beendet sind, kann ein Analogsignal angelegt werden.
Ich wünsche viel Spaß beim Musik hören und nachbauen.
Nachtrag: Fehlende Zeilen im Quellcode wurden hinzugefügt. Danke an Denis für den Hinweis!
7 commentaires
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
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
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
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
Am ende des Sketch fehlen 4 Zeilen.
strip.show();
}
}
}
Jürgen
Hmmm, code kopiert aber es hagelt an Fehlermeldungen, kann das sein?
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!