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

Hola y bienvenidos a la segunda parte de la serie de blogs de "gafas".

En esta parte, como muchos de ustedes esperan, se amplían las funcionalidades de nuestras gafas, pero también en esta parte, comentaremos los comentarios de la primera parte. Por lo tanto, les proporcionaré un plan de cableado actualizado. También me referiré explícitamente a los detalles del cableado de la WS1812b.
Además, estamos donando a nuestro Hardware un pequeño ajuste de imagen del firmware que permite seleccionar hasta cuatro animaciones de luz diferentes y emocionantes a través de una pulsación de tecla en el teclado.

Por favor, cableen su Hardware según este plan de cableado actualizado:

Fritzing Plan

Dado que también hemos recibido preguntas específicas sobre el cableado de detalle de los anillos, esta parte en particular se ha ampliado.:

Detalle De Fritzing De Las Gafas

 

Se puede ver en la imagen que "pule" la línea de datos entre los anillos. Es decir, desde el microcontrolador de la salida de datos D6 se conecta al primer anillo a DI (Data in) y, a continuación, de este anillo a DI (Data in), del Pin DO (Data Out) al segundo anillo. Este tipo de conexión es necesario debido al funcionamiento del bus de datos serie. 


Ahora podemos ir al primer paso del Firmwarpeum y subir el siguiente código a nuestro Arduino.:

 

 

# include <Adafruit_NeoPixel.h>

# define BUTTON_CHANGEANIMACIÓN  12    // Digital IO pin connected to the button.  Esto va a ser
/ driven with a pull-up resistor so the switch should
/ pull the pin to ground momentarily.  On a high - > low
// transition the button press logic will execute.
# define PIXEL_PIN    6    // Digital IO pin connected to the NeoPixels.
# define PIXEL_COUNT 24   // All Pixels on 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 anglemina = 0;
const int angleSector = 60;
const int angleMax = 360;
const int brightMin = 0;
const int brightMax = 255;

bytes hue, brightness;
// The saturation is fixed at 255 (full) to remove blead-through of different
/ colours.
// It could be linked to another potentiómetro if a demonstration of hue
/ desired.
bytes saturation = 255;

// interrut Control
bool A60telSecInterruptOccured = true;
bytes A60telSeconds24 = 0;
bytes A4telSeconds24 = 0;

// Temporizador Variable
int TimerSeconds = 0;  // Numerador
int Equipo de alarma de temporizador = 15; / Temporizador 15 Segundos
bool TimerStartFlagFlag = false;
bool Temporizador = true;

// Manual Operations
bool ButtonAPress  = false;

//Intental LED LightEffects (LED 13))
bytes LedMode = 2;

//AnimationControl
int Animación de inmersión  = 0;
int Isanimación  = 0;
int OLDLightBorder = 0;
bool Estado de getonoff = false;

bool Estado oldonoff = false;
bool PlayIntro = false; // Juegos Introducción
bool PlayOutro = false; // Juego Outro
bool Animación de cambio = false;
bool RunOnce = true;  // Para Selección Desactivada 0

// universal variable variable
bytes a, c, d, e, f;
sin firma int r, g, b;

// Interrupción De Rutina

ISR(TIMER1_COMPA_vect)
{   bool LEDChange, PressedZ;   // Consulta Switch   PressedZ = digitalRead(BUTTON_CHANGEANIMACIÓN);   if ((PressedZ == LOW) and (ButtonAPress == false))   {     ButtonAPress = true;   }   TCNT1 = 0;      // Iniciar la ficha con 0
}

// Interrupción final
// begin Program

void setup()
{   strip.begin();   strip.show();   // Initialize all pixels to 'off'   pinMode(BUTTON_CHANGEANIMACIÓN, INPUT_PULUP);   randomSeed(analogRead(0));   noInterrupts(); // Desactivar temporalmente todos los interruptores   TCCR1A = 0x00;   TCCR1B =  0x02;   TCNT1 = 0;      // Iniciar la ficha con 0   OCR1A =  33353;      // Output Compare Register   TIMSK1 |= (1 << OCIE1A);  // Temporizador Compare interface   interrupts();   // activar todos los interruptores   Serial.begin(9600);   Serial.rubor();
}


// Funciones auxiliares


void HSBToRGB(   sin firma int inHue, sin firma int reclusión, sin firma int inBrightness,   sin firma int *oR, sin firma int *oG, sin firma int *oB )
{   if (reclusión == 0)   {     // acromatic (grey)     *oR = *oG = *oB = inBrightness;   }   else   {     sin firma int scaledHue = (inHue * 6);     sin firma int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel     sin firma int vector offsético = scaledHue - (sector << 8);  // position within the sector     sin firma int p = (inBrightness * ( 255 - reclusión )) >> 8;     sin firma int q = (inBrightness * ( 255 - ((reclusión * vector offsético) >> 8) )) >> 8;     sin firma int t = (inBrightness * ( 255 - ((reclusión * ( 255 - vector offsético )) >> 8) )) >> 8;     switch ( sector ) {       case 0:         *oR = inBrightness;         *oG = t;         *oB = p;         break;       case 1:         *oR = q;         *oG = inBrightness;         *oB = p;         break;       case 2:         *oR = p;         *oG = inBrightness;         *oB = t;         break;       case 3:         *oR = p;         *oG = q;         *oB = inBrightness;         break;       case 4:         *oR = t;         *oG = p;         *oB = inBrightness;         break;       default:    // case 5:         *oR = inBrightness;         *oG = p;         *oB = q;         break;     }   }
}

void CheckConfigButtons ()    // Interruptroutinas
{   bool PressedZ;   if (ButtonAPress == true)   {     if (Animación de inmersión < MaxAninmationsAvail )     {       Animación de inmersión++;       Serial.println ("phase1");       Serial.println (Animación de inmersión);       // Animación = 1;     } else     {       Animación de inmersión = 0;     }     delay(700);     ButtonAPress = false;   }
}

void Control de animación ()
{   int Animación = 0;   if (Estado de getonoff != Estado oldonoff)   {     Estado oldonoff = Estado de getonoff;     if (Estado de getonoff)     {       Animación de inmersión = 1;     } else     {       Animación de inmersión = 0;     }   }
}

// Main Loop  -----------------------------------------------------------------------

void loop()
{   Control de animación();   RunAnimations();   CheckConfigButtons();
}
// Main Loop ----------------------------------------------------------------------- A Finales De
// Introducciones

void Intro_CountUp (bytes r, bytes g, bytes b, int delaytime, bool a ti)
{   if (a ti)   {     for ( int i = 0; i < strip.numPixels(); i++)     {       strip.setPixelColor(i, r, g, b);    //Calulate RGB Values for Pixel       strip.show();   // Show results :)       delay(delaytime);     }   } else   {     for ( int i = 0; i < strip.numPixels() + 1; i++)     {       bytes pos = strip.numPixels() - i;       strip.setPixelColor(pos, r, g, b);    //Calulate RGB Values for Pixel       strip.show();   // Show results :)       delay(delaytime);     }   }
}


void Intro_RaiseRainbow(bool caso de riesgo)
{   brightness = 255;   int Rainbowcolor = 0;   if (caso de riesgo)   {     for (int i = 0; i < strip.numPixels(); i++)     {       hue = mapa(i + Rainbowcolor, anglemina, 60, hueRedLow, hueRedHigh); // Set Color       HSBToRGB(hue, saturation, brightness, &r, &g, &b); // Set Color       strip.setPixelColor(i, r, g, b);     //Calulate RGB Values for Pixel       strip.show();       delay(40);     }   } else   {     for (int i = 0; i < strip.numPixels(); i++)     {       strip.setPixelColor(i, 0, 0, 0);       strip.show();       delay(40);     }   }
}


// Outtros



// Animations

void Ani_AllOff ()
{   for ( int i = 0; i < strip.numPixels(); i++)   {     strip.setPixelColor(i, 0, 0, 0);     // all off   }   strip.show();
}


void Ani_AllOn (bytes r, bytes g, bytes b)
{   for ( int i = 0; i < strip.numPixels(); i++)   {     strip.setPixelColor(i, r, g, b);     // all on   }   strip.show();
}

void Ani_Starshower ()
{   int array[10] ;   for ( int i = 0; i < strip.numPixels(); i++)   {     strip.setPixelColor(i, 0, 0, 15);     // all blue based   }   for (int i = 0; i < 10; i++)   {     int selected = random(strip.numPixels());     strip.setPixelColor(selected, 255, 255, 255); // White   }   strip.show();   delay(100);   for ( int i = 0; i < strip.numPixels(); i++)   {     strip.setPixelColor(i, 0, 0, 15);     // all blue based   }   strip.show();   delay(500);
}

void Ani_Rainbow(bytes delaytime)
{   brightness = 100;   int Rainbowcolor = 0;   do   {     for (int i = 0; i < strip.numPixels(); i++)     {       hue = mapa(i + Rainbowcolor, anglemina, 60, hueRedLow, hueRedHigh);       HSBToRGB(hue, saturation, brightness, &r, &g, &b);       strip.setPixelColor(i, r, g, b);     }     strip.show();   // Show results :)     delay(delaytime);     Rainbowcolor++ ;   } while (Rainbowcolor < 61);
}

void Ani_Two_Color ()
{   // byte Segments = PIXEL_COUNT / 5;   bytes Divider = random (1, 10);   bool color;   int x = 1;   b = 0;   for (int s = 0; s > -1; s = s + x)   {     color = false;     for ( int i = 0; i < strip.numPixels(); i++)     {       a = i / Divider;       if (!(a == b))       {         b = a;         color = !color;       }       if (color) {         strip.setPixelColor(i, 0, s, 0);  // Verde       }       if (!(color)) {         strip.setPixelColor(i, s, 0, 0);  // rojo       }     }     strip.show();     if (s == 255)     {       x = -1;       delay(2000);     }     delay(10);   }   strip.show();
}

void Ani_Halloween()
{   a = -10;   for (int i = 0; i < strip.numPixels(); i++)   {     strip.setPixelColor(i, random(1, 254), random(1, 204), random(1, 254));     e = e + a;     f = f + a;     if (f <= 0)     {       a = +10;     }     if (f >= 60)     {       a = -10;     }   }   strip.show();   // Show results :)   delay(300);
}

void FadeColor ()
{   bytes brightness = 0;   bytes saturation = 0;   int Colori = 49 ;   do   {     for (int i = 0; i < strip.numPixels(); i++)     {       // wdt_reset();       HSBToRGB(Colori, saturation, brightness, &r, &g, &b); // Set Color       strip.setPixelColor(i, r, g, b);     //Calulate RGB Values for Pixel     }     brightness ++;     strip.show();   // Show results :)     delay(40);   } while (brightness < 50);
}

void RunAnimations()
{   if (!(Animación de inmersión == Isanimación))   {     PlayOutro = true;     Animación de cambio = true;   }   switch (Isanimación)   {     case 0:                                    // all LedsOFF       if (PlayIntro)       {         PlayIntro = false;         RunOnce = true;       }       if   ((!(PlayIntro)) &&  (!(PlayOutro)))       {         if (RunOnce) {           Ani_AllOff ();         }         RunOnce = false;       }       if  (PlayOutro)       {         PlayOutro  = false;         PlayIntro = true;         RunOnce = true;         Isanimación = Animación de inmersión;       }       break;     case 1:       if (PlayIntro)       {         Intro_CountUp (0, 0, 15, 100, true);         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Starshower();       }       if  (PlayOutro)       {         Intro_CountUp (0, 0, 0, 100, false);         PlayOutro  = false;         PlayIntro = true;         Isanimación =  Animación de inmersión;       }       break;     case 2:       if (PlayIntro)       {         Intro_RaiseRainbow(true);         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Rainbow(20);       }       if  (PlayOutro)       {         Intro_RaiseRainbow(false);         PlayOutro  = false;         PlayIntro = true;         Isanimación =  Animación de inmersión;       }       break;     case 3:       if (PlayIntro)       {         Ani_AllOff ();         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Two_Color (); // Ani_Two_Color (byte hue, byte tail, byte brightness,byte delaytime)       }       if  (PlayOutro)       {         PlayOutro  = false;         PlayIntro = true;         Isanimación =  Animación de inmersión;       }       break;     case 4:       if (PlayIntro)       {         Ani_AllOff ();         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Halloween (); //       }       if  (PlayOutro)       {         PlayOutro  = false;         PlayIntro = true;         Isanimación =  Animación de inmersión;       }       break;   }
}

 

Funcionamiento: mediante una breve presión en el teclado se pueden activar las siguientes animaciones una tras otra. Un

  • Starshower
  • Rainbow
  • Motion of Two color
  • Halloween


Tenga en cuenta que las animaciones no pasan inmediatamente a la siguiente animación, sino que siempre terminan la secuencia actual antes de iniciar la siguiente animación.


También en este caso, por supuesto, están invitados a programar más secuencias de animación en caso de que los cuatro no sean suficientes. El código indica el enfoque de principio.
En la siguiente y última parte de la serie, haremos que nuestros lentes reaccionen a los "estímulos ambientales".


Que te diviertas reconstruyendo y hasta la próxima vez.

Für arduinoProjekte für anfänger

2 comentarios

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?

Deja un comentario

Todos los comentarios son moderados antes de ser publicados