Several "programmes" for our disco glasses with the ring WS2812b RGB LED

Hello, and warmly welcome to the second part of the "disco glasses" blog row.

In this part extend like already from many of you expects, the functionalities of our glasses, but we will also come in this part on comments from the first part. Hence, I make available to you an updated wiring plan. Besides I will come explicitly on details of the wiring of the WS1812b.
In addition, we give to our hardware to a small Firmwareupgrade which enables to select about a keystroke on the tracer from up to 4 different, exciting luminous animations.

Please, your hardware wires after this updated wiring plan:

Disco glasses - Fritzing plan

Because to us also especially questions have reached to the detailed wiring of the rings, here sometimes especially this part enlargedly shown:

Disco glasses - Fritzing - detail

 

One sees in the picture which becomes the data line between the rings "durchgeschliffen". I.e. the data exit exit D6 on the first ring will form an alliance from the microcontroller after TU (Data in), and form an alliance then from this ring again from the Pin TH (Data Out) to the second ring after TU (Data in). This connecting kind is necessary on account of the functionality of the serial data coach.


Now we can venture on the Firmwareupgrade, and the following code on our Arduino high-level store:

 

 

#include <Adafruit_NeoPixel.H>

#define BUTTON_CHANGEANIMATION  12    //Digitally IO pin connected to the badge. This wants Be
//driven with a pull-up resistor thus the switch should
//row the pin to ground momentarily. On a high -> low
//transition the badge press logic wants execute.
#define PIXEL_PIN    6    //Digitally IO pin connected to the neopixel.
#define PIXEL_COUNT 24   //Of all pixel 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 angleMin = 0;
const int angleSector = 60;
const int angleMax = 360;
const int brightMin = 0;
const int brightMax = 255;

byte gee up, brightness;
//The saturation is fixed At 255 (fill) to remove blead-through of different
//colours.
//It could Be linked to of another potentiometers if a demonstration of gee up
//is desired.
byte saturation = 255;

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

//Timer of variable
int TimerSeconds = 0;  //Counter
int Timer alarm set = 15; //15 seconds of timer
bool TimerStartFlagFlag = false;
bool Timer top = true;

//Manual Operations
bool ButtonAPress  = false;

//Intenal LED LightEffects (LED 13)
byte LedMode = 2;

//AnimationControl
int ShouldAnimation  = 0;
int IsAnimation  = 0;
int OLDLightBorder = 0;
bool GetONOFFStatus = false;

bool OLDONOFFStatus = false;
bool PlayIntro = false; //Spiele Intro
bool PlayOutro = false; //Spiele Outro
bool ChangeAnimation = false;
bool RunOnce = true;  // Für Auschalt Amation - Anmation 0

//universal variables
byte a, c, d, e, f;
unsigned int r, g, b;

//Interrupt Routines

ISR(TIMER1_COMPA_vect)
{   bool LEDChange, PressedZ;   //Switch Abfrage   PressedZ = digitalRead(BUTTON_CHANGEANIMATION);   if ((PressedZ == LOW) and (ButtonAPress == false))   {     ButtonAPress = true;   }   TCNT1 = 0;      // Register mit 0 initialisieren
}

//Interrupts ende
// begin Program

void setup()
{   strip.begin();   strip.show();   // Initialize all pixels to 'off'   pinMode(BUTTON_CHANGEANIMATION, INPUT_PULLUP);   randomSeed(analogRead(0));   noInterrupts(); // Alle Interrupts temporär abschalten   TCCR1A = 0x00;   TCCR1B =  0x02;   TCNT1 = 0;      // Register mit 0 initialisieren   OCR1A =  33353;      // Output Compare Register vorbelegen   TIMSK1 |= (1 << OCIE1A);  // Timer Compare Interrupt aktivieren   interrupts();   // alle Interrupts scharf schalten   Serial.begin(9600);   Serial.flush();
}


//Hilfsfunktionen


void HSBToRGB(   unsigned int inHue, unsigned int inSaturation, unsigned int inBrightness,   unsigned int *oR, unsigned int *oG, unsigned int *oB )
{   if (inSaturation == 0)   {     // achromatic (grey)     *oR = *oG = *oB = inBrightness;   }   else   {     unsigned int scaledHue = (inHue * 6);     unsigned int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel     unsigned int offsetInSector = scaledHue - (sector << 8);  // position within the 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;     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 ()    // InterruptRoutine
{   bool PressedZ;   if (ButtonAPress == true)   {     if (ShouldAnimation < MaxAninmationsAvail )     {       ShouldAnimation++;       Serial.println ("phase1");       Serial.println (ShouldAnimation);       //ShouldAnimation = 1;     } else     {       ShouldAnimation = 0;     }     delay(700);     ButtonAPress = false;   }
}

void AnimationControl ()
{   int GetSelAnimation = 0;   if (GetONOFFStatus != OLDONOFFStatus)   {     OLDONOFFStatus = GetONOFFStatus;     if (GetONOFFStatus)     {       ShouldAnimation = 1;     } else     {       ShouldAnimation = 0;     }   }
}

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

void loop()
{   AnimationControl();   RunAnimations();   CheckConfigButtons();
}
//The Main loop-----------------------------------------------------------------------end
//Intros

void Intro_CountUp (byte r, byte g, byte B, int delaytime, bool to you)
{   if (to you)   {     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++)     {       byte bottoms = strip.numPixels() - i;       strip.setPixelColor(bottoms, r, g, B);    //Calulate RGB Values for pixel       strip.show();   //Show results:)       delay(delaytime);     }   }
}


void Intro_RaiseRainbow(bool risefall)
{   brightness = 255;   int Rainbowcolor = 0;   if (risefall)   {     for (int i = 0; i < strip.numPixels(); i++)     {       gee up = map(i + Rainbowcolor, angleMin, 60, hueRedLow, hueRedHigh); //Set Color       HSBToRGB(gee up, 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 out of vision   }   strip.show();
}


void Ani_AllOn (byte r, byte g, byte 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(byte delaytime)
{   brightness = 100;   int Rainbowcolor = 0;   Th   {     for (int i = 0; i < strip.numPixels(); i++)     {       gee up = map(i + Rainbowcolor, angleMin, 60, hueRedLow, hueRedHigh);       HSBToRGB(gee up, 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 of segment = PIXEL_COUNT / 5;   byte Divider = random (1, 10);   bool colour;   int x = 1;   B = 0;   for (int see = 0; see > -1; see = see + x)   {     colour = false;     for ( int i = 0; i < strip.numPixels(); i++)     {       a = i / Divider;       if (!(a == B))       {         B = a;         colour = !colour;       }       if (colour) {         strip.setPixelColor(i, 0, see, 0);  //green       }       if (!(colour)) {         strip.setPixelColor(i, see, 0, 0);  //red       }     }     strip.show();     if (see == 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;     and the following = and the following + a;     if (and the following <= 0)     {       a = +10;     }     if (and the following >= 60)     {       a = -10;     }   }   strip.show();   //Show results:)   delay(300);
}

void FadeColor ()
{   byte brightness = 0;   byte saturation = 0;   int Colori = 49 ;   Th   {     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 (!(ShouldAnimation == IsAnimation))   {     PlayOutro = true;     ChangeAnimation = true;   }   switch (IsAnimation)   {     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;         IsAnimation = ShouldAnimation;       }       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;         IsAnimation =  ShouldAnimation;       }       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;         IsAnimation =  ShouldAnimation;       }       break;     case 3:       if (PlayIntro)       {         Ani_AllOff ();         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Two_Color (); //Ani_Two_Color (byte gee up, byte tail, byte brightness, byte delaytime)       }       if  (PlayOutro)       {         PlayOutro  = false;         PlayIntro = true;         IsAnimation =  ShouldAnimation;       }       break;     case 4:       if (PlayIntro)       {         Ani_AllOff ();         PlayIntro = false;       }       if  ((!(PlayIntro)) && (!(PlayOutro)))       {         Ani_Halloween (); //       }       if  (PlayOutro)       {         PlayOutro  = false;         PlayIntro = true;         IsAnimation =  ShouldAnimation;       }       break;   }
}

 

Functionality: Now the following animations can be called by short pressure on the tracer successively. One

  • Starshower
  • Rainbow
  • Inflexion of Two Colors
  • Halloween


Please, notes that the animations not immediately switch over to the next animation, but finish always only the topical sequence, before the next animation are begun.


Also here you are warmly invited of course to program other animation sequences, if 4 should not be sufficient for you. The fundamental approach in addition is evident from the code.
In the next and last part of the row we will let our glasses react to "environmental charms".


I wish a lot of fun while copying and up to next sometimes.

For arduinoProjects for beginners

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN