Infinity Mirror Animations

It occurred to me after my first workshop concluded that I didn’t delve into the code required to run the Infinity Mirror. I had the attendees upload the code and that was that. It worked, which was my only standard at that moment. However, I feel like it was a disservice to the attendees. One I won’t repeat and which I’d like to partially rectify now.

The code for running a NeoPixel strip is, thankfully, simple. You download the library, install it into Arduino and you can run a strip quite quickly.

Head to File > Examples > Adafruit_NeoPixel > strandtest

strandtest location in IDE
The Adafruit NeoPixel library strandtest code location in Arduino

Let’s look at the initial code you’ll see.

#include <Adafruit_NeoPixel.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}

void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
// Send a theater pixel chase in...
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color( 0, 0, 127), 50); // Blue

rainbow(20);
rainbowCycle(20);
theaterChaseRainbow(50);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();

delay(wait);

for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();

delay(wait);

for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}

To start there is a #define PIN 6 This lets the Arduino know which pin is controlling your strip. The next important line to notice is the declaration of which type of strip you’re using. Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_GRB + NEO_KHZ800); with how many LEDs you have in your strip (in the case of the infinity mirror with holes cut there are 24), the control pin, plus the colour style and speed.

From now on, you reference your NeoPixel strip as simply strip.

In the Arduino setup function, there is simply

strip.begin();
strip.show();

These two lines initialize your strip and then turn on whatever “pixels” you wanted on. Since you didn’t set any pixels, the strip will be off.

Now in the loop function, are the calls to the various types of animation “presets”.  colorWipetheaterChaserainbowrainbowCycletheaterChaseRainbow.

colorWipe looks like this:

You can download colour variations of colorWipe here. I’ve included a few variations.

theaterChase looks like this:

You can download colour variations of theaterChase here. I’ve included a few variations.

rainbow looks like this:

Rainbow can be downloaded here.

And finally rainbowCycle:

RainbowCycle can be downloaded here.

Some key differences between the example code to make note of in my provided examples.

I added three colour variables:
int redCol = 0;
int greenCol = 0;
int blueCol = 0;

this allows me to change the colour in one spot and reference a variable instead of a number. (or integer in this case)

For instance in the colorWipe example, colorWipe(strip.Color(redCol, greenCol, blueCol), 50); means I can change one value between red, green and blue and create my different colours. Making it even easier when in the random colorWipe example, I can do this;

redCol = ceil(random()*255);
greenCol = ceil(random()*255);
blueCol = ceil(random()*255);

So there you have it, several ready-made examples to download and test out with your NeoPixel LED strip.

0 comments on “Infinity Mirror AnimationsAdd yours →

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.