Ciao e benvenuto in una nuova parte della serie "VU-Meter".
La grande risposta alla prima parte della serie è travolgente! Naturalmente accetteremo la sfida e nel prossimo passaggio aggiungeremo un altro canale al nostro misuratore VU. Il secondo canale viene visualizzato negativamente sul pannello U64. Abbiamo già un ottimo VU meter stereo con un impressionante effetto controrotante!
Naturalmente, ci sono anche alcune estensioni hardware e ottimizzazioni a bordo. Come ho scritto nella prima parte, il pannello U64 ha molta fame. Pertanto, la nostra prima modifica hardware è uno scambio del modulo di alimentazione della breadboard con un alimentatore stabile da 5 V / 2,6 A. Ora possiamo aumentare la luminosità dei LED del pannello dal 39% al 100% senza problemi di elettricità. Il display rende un po 'di più. Tuttavia, il codice inizialmente limita questa luminosità al 60% di luminosità. Questa limitazione scenderà quindi nella parte successiva della serie senza modificare l'alimentazione.
Ovviamente il modulo di alimentazione della breadboard non è spazzatura, ma può essere utilizzato per tutte le altre sovrastrutture -tracking progetti ugualmente entusiasmanti possono continuare ad essere utilizzati. Le altre parti aggiuntive, ovvero i due 680 ohm resistenze e i due diodi Zener da 5,1 volt svolgono funzioni di protezione del circuito per Arduino. Ciò risulta nel seguente elenco parziale per la parte odierna della serie:
- 1x Arduino Nano (con FTDI)
- 1x Pannello LED U64
- 2x 10 KOhm resistenze 1%
- 2x 680 ohm resistenze 5%
- 1x alimentatore da 5 volt, min 2,6 amp
- 1x condensatore elettrolitico da 10 uF a 64 volt
- 1x connettore jack stereo da 3,5 mm
- 2x diodo zener da 5,1 volt
Colleghiamo i componenti al seguente schema elettrico:
Dopo aver completamente costruito o aggiornato il circuito, ora possiamo caricare il codice aggiornato ed espanso sul nostro Arduino:
#include <Adafruit_NeoPixel.B> // Quale pin di Arduino è collegato ai NeoPixels? // Su un gingillo o Gemma ti consigliamo di cambiarlo in 1: #define LED_PIN 13 // Quanti NeoPixels sono collegati ad Arduino? #define LED_COUNT 64 // Dichiara il nostro oggetto striscia NeoPixel: Adafruit_NeoPixel striscia(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); // Argomento 1 = Numero di pixel nella striscia NeoPixel // argomento 2 = numero pin Arduino (la maggior parte sono validi) // Argomento 3 = Flag di tipo pixel, sommati secondo necessità: // NEO_KHZ800 bitstream 800 KHz (la maggior parte dei prodotti NeoPixel con LED WS2812) // NEO_KHZ400 400 KHz (pixel FLORA 'v1' classici (non v2), driver WS2811) // I pixel NEO_GRB sono cablati per bitstream GRB (la maggior parte dei prodotti NeoPixel) // I pixel NEO_RGB sono cablati per bitstream RGB (pixel FLORA v1, non v2) // I pixel NEO_RGBW sono cablati per bitstream RGBW (prodotti NeoPixel RGBW) #define analogPinLeft A5 // Canale audio sinistro, collegato al pin analogico A5 #define analogPinRight A4 // Canale audio destro, collegato al pin analogico A4 #define Left_Channel_Deviation 5 #define Right_Channel_Deviation 5 int val_left_old = 0; // variabile per memorizzare il valore letto dal canale sinistro int Base_Left = 0; // 0 base int val_right_old = 0; // variabile per memorizzare il valore letto dal canale sinistro int Base_Right = 0; // 0 base int tempo di caduta di sinistra, tempo di caduta destra; int ritardo goccia = 4; // tempo di attesa prima di far cadere i led // Luminosità NeoPixel, da 0 (min) a 255 (max) byte LUMINOSITÀ = 153; // 60% di luminosità galleggiante fattore di goccia = .98; vuoto configurazione() { striscia.iniziare(); // INIZIALIZZA oggetto striscia NeoPixel (RICHIESTO) striscia.spettacolo(); // DISATTIVA tutti i pixel AL PIÙ PRESTO striscia.SetBrightness(LUMINOSITÀ); // Impostare LUMINOSITÀ su circa 1/5 (max = 255) Base_Left = Leggi analogico(analogPinLeft); Base_Left += Leggi analogico(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; Seriale.inizio(9600); colorWipe(striscia.Colore(255, 0, 0), 5); // Rosso colorWipe(striscia.Colore(255, 255, 0), 5); // giallo colorWipe(striscia.Colore(0, 255, 0), 5); // Verde rainbowFade2White(1, 1, 1); } vuoto ciclo continuo() { Left_VU_Meter(LED_COUNT / 2, 512); Right_VU_Meter(LED_COUNT / 2, 511); striscia.mostrare(); // Aggiorna striscia per abbinare } vuoto Left_VU_Meter(byte Level_Max_Pixels, int sensibilità) { int val_left = 0; bool Sovraccarico = falso; uint32_t rgbcolor; uint32_t colore; int La potenza del segnale = 0; byte VU_Led_Level = 0; val_left = analogRead(analogPinLeft); // legge il pin di input val_left += analogRead(analogPinLeft); // legge il pin di input val_left += analogRead(analogPinLeft); // legge il pin di input val_left += analogRead(analogPinLeft); // legge il pin di input val_left = val_left / 4; Se (!(addominali(val_left - val_left_old) > Left_Channel_Deviation)) { val_left = val_left_old; } Se (val_left < val_left_old) { leftDropTime++; Se (leftDropTime > dropDelay) { val_left = val_left_old * dropFactor; leftDropTime = 0; } altro { val_left = val_left_old; } } val_left_old = val_left; La potenza del segnale = val_left - Base_Left; Se (La potenza del segnale < 0) { La potenza del segnale = - La potenza del segnale; } VU_Led_Level = carta geografica(La potenza del segnale, 0, sensibilità , 0, Level_Max_Pixels); Se (VU_Led_Level > Level_Max_Pixels) { Sovraccarico = vero; VU_Led_Level = Level_Max_Pixels; } altro { Sovraccarico = falso; } per (int io = 0; io < Level_Max_Pixels; io++) { striscia.setPixelColor(io, 0, 0, 0); // Cancella il colore dei pixel (in RAM) } per (int io = 0; io < VU_Led_Level; io++) { // Per ogni pixel nella striscia ... colore = carta geografica(io, Level_Max_Pixels - 1, 0, 0, 21800); Se (Sovraccarico) { rgbcolor = striscia.Colore(255, 0, 0); // Conversazione da tonalità a RGB } altro { rgbcolor = striscia.ColorHSV(colore, 255, LUMINOSITÀ); } striscia.setPixelColor(io, rgbcolor); // Imposta il colore del pixel (in RAM) } // strip.show (); // Aggiorna striscia per abbinare } vuoto colorWipe(uint32_t colore, int aspettare) { per (int io = 0; io < striscia.numPixels(); io++) { // Per ogni pixel nella striscia ... striscia.setPixelColor(io, colore); // Imposta il colore del pixel (in RAM) striscia.mostrare(); // Aggiorna striscia per abbinare ritardo(aspettare); // Pausa per un momento } } vuoto Right_VU_Meter(byte Level_Max_Pixels, int sensibilità) { int val_right = 0; bool Sovraccarico = falso; uint32_t rgbcolor; uint32_t colore; int La potenza del segnale = 0; byte VU_Led_Level = 0; val_right = analogRead(analogPinRight); // legge il pin di input val_right += analogRead(analogPinRight); // legge il pin di input val_right += analogRead(analogPinRight); // legge il pin di input val_right += analogRead(analogPinRight); // legge il pin di input val_right = val_right / 4; Se (!(addominali(val_right - val_right_old) > Right_Channel_Deviation)) { val_right = val_right_old; } Se (val_right < val_right_old) { rightDropTime++; Se (rightDropTime > dropDelay) { val_right = val_right_old * dropFactor; rightDropTime = 0; } altro { val_right = val_right_old; } } val_right_old = val_right; La potenza del segnale = val_right - Base_Right; Se (La potenza del segnale < 0) { La potenza del segnale = - La potenza del segnale; } VU_Led_Level = carta geografica(La potenza del segnale, 0, sensibilità , 0, Level_Max_Pixels); Se (VU_Led_Level > Level_Max_Pixels) { Sovraccarico = vero; VU_Led_Level = Level_Max_Pixels; } altro { Sovraccarico = falso; } int ColorVector = 0; per (int io = LED_COUNT - Level_Max_Pixels; io < LED_COUNT; io++) { striscia.setPixelColor(io, 0, 0, 0); // Cancella il colore dei pixel (in RAM) } int StartVector = LED_COUNT - VU_Led_Level; per (int io = LED_COUNT - Level_Max_Pixels; io < LED_COUNT; io++) { // Per ogni pixel nella striscia ... colore = carta geografica(ColorVector, Level_Max_Pixels - 1, 0, 21800, 0); ColorVector++; Se ( io >= StartVector) { Se (Sovraccarico) { rgbcolor = striscia.Colore(255, 0, 0); // Conversazione da tonalità a RGB } altro { rgbcolor = striscia.ColorHSV(colore, 255, LUMINOSITÀ); } striscia.setPixelColor(io, rgbcolor); // Imposta il colore del pixel (in RAM) } } } vuoto rainbowFade2White(int aspettare, int rainbowLoops, int whiteLoops) { int fadeVal = 0, fadeMax = 100; // La tonalità del primo pixel esegue il ciclo completo 'rainbowLoops' attraverso il colore // ruota. La ruota dei colori ha un intervallo di 65536 ma va bene se ci capovolgiamo, quindi // basta contare da 0 a rainbowLoops * 65536, usando i passaggi di 256, quindi noi // avanza intorno alla ruota con una clip decente. per (uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops * 65536; firstPixelHue += 256) { per (int io = 0; io < striscia.numPixels(); io++) { // Per ogni pixel nella striscia ... // Sfalsa la tonalità dei pixel di un importo per fare un giro completo del // ruota dei colori (intervallo di 65536) lungo la lunghezza della striscia // (strip.numPixels () steps): uint32_t pixelHue = firstPixelHue + (io * 65536L / striscia.numPixels()); // strip.ColorHSV () può accettare 1 o 3 argomenti: una tonalità (da 0 a 65535) o // opzionalmente aggiunge saturazione e valore (luminosità) (ciascuno da 0 a 255). // Qui stiamo usando solo la variante a tre argomenti, sebbene il // il secondo valore (saturazione) è una costante 255. striscia.setPixelColor(io, striscia.gamma32(striscia.ColorHSV(pixelHue, 255, 255 * fadeVal / fadeMax))); } striscia.mostrare(); ritardo(aspettare); Se (firstPixelHue < 65536) { // Primo ciclo, Se (fadeVal < fadeMax) fadeVal++; // dissolvenza } altro Se (firstPixelHue >= ((rainbowLoops - 1) * 65536)) { // Last loop, Se (fadeVal > 0) fadeVal--; // dissolvenza } altro { fadeVal = fadeMax; // Loop intermedio, assicurarsi che la dissolvenza sia al massimo } } per (int K = 0; K < whiteLoops; K++) { per (int j = 0; j < 256; j++) { // Aumenta da 0 a 255 // Riempi l'intera striscia di bianco al livello di luminosità con correzione gamma 'j': striscia.riempire(striscia.Colore(0, 0, 0, striscia.gamma8(j))); striscia.mostrare(); } per (int j = 255; j >= 0; j--) { // Riduci da 255 a 0 striscia.riempire(striscia.Colore(0, 0, 0, striscia.gamma8(j))); striscia.mostrare(); } } }
Esst beim Betrieb zu beachten, das während des Einschaltens des VU Meters and dem Abspielen des Intros die Virtuelle Nulllinie eingelesen wird. Dannazione di Kalibrierung korrekt ablaufen kann, è un esempio, quando è in arrivo in fase di segnale audio anzulegen. Prima di tutto ho iniziato a parlare con me, con un analogo film di angelo.
Ich wünsche viel Spaß beim Nachbauen bis zum nächsten Mal
2 commenti
Tobias
Hallo Niko,
Die Polung der Elkos bei Wechselspannung ist immer so eine Sache der Perspektive ;)
Dennoch ist die Polung hier Richtig, da der Bezug zur Masse des Audiosignals !über den 10 KOhm Wiederstand hergestellt wird.
Viele Grüße
Niko
Hallo Tobias,
ich will ja nicht lästig sein, aber bitte noch einmal die Polung der Elkos prüfen. Ich denke, die sollten andersrum gesteckt werden. Minus in Richtung Audiobuchse.
Schöne Grüße
und vielen Dank für die vielen Ideen und Vorschläge in deinem Blog!