Mehrere „Programme“ für unsere Discobrille mit den WS2812b RGB LED Ring - AZ-Delivery

Ciao, e caldamente sia il benvenuto nella seconda parte di «fila di blog» di occhiali di discoteca.

In questa parte si estendono come già da molti di Lei aspetta, le funzionalità dei nostri occhiali, ma anche ci troveremo in questa parte su commenti dalla prima parte. Dunque, Le rendo disponibile un piano d'impianto elettrico aggiornato. Inoltre verrò esplicitamente a dettagli dell'impianto elettrico del WS1812b.
Inoltre, diamo al nostro hardware a piccolo Firmwareupgrade che permette per scegliere su una battuta sul proiettile tracciante da fino a 4 animazioni luminose diverse, emozionanti.

Per favore, i Suoi fili di hardware dopo questo aggiornato telegrafando il piano:

Occhiali di discoteca - piano di Fritzing

Perché a noi anche particolarmente le domande si sono estese all'impianto elettrico dettagliato degli anelli, qui qualche volta particolarmente questa parte enlargedly mostrato:

Occhiali di discoteca - Fritzing - dettaglio

 

Uno vede nel quadro che diventa la linea di dati tra gli anelli «durchgeschliffen». Cioè l'uscita di uscita di dati D6 sul primo squillo formerà un'alleanza dal microcontrollore dopo TU (I dati in) e formerà un'alleanza allora da questo anello di nuovo dallo Spillo TH (i Dati Fuori) al secondo squillo dopo TU (I dati in). Questo genere di collegamento è necessario per via della funzionalità dell'allenatore di dati seriale.


Adesso possiamo avventurarci in Firmwareupgrade e il codice seguente secondo il nostro deposito di alto livello di Arduino:

 

 

#include <Adafruit_NeoPixel.H>

#define BUTTON_CHANGEANIMATION  12    //Digitalmente lo spillo di IO si è connesso al distintivo. Questo vuole Essere
//guidato con un resistore di tirata su così l'interruttore debba
//trasporti lo spillo in barca per basarsi per un attimo. Su un alto -> in basso
//la transizione che la logica di stampa di distintivo vuole esegue.
#define PIXEL_PIN    6    //Digitalmente lo spillo di IO si è connesso al neopixel.
#define PIXEL_COUNT 24   //Di tutto il pixel su Striscia
#define MaxAninmationsAvail 4

Adafruit_NeoPixel striscia = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_RGB + NEO_KHZ800);

può intervallo hueRedLow = 0;
può intervallo hueRedHigh = 255;
può intervallo hueBlue = 170;
può intervallo angleMin = 0;
può intervallo angleSector = 60;
può intervallo angleMax = 360;
può intervallo brightMin = 0;
può intervallo brightMax = 255;

byte perbacco su, splendore;
//La saturazione è fissata A 255 (si riempiono) per togliere blead-attraverso di diversi
//colori.
//Poteva Esser collegato a di altro potentiometers se una dimostrazione di perbacco su
//è desiderato.
byte saturazione = 255;

//Controllo d'intersolco
bool A60telSecInterruptOccured = vero;
byte A60telSeconds24 = 0;
byte A4telSeconds24 = 0;

//Contaminuti di variabile
intervallo TimerSeconds = 0;  //Banco
intervallo Serie di allarme di contaminuti = 15; //15 secondi di contaminuti
bool TimerStartFlagFlag = falso;
bool Cima di contaminuti = vero;

//Operazioni manuali
bool ButtonAPress  = falso;

//Intenal ha CONDOTTO LightEffects (ha CONDOTTO 13)
byte LedMode = 2;

//AnimationControl
intervallo ShouldAnimation  = 0;
intervallo IsAnimation  = 0;
intervallo OLDLightBorder = 0;
bool GetONOFFStatus = falso;

bool OLDONOFFStatus = falso;
bool PlayIntro = falso; //Introduzione di giochi
bool PlayOutro = falso; //Giochi Outro
bool ChangeAnimation = falso;
bool RunOnce = vero;  //Per Auschalt Amation - Anmation 0

//universalmente la variabile
byte a, C, d, e, e il seguente;
non firmato intervallo r, g, B;

//Ordinarie amministrazioni d'interruzione

ISR(TIMER1_COMPA_vect)
{   bool LEDChange, PressedZ;   //Domanda d'interruttore   PressedZ = digitalRead(BUTTON_CHANGEANIMATION);   se ((PressedZ == IN BASSO) e (ButtonAPress == falso))   {     ButtonAPress = vero;   }   TCNT1 = 0;      //I registri con 0 inizializzano
}

//Fini di interruzioni
//cominci il programma

vuoto situazione()
{   striscia.cominciare();   striscia.mostrare();   //Inizializzi di tutto il pixel a 'di vista'   pinMode(BUTTON_CHANGEANIMATION, INPUT_PULLUP);   randomSeed(analogRead(0));   noInterrupts(); //Tutte le Interruzioni spengono temporaneamente   TCCR1A = 0x00;   TCCR1B =  0x02;   TCNT1 = 0;      Registrare mit 0 initialisieren   OCR1A =  33353;      Output Compare Register vorbelegen   TIMSK1 |= (1 << CIE1A);  Timer Confronta Interrupt aktivieren   Interrompe();   alle Interrupts scharf schalten   Seriale.Iniziare(9600);   Seriale.sciacquone();
}


Hilfsfunktionen


Vuoto HSBToRGB(   Unsigned Int inHue, Unsigned Int inSaturazione, Unsigned Int inLuminosità,   Unsigned Int *O, Unsigned Int *Og, Unsigned Int *Ob )
{   Se (inSaturazione == 0)   {     acromatico (grigio)     *O = *Og = *Ob = inLuminosità;   }   Altro   {     Unsigned Int scaledHue = (inHue * 6);     Unsigned Int Settore = scaledHue >> 8; settore da 0 a 5 intorno alla ruota dei colori     Unsigned Int offsetInSector = scaledHue - (Settore << 8);  posizione all'interno del settore     Unsigned Int P = (inLuminosità * ( 255 - inSaturazione )) >> 8;     Unsigned Int D = (inLuminosità * ( 255 - ((inSaturazione * offsetInSector) >> 8) )) >> 8;     Unsigned Int T = (inLuminosità * ( 255 - ((inSaturazione * ( 255 - offsetInSector )) >> 8) )) >> 8;     Interruttore ( Settore ) {       Caso 0:         *O = inLuminosità;         *Og = T;         *Ob = P;         Pausa;       Caso 1:         *O = D;         *Og = inLuminosità;         *Ob = P;         Pausa;       Caso 2:         *O = P;         *Og = inLuminosità;         *Ob = T;         Pausa;       Caso 3:         *O = P;         *Og = D;         *Ob = inLuminosità;         Pausa;       Caso 4:         *O = T;         *Og = P;         *Ob = inLuminosità;         Pausa;       Predefinito:    caso 5:         *O = inLuminosità;         *Og = P;         *Ob = D;         Pausa;     }   }
}

Vuoto CheckConfigButtons ()    InterruptRoutine
{   Bool Premuto;   Se (ButtonAPress == Vero)   {     Se (ShouldAnimation < MaxAninmationsAvail )     {       ShouldAnimation++;       Seriale.println ("fase1");       Seriale.println (ShouldAnimation);       ShouldAnimation : 1;     } Altro     {       ShouldAnimation = 0;     }     Ritardo(700);     ButtonAPress = False;   }
}

Vuoto AnimazioneControllo ()
{   Int GetSelAnimation = 0;   Se (GetONOFFStatus (Stato) GetONOFF != OLDONOFFStatus)   {     OLDONOFFStatus = GetONOFFStatus (Stato) GetONOFF;     Se (GetONOFFStatus (Stato) GetONOFF)     {       ShouldAnimation = 1;     } Altro     {       ShouldAnimation = 0;     }   }
}

----------------------------------------------------------------------- loop principale

Vuoto Ciclo()
{   AnimazioneControllo();   Animazioni RunAnimations();   CheckConfigButtons();
}
Loop principale ----------------------------------------------------------------------- Ende
Intros

Vuoto Intro_CountUp (byte R, byte G, byte B, Int tempo di ritardo, Bool Dir)
{   Se (Dir)   {     Per ( Int Ho = 0; Ho < Striscia.numPixel(); Ho++)     {       Striscia.setPixelColor(Ho, R, G, B);    Calulate Valori RGB per Pixel       Striscia.Visualizza();   Mostra :) risultati       Ritardo(tempo di ritardo);     }   } Altro   {     Per ( Int Ho = 0; Ho < Striscia.numPixel() + 1; Ho++)     {       byte Pos = Striscia.numPixel() - Ho;       Striscia.setPixelColor(Pos, R, G, B);    Calulate Valori RGB per Pixel       Striscia.Visualizza();   Mostra :) risultati       Ritardo(tempo di ritardo);     }   }
}


Vuoto Intro_RaiseRainbow(Bool risefall)
{   Luminosità = 255;   Int Colore arcobaleno = 0;   Se (risefall)   {     Per (Int Ho = 0; Ho < Striscia.numPixel(); Ho++)     {       Hue = Mappa(Ho + Colore arcobaleno, angleMin, 60, tonalitàRedLow, hueRedHigh); Imposta colore       HSBToRGB(Hue, Saturazione, Luminosità, &R, &G, &B); Imposta colore       Striscia.setPixelColor(Ho, R, G, B);     Calulate Valori RGB per Pixel       Striscia.Visualizza();       Ritardo(40);     }   } Altro   {     Per (Int Ho = 0; Ho < Striscia.numPixel(); Ho++)     {       Striscia.setPixelColor(Ho, 0, 0, 0);       Striscia.Visualizza();       Ritardo(40);     }   }
}


Outtro



Animazioni

Vuoto Ani_AllOff ()
{   Per ( Int Ho = 0; Ho < Striscia.numPixel(); Ho++)   {     Striscia.setPixelColor(Ho, 0, 0, 0);     tutto fuori   }   Striscia.Visualizza();
}


Vuoto Ani_AllOn (byte R, byte G, byte B)
{   Per ( Int Ho = 0; Ho < Striscia.numPixel(); Ho++)   {     Striscia.setPixelColor(Ho, R, G, B);     tutto il   }   Striscia.Visualizza();
}

Vuoto Ani_Starshower ()
{   Int Matrice[10] ;   Per ( Int Ho = 0; Ho < Striscia.numPixel(); Ho++)   {     Striscia.setPixelColor(Ho, 0, 0, 15);     tutti a base blu   }   Per (Int Ho = 0; Ho < 10; Ho++)   {     Int Selezionato = Casuale(Striscia.numPixel());     Striscia.setPixelColor(Selezionato, 255, 255, 255); Bianco   }   Striscia.Visualizza();   Ritardo(100);   Per ( Int Ho = 0; Ho < Striscia.numPixel(); Ho++)   {     Striscia.setPixelColor(Ho, 0, 0, 15);     tutti a base blu   }   Striscia.Visualizza();   Ritardo(500);
}

Vuoto Ani_Rainbow(Byte tempo di ritardo)
{   "Io non sono = 100;   Int Colore arcobaleno = 0;   Thu   {     Per (Int Ho. = 0; Ho. < Striscia.numPixel(); Ho.++)     {       Hue = Mappa(Ho. + Colore arcobaleno, angleMin, 60, tonalitàRedLow, hueRedHigh);       HSBToRGB(Hue, Saturazione, "Io non sono, &R, &G, &B);       Striscia.setPixelColor(Ho., R, G, B);     }     Striscia.Visualizza();   Mostra :) risultati     Ritardo(tempo di ritardo);     Colore arcobaleno++ ;   } Mentre (Colore arcobaleno < 61);
}

Vuoto Ani_Two_Color ()
{   segmenti di byte - PIXEL_COUNT / 5;   Byte Divisore = Casuale (1, 10);   Bool Colore;   Int X = 1;   B = 0;   Per (Int S (in vi = 0; S (in vi > -1; S (in vi = S (in vi + X)   {     Colore = False;     Per ( Int Ho. = 0; Ho. < Striscia.numPixel(); Ho.++)     {       Un = Ho. / Divisore;       Se (!(Un == B))       {         B = Un;         Colore = !Colore;       }       Se (Colore) {         Striscia.setPixelColor(Ho., 0, S (in vi, 0);  Verde       }       Se (!(Colore)) {         Striscia.setPixelColor(Ho., S (in vi, 0, 0);  Rosso       }     }     Striscia.Visualizza();     Se (S (in vi == 255)     {       X = -1;       Ritardo(2000);     }     Ritardo(10);   }   Striscia.Visualizza();
}

Vuoto Ani_Halloween()
{   Un = -10;   Per (Int Ho. = 0; Ho. < Striscia.numPixel(); Ho.++)   {     Striscia.setPixelColor(Ho., Casuale(1, 254), Casuale(1, 204), Casuale(1, 254));     E (in questo modo = E (in questo modo + Un;     D = D + Un;     Se (D <= 0)     {       Un = +10;     }     Se (D >= 60)     {       Un = -10;     }   }   Striscia.Visualizza();   Mostra :) risultati   Ritardo(300);
}

Vuoto Colore Dissolvenza ()
{   Byte "Io non sono = 0;   Byte Saturazione = 0;   Int Colori = 49 ;   Thu   {     Per (Int Ho. = 0; Ho. < Striscia.numPixel(); Ho.++)     {       wdt_reset();       HSBToRGB(Colori, Saturazione, "Io non sono, &R, &G, &B); Imposta colore       Striscia.setPixelColor(Ho., R, G, B);     Calulate Valori RGB per Pixel     }     "Io non sono ++;     Striscia.Visualizza();   Mostra :) risultati     Ritardo(40);   } Mentre ("Io non sono < 50);
}

Vuoto Animazioni RunAnimations()
{   Se (!(ShouldAnimation == IsAnimation))   {     PlayOutro = Vero;     ModificaAnimazione = Vero;   }   Interruttore (IsAnimation)   {     Caso 0:                                    tutti i LedOFF       Se (PlayIntro)       {         PlayIntro = False;         Runonce = Vero;       }       Se   ((!(PlayIntro)) &&  (!(PlayOutro)))       {         Se (Runonce) {           Ani_AllOff ();         }         Runonce = False;       }       Se  (PlayOutro)       {         PlayOutro  = False;         PlayIntro = Vero;         Runonce = Vero;         IsAnimation = ShouldAnimation;       }       Pausa;     Caso 1:       Se (PlayIntro)       {         Intro_CountUp (0, 0, 15, 100, Vero);         PlayIntro = False;       }       Se  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Starshower();       }       Se  (PlayOutro)       {         Intro_CountUp (0, 0, 0, 100, False);         PlayOutro  = False;         PlayIntro = Vero;         IsAnimation =  ShouldAnimation;       }       Pausa;     Caso 2:       Se (PlayIntro)       {         Intro_RaiseRainbow(Vero);         PlayIntro = False;       }       Se  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Rainbow(20);       }       Se  (PlayOutro)       {         Intro_RaiseRainbow(False);         PlayOutro  = False;         PlayIntro = Vero;         IsAnimation =  ShouldAnimation;       }       Pausa;     Caso 3:       Se (PlayIntro)       {         Ani_AllOff ();         PlayIntro = False;       }       Se  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Two_Color (); Ani_Two_Color (coda byte,coda byte,luminosità byte,byte delaytime)       }       Se  (PlayOutro)       {         PlayOutro  = False;         PlayIntro = Vero;         IsAnimation =  ShouldAnimation;       }       Pausa;     Caso 4:       Se (PlayIntro)       {         Ani_AllOff ();         PlayIntro = False;       }       Se  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Halloween (); //       }       Se  (PlayOutro)       {         PlayOutro  = False;         PlayIntro = Vero;         IsAnimation =  ShouldAnimation;       }       Pausa;   }
}

 

Come funziona: premendo il pulsante, le seguenti animazioni possono ora essere chiamate una dopo l'altra. Un

  • Doccia stellare
  • arcobaleno
  • Movimento di due colori
  • Halloween


Si noti che le animazioni non passano immediatamente all'animazione successiva, ma terminano sempre la sequenza corrente prima di avviare l'animazione successiva.


Ancora una volta, naturalmente, sei cordialmente invitato a programmare più sequenze di animazione, se il 4 non sono sufficienti per te. La procedura di base per questo può essere visto nel codice.
Nella prossima e ultima parte della serie avremo i nostri occhiali reagire a "stimoli ambientali".


Vi auguro un sacco di divertimento ricostruzione e fino alla prossima volta.

Für arduinoProjekte für anfänger

2 commenti

Andreas Wolter

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

Sebastian

Hi,
ich möchte 5 von der 38mm Ringen nutzen. Wo genau muss ich denn die Anzahl der Ringe einstellen?

Lascia un commento

Tutti i commenti vengono moderati prima della pubblicazione