Ok I know this is an old thread, but I came across it while searching for a way to do a very similar sort of thing and I think I found a more elegant way to solve the issue. I was first trying to use array shifting to scroll an animation across a huge row of neopixles (my christmas lights) but I found that trying to scroll the array continuously would quickly lead to the array going out of bounds after a number of iterations, so I thought what about a FIFO queue?
Turns out there is a FIFO queue include for arduino here: Arduino Playground - QueueList Library
My implementation (snippet) is here:
#include <QueueList.h>
#include <Adafruit_NeoPixel.h>
void setup() {
strip.begin(); //initialize strip
strip.show(); // Initialize all pixels to 'off'
//Serial.begin (9600); //for debugging
}
void loop() {
scrollAnimate (strip.Color(0,255,0), strip.Color(255,0,0), 60, 500, 4, 10, true); //call the scroll animate script as (double backgroundColor, double scrollColor, int width, int loopCount, int brightnessFactor, int wait, boolean forever
}
void scrollAnimate (double backgroundColor, double scrollColor, int width, int loopCount, int brightnessFactor, int wait, boolean forever) {
double queuePop;
QueueList <double> stripQueue;
stripQueue.setPrinter (Serial);
for (int i=0; i < width; i++){
stripQueue.push(scrollColor); //push in the scrolling color
}
for (int i=0; i < width; i++){
stripQueue.push(backgroundColor); //push in the background color
}
for (int y=0; y<loopCount; y++){
for (int i=0; (i< strip.numPixels()-1); i++) { //the strip.numPixels()-1 forces the animation to move by 1 pixel each time the loop goes through. It does sacrifice the last pixel of the string.
queuePop=stripQueue.pop(); //pop out the current color value
strip.setPixelColor(i, queuePop); //set the current led to the popped value
stripQueue.push (queuePop); //push the value back to the bottom of the queue pile
//Serial.println(queuePop); //for debugging, this seriously slows down the animation if enabled
if (forever){ //continue the animation without interruption
y=0;
}
}
strip.show(); //display the strip
delay(wait); //delay by the wait value, smaller values make the animation go faster.
}
}
I had originally tried making a queue for the entire string of pixels I was working with (600 at this point) but that quickly ran into problems with my Uno development board (I have a Mega running the lights, and it probably would have been ok) so instead I only make the queue large enough to hold the repeating animation, then keep filling out the string by popping a value and then pushing it back to the bottom of the queue.
Anyway hopefully this helps someone out in the future, because I believe using a FIFO queue is a pretty elegant solution to shifting the order of values around but keeping the order.