Hallo en welkom bij het laatste deel van de "VU-Meter" -serie.
In dit deel behandelen we enkele van uw verbeteringsverzoeken en voorzien onze VU-meter van nieuwe instellingsopties. Met behulp van in totaal 4 nieuwe roterende potentiometers kan de helderheid van het display nu in een breed bereik worden ingesteld en kan de gevoeligheid voor elk individueel kanaal ook in het algemeen worden geregeld!
We vragen echter om uw begrip dat niet elk van uw geweldige ideeën en suggesties voor verbetering kunnen worden overwogen, omdat we andere geweldige ideeën hebben voor projecten die we aan u willen introduceren.
Laten we eerst de hardware-uitbreidingen van vandaag voor onze VU-meter behandelen. Eerst wordt een 2 KOhm-potentiometer in serie aangesloten in de twee audiokanalen R en L. Samen vormen deze een individueel instelbare, effectieve, ruwe, afzonderlijke gevoeligheidscontroller voor beide kanalen. Daarnaast hebben we een fijne 10 KOhm-gevoeligheidscontroller, die beide kanalen vastlegt, als een afzonderlijke software-ondersteunde instellingsoptie. Het is raadzaam om de twee ingangscontrollers te ontwerpen als printpotentiometers, die, eenmaal ingesteld, in de behuizing van de VU-meter blijven staan. De fijngevoeligheidsregelaar moet daarentegen worden bevestigd en van buitenaf worden afgesteld met een draaiknop.
Tot slot ontbreekt het ons nog steeds een instellingsoptie voor de helderheid van het scherm van 1-100%. Tot nu toe hebben we de helderheid statisch in de code gedefinieerd, ook om de huidige belasting binnen de limieten te houden. Omdat dit niet langer nodig is met onze nieuwe, krachtigere voeding (5 volt, 2,5 A min), geven we deze parameter ook naar buiten toe via een potentiometer van 10 KOhm voor aanpassing. Ik raad aan om deze potentiometer vanaf de buitenkant te installeren met een verstelbare knop.
Voor het laatste deel van de reeks resulteert de volgende gedeeltelijke lijst in resultaten:
- 1x Arduino Nano (met FTDI)
- 1x U64 LED paneel
- 2x 10 KOhm weerstanden 1%
- 2x 680 ohm weerstand 5%
- 1x 5 volt, min. 2,5 amp voeding
- 2x 10 uF 64 volt elektrolytische condensator
- 1x stereo jack-aansluiting 3,5 mm-aansluiting
- 2x 5,1 volt zenerdiode
- 2x 10 KOhm roterende potentiometers (helderheid, fijnafstemmingsgevoeligheid)
- 2x 2 KOhm roterende potentiometers (ruwe instelgevoeligheid R / L)
We bedraden nu de componenten van het volgende schakelschema:
Nadat we het circuit volledig hebben gebouwd of bijgewerkt, kunnen we de aangepaste code nu uploaden naar onze Arduino:
# opnemen <Adafruit_NeoPixel.h> // Welke pin op de Arduino is verbonden met de NeoPixels? // Op een Trinket of Gemma raden we aan dit te wijzigen in 1: #define LED_PIN 13 // Hoeveel NeoPixels zijn gekoppeld aan de Arduino? #define LED_COUNT 64 // Verklaar ons NeoPixel-stripobject: Adafruit_NeoPixel strippen(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); // Argument 1 = Aantal pixels in NeoPixel-strip // argument 2 = Arduino-pincode (de meeste zijn geldig) // Argument 3 = Pixel type vlaggen, voeg indien nodig bij elkaar: // NEO_KHZ800 800 KHz bitstream (meeste NeoPixel-producten met WS2812 LED's) // NEO_KHZ400 400 KHz (klassiek 'v1' (geen v2) FLORA-pixels, WS2811-stuurprogramma's) // NEO_GRB Pixels zijn bedraad voor GRB bitstream (de meeste NeoPixel-producten) // NEO_RGB Pixels zijn bedraad voor RGB bitstream (v1 FLORA-pixels, niet v2) // NEO_RGBW Pixels zijn bedraad voor RGBW bitstream (NeoPixel RGBW-producten) #define analogPinLeft A5 // Linker audiokanaal, aangesloten op analoge pin A5 #define analogPinRight A4 // Linker audiokanaal, verbonden met analoge pin A4 #define analogPinBrightness A3 // Helderheidspotentiometer 10 K, verbonden met analoge pin A3 #define analogPinSensivity A2 // Gevoeligheidspotentiometer 10 K, aangesloten op analoge pin A2 #bepalen Left_Channel_Deviation 5 #bepalen Right_Channel_Deviation 5 #bepalen Led_Brightness_Deviation 5 #bepalen VU_Sensivity_Deviation 7 int val_left_old = 0; // variabele om de waarde op te slaan die is gelezen van Channel Left int Base_Left = 0; // 0 Basis int val_right_old = 0; // variabele om de waarde op te slaan die is gelezen van Channel Left int Base_Right = 0; // 0 Basis int leftDropTime, rightDropTime; int dropDelay = 4; // tijd vasthouden voordat de leds vallen int Led_Brightness = 512; // 50% Led Led_Brightness standaard int Led_Brightness_old = 512; int GlobalSensivity = 512; // Init met minimale gevoeligheid byte LedRun_Brightness = 255; // 100% maximale Led_Brightness int VU_Sensivity = 0; int VU_Sensivity_old = 0; vlotter dropFactor = .98; nietig opstelling() { Serie.beginnen(9600); strip.beginnen(); // INITIALIZE NeoPixel-stripobject (VERPLICHT) Led_Brightness = analoog(analogPinBrightness); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); // Schakel alle pixels zo snel mogelijk UIT VU_Sensivity = analoog(analogPinSensivity); VU_Sensivity += analoog(analogPinSensivity); VU_Sensivity += analoog(analogPinSensivity); VU_Sensivity += analoog(analogPinSensivity); VU_Sensivity = VU_Sensivity / 4; Base_Left = analoog(analogPinLeft); Base_Left += analoog(analogPinLeft); Base_Left += analoog(analogPinLeft); Base_Left += analoog(analogPinLeft); Base_Left = Base_Left / 4; Base_Right = analoog(analogPinRight); Base_Right += analoog(analogPinRight); Base_Right += analoog(analogPinRight); Base_Right += analoog(analogPinRight); Base_Right = Base_Right / 4; Serie.beginnen(9600); kleur Veeg(strip.Kleur(255, 0, 0), 5); // rood Led_Brightness = analoog(analogPinBrightness); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); kleur Veeg(strip.Kleur(255, 255, 0), 5); // geel Led_Brightness = analoog(analogPinBrightness); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); kleur Veeg(strip.Kleur(0, 255, 0), 5); // groen Led_Brightness = analoog(analogPinBrightness); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); rainbowFade2White(1, 1, 1); Led_Brightness = analoog(analogPinBrightness); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); Serie.println("Init voltooid. Virtuele nulregels:"); Serie.afdrukken("Links : "); Serie.println(Base_Left); Serie.afdrukken("Rechtsaf: "); Serie.println(Base_Right); } nietig lus() { Left_VU_Meter(LED_COUNT / 2, GlobalSensivity); Right_VU_Meter(LED_COUNT / 2, GlobalSensivity); Read_External_Parameters(); strip.tonen(); // Update strip om overeen te komen } nietig Read_External_Parameters() { Led_Brightness = 0; Led_Brightness = analoog(analogPinBrightness); Led_Brightness += analoog(analogPinBrightness); Led_Brightness = Led_Brightness / 2; als ((buikspieren(Led_Brightness - Led_Brightness_old) > Led_Brightness_Deviation)) { Led_Brightness_old = Led_Brightness; // Serial.print ("Nieuwe LED-helderheid:"); // Serial.println (kaart (Led_Brightness, 0, 1023, 1, 255)); strip.set Helderheid(kaart(Led_Brightness, 0, 1023, 1, 255)); // Stel HELDERHEID in volgens Potentiometer strip.tonen(); } VU_Sensivity = 0; VU_Sensivity = analoog(analogPinSensivity); VU_Sensivity += analoog(analogPinSensivity); VU_Sensivity = VU_Sensivity / 2; als ((buikspieren( VU_Sensivity - VU_Sensivity_old) > VU_Sensivity_Deviation)) { VU_Sensivity_old = VU_Sensivity; GlobalSensivity = kaart(VU_Sensivity, 0, 1023, 30, 512); // Serial.print ("Nieuwe VU-gevoeligheid:"); // Serial.println (GlobalSensivity); } } nietig Left_VU_Meter(byte Level_Max_Pixels, int gevoeligheid) { int val_left = 0; dwaas Overbelasten = fout; uint32_t rgbcolor; uint32_t tint; int De signaalsterkte = 0; byte VU_Led_Level = 0; val_left = analoog(analogPinLeft); // lees de invoerpen val_left += analoog(analogPinLeft); // lees de invoerpen val_left += analoog(analogPinLeft); // lees de invoerpen val_left += analoog(analogPinLeft); // lees de invoerpen val_left = val_left / 4; als (!(buikspieren(val_left - val_left_old) > Left_Channel_Deviation)) { val_left = val_left_old; } als (val_left < val_left_old) { leftDropTime++; als (leftDropTime > dropDelay) { val_left = val_left_old * dropFactor; leftDropTime = 0; } anders { val_left = val_left_old; } } val_left_old = val_left; De signaalsterkte = val_left - Base_Left; als (De signaalsterkte < 0) { De signaalsterkte = - De signaalsterkte; } VU_Led_Level = kaart(De signaalsterkte, 0, gevoeligheid , 0, Level_Max_Pixels); als (VU_Led_Level > Level_Max_Pixels) { Overbelasten = waar; VU_Led_Level = Level_Max_Pixels; } anders { Overbelasten = fout; } voor (int ik = 0; ik < Level_Max_Pixels; ik++) { strip.setPixelColor(ik, 0, 0, 0); // Kleur van pixel wissen (in RAM) } voor (int ik = 0; ik < VU_Led_Level; ik++) { // Voor elke pixel in strip ... tint = kaart(ik, Level_Max_Pixels - 1, 0, 0, 21800); als (Overbelasten) { rgbcolor = strip.Kleur(255, 0, 0); // Tint naar RGB-conversatie } anders { rgbcolor = strip.ColorHSV(tint, 255, LedRun_Brightness); } strip.setPixelColor(ik, rgbcolor); // Stel de kleur van de pixel in (in RAM) } } nietig kleur Veeg(uint32_t kleur, int wacht) { voor (int ik = 0; ik < strip.aantalPixels(); ik++) { // Voor elke pixel in strip ... strip.setPixelColor(ik, kleur); // Stel de kleur van de pixel in (in RAM) strip.tonen(); // Update strip om overeen te komen vertraging(wacht); // Even pauzeren } } nietig Right_VU_Meter(byte Level_Max_Pixels, int gevoeligheid) { int val_right = 0; dwaas Overbelasten = fout; uint32_t rgbcolor; uint32_t tint; int De signaalsterkte = 0; byte VU_Led_Level = 0; val_right = analoog(analogPinRight); // lees de invoerpen val_right += analoog(analogPinRight); // lees de invoerpen val_right += analoog(analogPinRight); // lees de invoerpen val_right += analoog(analogPinRight); // lees de invoerpen val_right = val_right / 4; als (!(buikspieren(val_right - val_right_old) > Right_Channel_Deviation)) { val_right = val_right_old; } als (val_right < val_right_old) { rightDropTime++; als (rightDropTime > dropDelay) { val_right = val_right_old * dropFactor; rightDropTime = 0; } anders { val_right = val_right_old; } } val_right_old = val_right; De signaalsterkte = val_right - Base_Right; als (De signaalsterkte < 0) { De signaalsterkte = - De signaalsterkte; } VU_Led_Level = kaart(De signaalsterkte, 0, gevoeligheid , 0, Level_Max_Pixels); als (VU_Led_Level > Level_Max_Pixels) { Overbelasten = waar; VU_Led_Level = Level_Max_Pixels; } anders { Overbelasten = fout; } int ColorVector = 0; voor (int ik = LED_COUNT - Level_Max_Pixels; ik < LED_COUNT; ik++) { strip.setPixelColor(ik, 0, 0, 0); // Kleur van pixel wissen (in RAM) } int StartVector = LED_COUNT - VU_Led_Level; voor (int ik = LED_COUNT - Level_Max_Pixels; ik < LED_COUNT; ik++) { // Voor elke pixel in strip ... tint = kaart(ColorVector, Level_Max_Pixels - 1, 0, 21800, 0); ColorVector++; als ( ik >= StartVector) { als (Overbelasten) { rgbcolor = strip.Kleur(255, 0, 0); // Tint naar RGB-conversatie } anders { rgbcolor = strip.ColorHSV(tint, 255, LedRun_Brightness); } strip.setPixelColor(ik, rgbcolor); // Stel de kleur van de pixel in (in RAM) } } } nietig rainbowFade2White(int wacht, int regenboogLoops, int whiteLoops) { int fadeVal = 0, fadeMax = 100; // Tint van eerste pixel voert volledige 'loops' van de regenboog door de kleur // wiel. Kleurenwiel heeft een bereik van 65536, maar het is OK als we omrollen, dus // tel gewoon van 0 tot regenboogLoops * 65536, met stappen van 256 dus we // ga met een behoorlijke clip rond het stuur. voor (uint32_t firstPixelHue = 0; firstPixelHue < regenboogLoops * 65536; firstPixelHue += 256) { voor (int ik = 0; ik < strip.aantalPixels(); ik++) { // Voor elke pixel in strip ... // Verschuif pixeltint met een hoeveelheid om een volledige revolutie van de te maken // kleurenwiel (bereik van 65536) over de lengte van de strip // (stappen strip.numPixels ()): uint32_t pixelHue = firstPixelHue + (ik * 65536L / strip.aantalPixels()); // strip.ColorHSV () kan 1 of 3 argumenten aannemen: een tint (0 tot 65535) of // voeg eventueel verzadiging en waarde (helderheid) toe (elk van 0 tot 255). // Hier gebruiken we alleen de variant met drie argumenten, hoewel de // tweede waarde (verzadiging) is een constante 255. strip.setPixelColor(ik, strip.gamma32(strip.ColorHSV(pixelHue, 255, 255 * fadeVal / fadeMax))); } strip.tonen(); vertraging(wacht); als (firstPixelHue < 65536) { // Eerste lus, als (fadeVal < fadeMax) fadeVal++; // vervagen } anders als (firstPixelHue >= ((regenboogLoops - 1) * 65536)) { // Laatste lus, als (fadeVal > 0) fadeVal--; // vervagen } anders { fadeVal = fadeMax; // Tussentijdse lus, zorg ervoor dat fade maximaal is } } voor (int k = 0; k < whiteLoops; k++) { voor (int j = 0; j < 256; j++) { // Ramp omhoog 0 tot 255 // Vul de volledige strip met wit op gamma-gecorrigeerd helderheidsniveau 'j': strip.vullen(strip.Kleur(0, 0, 0, strip.gamma8(j)));
strip.show ();
}
}
}
Die erste Kalibrierung der Empfindlichkeit sollte an den getrennten R / L Grobreglern vorgenommen werden. Es sollte dabei darauf aangenomenet werden, dass der Fein Regler für die Empfindlichkeit auf „Minimum“ eingestellt wird. Weiterhin sollte darauf aangenomenet werden, dass während des Einschaltens des VU Meters und dem Abspielen des Intros die virtuelle Nulllinie eingelesen wird. Damit diese Kalibrierung korrekt ablaufen kann, ist es wichtig, während der Einschaltphase noch kein Audiosignaal 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 Reacties
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!