Hallo en welkom bij het tweede deel van de "disco bril" blog-serie.
In dit deel van uit te breiden als veel van je verwacht, is de functionaliteit van onze bril, maar we zullen ook in dit deel van de opmerkingen in het eerste deel. Ik presenteer u een bijgewerkte schema beschikbaar. Bovendien, ik zal commentaar geven expliciet in op de Details van de bedrading van de WS1812b.
Daarnaast geven we onze Hardware een beetje firmware-upgrade maakt het mogelijk, via een drukknop op de druk op de knop van maximaal 4 verschillende, spannende licht-animaties te selecteren.
Houdt u vast uw Hardware om deze bijgewerkte schema:
Omdat we ook specifiek vragen over de details bedrading van de ringen hebben bereikt, hier, dit onderdeel is vergroot weergegeven:
U kunt zien in de afbeelding, de lijn tussen de ringen "van de grond" is. Dat is verbonden met de microcontroller de uitvoer van de gegevens uit de output D6 op de eerste Ring, de DI (Gegevens in), en vervolgens van deze Ring, op zijn beurt, met Pin te DOEN (Gegevens Uit) naar de tweede Ring aan de DI (Gegevens in) aangesloten. Dit type verbinding is vanwege de manier waarop de seriële data-bus is noodzakelijk.
Nu kunnen we aan de slag om de firmware, upgrade van de auto, en de volgende Code om onze Arduino upload:
#include <Adafruit_NeoPixel.h> #define BUTTON_CHANGEANIMATION 12 // Digitale IO-pin aangesloten op de knop. Dit zal worden // gereden met een pull-up weerstand, zodat de schakelaar // trek de pin op de grond rusten. Op een hoog -> laag // overgang op de knop drukt, logica zal uitvoeren. #definiëren PIXEL_PIN 6 // Digitale IO-pin aangesloten op de NeoPixels. #definiëren PIXEL_COUNT 24 // Alle Pixel op de Strip #define MaxAninmationsAvail 4 Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_RGB + NEO_KHZ800); const int hueRedLow = 0; const int hueRedHigh = 255; const int hueBlue = 170; const int angleMin = 0; const int hoek sector = 60; const int angleMax = 360; const int brightMin = 0; const int brightMax = 255; byte tint,, helderheid,; // De verzadiging is vastgesteld op 255 (volledig) verwijderen van niet-door middel van verschillende // kleuren. // Het kan worden gekoppeld aan een andere potentiometer als een demonstratie van hue // gewenst is. byte verzadiging = 255; // interrut Controle bool A60telSecInterruptOccured = ware; byte A60telSeconds24 = 0; byte A4telSeconds24 = 0; // Timer Variabele int timer seconden = 0; // teller int timer alarmset = 15; // 15 seconden Timer bool timer start vlag vlag = op false; bool timer stoppen = true,; //Handmatige Handelingen bool ButtonAPress = false; //Intenal LED-lichteffecten en een LED (13) byte LedMode = 2; //animation control int moet animatie = 0; int IsAnimation = 0; int oldlight grens = 0; bool GetONOFFStatus = valse; bool OLDONOFFStatus = valse; bool spelen de Intro = op false,; //afspelen van de Intro bool spelen outro = false,; //play het Einde bool wijzigen animatie = false,; bool RunOnce = true; // Voor Off Amation - Anmation 0 //universal variabele byte a, c, d, e, f; unsigned int r, g, b; //de Interrupt Routines ISR(TIMER1_COMPA_vect) { bool LEDChange, PressedZ; //Schakelaar de query PressedZ = digitale lezen(BUTTON_CHANGEANIMATION); als ((PressedZ == LAGE) en (ButtonAPress == valse)) { ButtonAPress = ware; } TCNT1 = 0; // Registreer met 0 initialiseren } //de Interrupts aan het eind // begin Programma void setup() { strip.beginnen(); strip.show(); // Initialiseer alle pixels in op "uit" pinMode(BUTTON_CHANGEANIMATION, INPUT_PULLUP); randomSeed(analogRead(0)); noInterrupts(); // Alle Interrupts tijdelijk uit TCCR1A = 0x00; TCCR1B = te 0x02; TCNT1 = 0; // Registreer met 0 initialiseren OCR1A = 33353; // Output-Compare Register en pre - TIMSK1 |= (1 << OCIE1A); // Timer Compare Interrupt enable interrupts(); // alle Interrupts bewapenen Seriële.beginnen(9600); Seriële.flush(); } //Helper functies void HSBToRGB( unsigned int inHue, , unsigned int inSaturation, , unsigned int inBrightness, , unsigned int *of, unsigned int *oG, unsigned int *oB ) { als (inSaturation == 0) { // achromatische (grijs) *of = *oG = *oB = inBrightness; } anders { unsigned int scaledHue = (inHue * 6); unsigned int sector = scaledHue >> 8; // sector 0 tot en met 5 van de kleurenschijf unsigned int offsetInSector = scaledHue - (sector << 8); // positie binnen de sector unsigned int p = (inBrightness * ( 255 - inSaturation )) >> 8; unsigned int q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8; unsigned int t = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8; schakelaar ( sector ) { geval 0: *of = inBrightness; *oG = t; *oB = p; breken; geval 1: *of = q; *oG = inBrightness; *oB = p; breken; geval 2: *of = p; *oG = inBrightness; *oB = t; breken; geval 3: *of = p; *oG = q; *oB = inBrightness; breken; geval 4: *of = t; *oG = p; *oB = inBrightness; breken; default: // case 5: *of = inBrightness; *oG = p; *oB = q; breken; } } } void CheckConfigButtons () // InterruptRoutine { bool PressedZ; als (ButtonAPress == ware) { als (ShouldAnimation < MaxAninmationsAvail ) { ShouldAnimation++; Seriële.println ("fase1"); Seriële.println (ShouldAnimation); //ShouldAnimation = 1; } anders { ShouldAnimation = 0; } vertraging(700); ButtonAPress = valse; } } void AnimationControl () { int GetSelAnimation = 0; als (GetONOFFStatus != OLDONOFFStatus) { OLDONOFFStatus = GetONOFFStatus; als (GetONOFFStatus) { ShouldAnimation = 1; } anders { ShouldAnimation = 0; } } } // Main Loop ----------------------------------------------------------------------- void loop() { AnimationControl(); RunAnimations(); CheckConfigButtons(); } // Main Loop ----------------------------------------------------------------------- Ende //intro ' s void Intro_CountUp (byte r, byte g, byte b, int delaytime, bool dir) { als (dir) { voor ( int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(i, r, g, b); //Calulate RGB-Waarden voor Pixel strip.show(); // Toon resultaten :) vertraging(delaytime); } } anders { voor ( int i = 0; i < strip.numPixels() + 1; ik++) { byte pos = strip.numPixels() - ik; strip.setPixelColor(pos, r, g, b); //Calulate RGB-Waarden voor Pixel strip.show(); // Toon resultaten :) vertraging(delaytime); } } } void Intro_RaiseRainbow(bool risefall) { helderheid = 255; int Rainbowcolor = 0; als (risefall) { voor (int i = 0; i < strip.numPixels(); ik++) { hue = kaart(ik + Rainbowcolor, angleMin, 60, hueRedLow, hueRedHigh); //Set Kleur HSBToRGB(tint, verzadiging, helderheid, &r, &g, &b); //Set Kleur strip.setPixelColor(i, r, g, b); //Calulate RGB-Waarden voor Pixel strip.show(); delay(40); } } anders { voor (int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(ik, 0, 0, 0); strip.show(); delay(40); } } } //Outtros //Animaties void Ani_AllOff () { voor ( int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(ik, 0, 0, 0); // alle off } - strip.show(); } void Ani_AllOn (byte r, byte g, byte b) { voor ( int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(i, r, g, b); // alle op de } strip.show(); } void Ani_Starshower () { int array[10] ; for ( int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(ik, 0, 0, 15); // alle blauw basis } voor (int i = 0; i < 10; i++) { int geselecteerde = willekeurige(strip.numPixels()); strip.setPixelColor(geselecteerd, 255, 255, 255); // Witte } strip.show(); vertraging(100); voor ( int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(ik, 0, 0, 15); // alle blauwe gebaseerd } strip.show(); vertraging(500); } void Ani_Rainbow(byte delaytime) { helderheid = 100; int Rainbowcolor = 0; doen { voor (int i = 0; i < strip.numPixels(); ik++) { hue = kaart(ik + Rainbowcolor, angleMin, 60, hueRedLow, hueRedHigh); HSBToRGB(tint, verzadiging, helderheid, &r, &g, &b); strip.setPixelColor(i, r, g, b); } strip.show(); // Toon resultaten :) vertraging(delaytime); Rainbowcolor++ ; } terwijl (Rainbowcolor < 61); } void Ani_Two_Color () { //byte Segmenten = PIXEL_COUNT / 5; byte Divider = willekeurige (1, 10); bool kleur,; int x = 1; b = 0; voor (int s = 0; s > -1; s = s + x) { kleur = false; voor ( int i = 0; i < strip.numPixels(); ik++) { een = ik / Divider; als (!(een == b)) { b = een; kleur = !kleur; } als (de kleur) { van de strook.setPixelColor(i, 0, s, 0); //grün } als (!(de kleur)) { van de strook.setPixelColor(i, s, 0, 0); //rot } } strip.show(); als (s == 255) { x = -1; vertraging(2000); } vertraging(10); } strip.show(); } void Ani_Halloween() { een = -10; voor (int i = 0; i < strip.numPixels(); ik++) { strip.setPixelColor(ik, willekeurige(1, 254), willekeurige(1, 204), willekeurige(1, 254)); e = e + a; f = f + a; als (f <= 0) { een = +10; } als (f >= 60) { een = -10; } } strip.show(); // Toon resultaten :) vertraging(300); } void FadeColor () { byte helderheid = 0; byte verzadiging = 0; int Colori = 49 ; doen { voor (int i = 0; i < strip.numPixels(); ik++) { // wdt_reset(); HSBToRGB(Colori, verzadiging, helderheid, &r, &g, &b); //Set Kleur strip.setPixelColor(i, r, g, b); //Calulate RGB-Waarden voor Pixel - } helderheid ++; strip.show(); // Toon resultaten :) vertraging(40); } tijdens (helderheid < 50); } void RunAnimations() { als (!(ShouldAnimation == IsAnimation)) { PlayOutro = ware; ChangeAnimation = true; } switch (IsAnimation) { geval 0: // alle LedsOFF als (PlayIntro) { PlayIntro = valse; RunOnce = ware; } als ((!(PlayIntro)) && (!(PlayOutro))) { als (RunOnce) { Ani_AllOff (); } RunOnce = false; } als (PlayOutro) { PlayOutro = valse; PlayIntro = ware; RunOnce = ware; IsAnimation = ShouldAnimation; } breken; geval 1: als (PlayIntro) { Intro_CountUp (0, 0, 15, 100, ware); PlayIntro = false; } als ((!(PlayIntro)) && (!(PlayOutro))) { Ani_Starshower(); } als (PlayOutro) { Intro_CountUp (0, 0, 0, 100, valse); PlayOutro = valse; PlayIntro = ware; IsAnimation = ShouldAnimation; } breken; geval 2: als (PlayIntro) { Intro_RaiseRainbow(ware); PlayIntro = false; } als ((!(PlayIntro)) && (!(PlayOutro))) { Ani_Rainbow(20); } als (PlayOutro) { Intro_RaiseRainbow(valse); PlayOutro = valse; PlayIntro = ware; IsAnimation = ShouldAnimation; } breken; geval 3: als (PlayIntro) { Ani_AllOff (); PlayIntro = false; } als ((!(PlayIntro)) && (!(PlayOutro))) { Ani_Two_Color (); // Ani_Two_Color (byte tint,byte staart,byte helderheid,byte delaytime) } als (PlayOutro) { PlayOutro = valse; PlayIntro = ware; IsAnimation = ShouldAnimation; } breken; geval 4: als (PlayIntro) { Ani_AllOff (); PlayIntro = false; } als ((!(PlayIntro)) && (!(PlayOutro))) { Ani_Halloween (); // } als (PlayOutro) { PlayOutro = valse; PlayIntro = ware; IsAnimation = ShouldAnimation; } breken; } }
Funktionsweise: Durch kurzen Druck auf den Voorproefje können jetzt folgende Animationen nacheinander aufgerufen werden. Ein
- Starshower
- Regenboog
- Beweging van Twee Kleuren
- Halloween
Bitte beachtet, dass die Animationen nicht sofort auf die nächste Animatie umschalten, sondern immer erst sterven aktuelle Sequenz beenden, bevor die nächste Animatie gestartet werden.
Auch hier seid ihr natürlich herzlich eingeladen, weitere Animationssequenzen zu programmieren, valt euch sterven 4 nicht ausreichen sollten. Sterven prinzipielle Vorgehensweise dazu ist aus dem Code ersichtlich.
Im nächsten und letzten Teil der Reihe werden wir unsere Brille auf "Umweltreize" reagieren lassen.
Ich wünsche viel Spaß beim Nachbauen und bis zum nächsten mal.
2 Reacties
Andreas Wolter
@Sebastian: zu Beginn des Codes wird mit der Zeile
#define PIXEL_COUNT 24
die Anzahl aller Pixel festgelegt (hier zwei Ringe je 12 Pixel, also 24). Diese Konstante wird dann später verwendet, wenn das Neopixelsobjekt instanziiert wird.
Wenn Sie fünf Ringe verwenden, müssten Sie dort statt 24 dann 5x 12 = 60 eintragen. Dann sollte überall dort, wo mit der for-Schleife bis strip.numPixels() gezählt wird, jeder der Neopixel angesprochen werden.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Sebastian
Hi,
ich möchte 5 von der 38mm Ringen nutzen. Wo genau muss ich denn die Anzahl der Ringe einstellen?