# Modifying the neopixel rainbow function to work with 4pins

So my setup is i have strips that is separated into 4 pins and would like to modify this rainbow function from the neopixel so that it will work on 4 separate strip that are on 4 separate pins. I would like to look like strip number 2 is a continuation of strip number 1 and number 3 is to 2 and number 4 is to 3. A very cool feature about this function is the start and end is a continuation so this mean i basically have a ring setup.

``````void rainbow(int wait) {
// Hue of first pixel runs 5 complete loops through the color wheel.
// Color wheel has a range of 65536 but it's OK if we roll over, so
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
// means we'll make 5*65536/256 = 1280 passes through this outer loop:
for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
// Offset pixel hue by an amount to make one full revolution of the
// color wheel (range of 65536) along the length of the strip
// (strip.numPixels() steps):
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
// strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
// optionally add saturation and value (brightness) (each 0 to 255).
// Here we're using just the single-argument hue variant. The result
// is passed through strip.gamma32() to provide 'truer' colors
// before assigning to each pixel:
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
strip.show(); // Update strip with new contents
delay(wait);  // Pause for a moment
}
}
``````

I do not understand how hue and gamma works so it a bit more tricky for me to modify this function.

Here is my attempt but my attempt is so crude and hoggs so much memory

``````void rainbow(int wait) {

unsigned int totalPixelCount = strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip4.numPixels();
uint32_t pixelHueList [totalPixelCount];
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
for (int i = 0; i < totalPixelCount; i++) {
int pixelHue = firstPixelHue + (i * 65536L / totalPixelCount);
pixelHueList[i] = strip1.gamma32(strip1.ColorHSV(pixelHue));
}

unsigned int j = 0;
for (j = j; j < strip1.numPixels(); j++)
strip1.setPixelColor(j,pixelHueList[j]);
for (j = j; j < strip1.numPixels() + strip2.numPixels(); j++)
strip2.setPixelColor(j,pixelHueList[j]);
for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels(); j++)
strip3.setPixelColor(j,pixelHueList[j]);
for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip3.numPixels(); j++)
strip3.setPixelColor(j,pixelHueList[j]);

strip1.show();
strip2.show();
strip3.show();
strip4.show();
delay(wait);
}
}
``````

Is there a way to make it more efficient?

• "unsinged" compiles? Oct 28, 2021 at 20:02
• Doesn't `setPixelColor()` also need the index of the LED as parameter? Oct 28, 2021 at 20:40
• Ok, your code cannot compile due to some syntax errors. Also you don't need to build up an array first. You are iterating through the LEDs either way, so you can just calculare the needed values right there without saving them in an array inbetweeen. When I'm at my PC again I can write you an answer (if nobody is faster) Oct 28, 2021 at 20:45
• @chrisl Apologies i have fixed the syntaxes :) . I am still commuting going home so i just actually wrote the code here. Oct 28, 2021 at 20:56
• You still have a sytax error with the line `pixelHueList[i] = (i, strip1.gamma32(`. I will look again at your question tomorrow. In my country its now time to go to bed :) Oct 28, 2021 at 21:00

Currently you are first filling an array with values from a calcuation by going through all LEDs; and then you are again going through all LEDs to actually set them. You can do that in one step. Also your current code will most likely not work, since you just count from zero to the total number of LEDs, but the individual strip doesn't know of that much LEDs. That will get you in problems with everything after the first for loop where you set the LEDs.

For doing it in one step and simultaneously solve the problem:

``````void rainbow(int wait) {
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536L; firstPixelHue += 256) {
int j = 0;
for (int i = 0; i < strip1.numPixels(); i++){
int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
strip1.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
}
j = strip1.numPixels();
for (int i = 0; i < strip2.numPixels(); i++){
int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
strip2.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
}
j += strip2.numPixels();
for (int i = 0; i < strip3.numPixels(); i++){
int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
}
j += strip3.numPixels();
for (int i = 0; i < strip4.numPixels(); i++){
int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
}

strip1.show();
strip2.show();
strip3.show();
strip4.show();
delay(wait);
}
}
``````

Here I used `j` as an index over the whole chain of LED strips and `i` as an index for the individual LED strip. So `j` is the index starting point of each strip. The calcuation of the hue is then done with the current total index (`j` as the offset of the current strip in the whole chain and `i` as the index of the current LED in the current strip) `j+i`. For actually setting the corresponding LED we use `i` as the index of the current LED in the current strip.

This solution eliminates the need for creating an additional array. Though it still can be optimized (mostly in terms of code structure). I will leave that to you if you really want to optimize further.

Note: I haven't tested the above code, nor did I compile it.

• Hello ! Sorry for the long reply had to deal with something. I will try this out. Nov 4, 2021 at 13:10