Closed henmel closed 4 years ago
You're on the right track, but I think you need to create a separate buffer for the "reverse" data. The data in the virtual strip is always in "forward" order, and you can't really muck with that order or it will mess up the effect. So I would create a separate buffer for the second physical strip:
WS2812FX ws2812fx_p2 = WS2812FX(LED_COUNT_P2, LED_PIN_P2, NEO_GRB + NEO_KHZ800, 1, 1);
And remove the code that reassigns the second physical strip's buffer to the virtual strip:
ws2812fx_p2.setPixels(LED_COUNT_P2, ws2812fx_v1.getPixels() + ... // remove this line
Then create the custom show() function that copies the virtual strip's pixel data to the second physical strip in reverse order. This is what I came up with:
void myCustomShow(void) {
ws2812fx_p1.Adafruit_NeoPixel::show(); // show zone 1
// copy the pixel data from the virtual buffer to the second physical buffer in reverse order
uint8_t bytesPerPixel = ws2812fx_p2.getNumBytesPerPixel(); // 3=RGB, 4=RGBW
uint8_t *fromPtr = ws2812fx_v1.getPixels() + (LED_COUNT_P1 * bytesPerPixel);
uint8_t *toPtr = ws2812fx_p2.getPixels();
copyPixelsRev(fromPtr, toPtr, LED_COUNT_P2, bytesPerPixel);
ws2812fx_p2.Adafruit_NeoPixel::show(); // show zone 2
}
void copyPixelsRev(uint8_t *fromPtr, uint8_t *toPtr, uint16_t numPixels, uint8_t bytesPerPixel) {
fromPtr += (numPixels - 1) * bytesPerPixel; // update fromPtr to point to the last pixel's data
for(uint16_t i=0; i<numPixels; i++) {
for(uint16_t j=0; j<bytesPerPixel; j++) {
toPtr[j] = fromPtr[j];
}
toPtr += bytesPerPixel;
fromPtr -= bytesPerPixel;
}
}
Thank you very much! Just the bit I needed. I actually changed it a bit and removed the:
ws2812fx_p1.setPixels(LED_COUNT_P1, ws2812fx_v1.getPixels());
and used memmove for both of the zones. Not sure if this is the best way to do this, but seems to work ok.
void copyPixelData() {
uint8_t reversePixelData[LED_COUNT_Z2 * 3]; // assumes RGB LEDs, multiply by 4 for RGBW LEDs
uint8_t numBytesPerPixel = ws2812fx_z2.getNumBytesPerPixel();
uint16_t numBytesPerSegment = LED_COUNT_Z2 * numBytesPerPixel;
// pre-calculate the reverse pixel data for zone 1 segment 0
uint8_t *forwardPtr = ws2812fx.getPixels();
uint8_t *reversePtr = reversePixelData + ((LED_COUNT_Z2 - 1) * numBytesPerPixel);
for(uint16_t i=0; i < numBytesPerSegment; i+=numBytesPerPixel) {
memmove(reversePtr - i, forwardPtr + i, numBytesPerPixel);
}
// copy virtual segment data to zone 1
memmove(ws2812fx_z1.getPixels(), ws2812fx.getPixels() + (numBytesPerSegment), LED_COUNT_Z1 * ws2812fx_z1.getNumBytesPerPixel());
ws2812fx_z1.Adafruit_NeoPixel::show(); // reshow zone 1
// copy virtual segment data to reverse zone 2
memmove(ws2812fx_z2.getPixels(), reversePixelData, numBytesPerSegment);
ws2812fx_z2.Adafruit_NeoPixel::show(); // reshow zone 2
}
Thanks again for the great library and your quick help.
I have a follow up question. I have been trying to copy effects from one strip to another, but with an offset. For example, I have two strips, 30 LEDs each. I would like to copy the effects from strip 1 to strip 2 with a 10 pixel offset. I tried a number of different ways to do the wrapping from strip 1, but did not have any luck. I was able to do this, but with two memmove steps. copying data before and after the offset, like this:
void myCustomShow(void) {
ws2812fx.Adafruit_NeoPixel::show(); // show zone 1
uint16_t pix_offset = 10;
memmove(ws2812fx_z2.getPixels(), ws2812fx.getPixels()+(pix_offset*ws2812fx.getNumBytesPerPixel()), (LED2_COUNT-pix_offset)*ws2812fx_z2.getNumBytesPerPixel());
memmove(ws2812fx_z2.getPixels()+(((LED2_COUNT-pix_offset)*ws2812fx_z2.getNumBytesPerPixel())), ws2812fx.getPixels(), (pix_offset)*ws2812fx_z2.getNumBytesPerPixel());
ws2812fx_z2.Adafruit_NeoPixel::show(); // show zone 2
}
Is there another, better way of dong this?
Again, thanks for all of your help...
That seems like a good way to do it to me. memmoves are very fast and more efficient than a fancy for loop.
I am trying to customize ws2812fx_virtual_strip example to reverse one of the strips, so the effects appear continuous from one strip to the other, as they are both wired from the same end. I have attached a modified version of the example, but it only appears to work with some effects, but not others. Can you please take a look and see what I am doing wrong? ws2812fx_virtual_strip_testreverse-200807a.zip
Thank you for a great library...