memmove() to "shift" array contents (C Library)

I'm working on a strip LED project where I have a byte array that contains 3 bytes for each led (one byte each for r,g,b) and is currently 192 bytes long for 64 LEDs. I'm trying to write a function that effectively "shifts" the values with wrapping of the values from the end back to the beginning of the array. The function should shift the bytes by 3 so that the r,g,b for a given LED stay together. The visual result would be a slide/wrapping of the LEDs when I push the byte array out to the LED strip.

That said, I've never used memmove() but it certainly seems like that's what I need to accomplish this. If there's a better way (fast is best) I'd love to know. Somehow I've tried every variation I can think of including the code below and it never works even close to correctly. Most attempts at doing something like below actually completely lock up my Arduino requiring a power reset (can't even button reset).

Help?

	int byteCount = sizeof(pixels);
	byte temp[3];

	//save the bytes on the end to a temp space
	memmove(temp, pixels+byteCount-4, 3);
	//shift byteCount-3 bytes
	memmove(pixels+3, pixels, byteCount - 3);
	//wrap 3 bytes that were on the end back at the beginning
	memmove(pixels, temp, 3);

Just to make it clear what output I'm expecting I've demonstrated below assuming each number is a byte.

BEFORE: { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
AFTER: { 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

Would it be simpler to just change your pointer into the array?
startpointer = 25; // actual pointer location managed elsewhere, assumes 1 to 192 (vs 0 to 191)
then do 2 passes thru your array

for (x = startpointer to 192; x<193; x=x+3){
shiftout (x ...); // whatever you are gonna do
shiftout(x+1...);
shiftout (x+2...);
}

for (x=1 to starpointer; x<startpointer; x=x+3){
shiftout (x ...); // whatever you are gonna do
shiftout(x+1...);
shiftout (x+2...);
}

While I was typing a reply, Crossroads came up with a nicer answer. However, here it is - you can avoid the overhead of memmove and just move the bytes by hand:

for(int i=0;i<3;i++)
  temp[i]=pixels[byteCount-3+i];

for(int i=byteCount-1;i>=3;i--)
  temp[i]=temp[i-3];

for(int i=0;i<3;i++)
  pixels[i]=temp[i];

@Crossroads: I'm kind of embarrassed to say that I hadn't even considered your solution... My mind got stuck insisting that the array indexes had to match the LED's. Great suggestion and I'm going to go implement that right now for this particular function.

@wildbill: I had, however, thought about trying to use memmove() to swap several chunks of the data around in more creative ways in the future for visual effect. I had made the assumption that memmove() would actually execute much faster than moving the bytes individually by hand. This was more from other programming experience (PC/Windows/C#/etc) as I'm quite new to Arduino and avr-gcc. Is it really not that big of a deal? If so I'll drop memmove() altogether and I can sling the bytes around by hand all day long... ?

Thanks for the quick reply guys... this one's had me stumped for hours trying to not be wasteful with cycles.

Yeah, not too bad for a hardware engineer :wink:

Excellent solution, Crossroads. Sometimes we get so focused on a solution that we don't stop to think about the problem.

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.