kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.6k stars 347 forks source link

Virtual Strip doen't work with Active Idle Segments #297

Closed faccan closed 3 years ago

faccan commented 3 years ago

Here is my Example:
It should change to Blue on swapActiveSegment(0,1) but it doesn't. I guess that perhaps there is a problem on virual strips working on Active and Idle Segment.

Thanks, Regards

include

define LED_COUNT 50

define LED_PIN_1 11

define LED_PIN_2 12

define TIRA_1 0, 49

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN_1, NEO_GRB + NEO_KHZ800,1,1); WS2812FX ws2812fx_Pin1 = WS2812FX(1, LED_PIN_1, NEO_GRB + NEO_KHZ800,1,1); WS2812FX ws2812fx_Pin2 = WS2812FX(1, LED_PIN_2, NEO_GRB + NEO_KHZ800,1,1);

void setup() { // put your setup code here, to run once: Serial.begin(115200);

ws2812fx.init(); ws2812fx.setBrightness(64); ws2812fx.setSegment(0, TIRA_1,FX_MODE_COMET, WHITE, 2000, NO_OPTIONS); ws2812fx.setIdleSegment(1, TIRA_1, FX_MODE_COMET, BLUE, 2000, NO_OPTIONS);

ws2812fx.start();

// init the physical strip's GPIOs and reassign their pixel data // pointer to use the virtual strip's pixel data. ws2812fx_Pin1.init(); ws2812fx_Pin1.setPixels(LED_COUNT, ws2812fx.getPixels()); ws2812fx_Pin2.init(); ws2812fx_Pin2.setPixels(LED_COUNT, ws2812fx.getPixels() );

ws2812fx.swapActiveSegment(0,1);

// config a custom show() function for the virtual strip, so pixel // data gets sent to the physical strips's LEDs instead ws2812fx.setCustomShow(myCustomShow);

}

// update the physical strips's LEDs void myCustomShow(void) { ws2812fx_Pin1.show(); ws2812fx_Pin2.show(); }

void loop() { // put your main code here, to run repeatedly: ws2812fx.service(); } `

moose4lord commented 3 years ago

You made a mistake in the ws2812fx declarations. Sine you're using two segments (one active and one idle), you must allocated space for two segments in the WS2812FX declarations.

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN_1, NEO_GRB + NEO_KHZ800,2,2);
WS2812FX ws2812fx_Pin1 = WS2812FX(1, LED_PIN_1, NEO_GRB + NEO_KHZ800,2,2);
WS2812FX ws2812fx_Pin2 = WS2812FX(1, LED_PIN_2, NEO_GRB + NEO_KHZ800,2,2);

Also, I wasn't sure how many LEDs you have in each physical strip. The _ws2812fx_virtualstrip example sketch is written from the perspective of the physical strips and calculates parameters for the virtual strip automatically. However your sketch seems to be written from the virtual strips's perspective and doesn't calculate the physical strip's parameters properly. If I assume you have 50 LEDs in each physical strip (#define LED_COUNT 50), then I wrote this example sketch that does the proper calculations:

#include <WS2812FX.h>

#define LED_COUNT 50  // assume each physical strip has 50 LEDs
//#define LED_PIN_1 11
//#define LED_PIN_2 12
#define LED_PIN_1 4
#define LED_PIN_2 5

// start and stop LED of the virtual strip
#define TIRA_1 0, LED_COUNT + LED_COUNT - 1

// note the "2"s at the end of the declarations. since you're using two segments (one active and one idle),
// you must allocate space for two segments in the WS2812FX objects.
WS2812FX ws2812fx =      WS2812FX(LED_COUNT + LED_COUNT, LED_PIN_1, NEO_GRB + NEO_KHZ800, 2, 2); // virtual strip
WS2812FX ws2812fx_Pin1 = WS2812FX(1,                     LED_PIN_1, NEO_GRB + NEO_KHZ800, 2, 2);
WS2812FX ws2812fx_Pin2 = WS2812FX(1,                     LED_PIN_2, NEO_GRB + NEO_KHZ800, 2, 2);

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(500);

ws2812fx.init();
ws2812fx.setBrightness(64);
ws2812fx.setSegment(0,     TIRA_1, FX_MODE_COMET, WHITE, 2000, NO_OPTIONS); // segment 0
ws2812fx.setIdleSegment(1, TIRA_1, FX_MODE_COMET, BLUE,  2000, NO_OPTIONS); // segment 1 (initially idle)
ws2812fx.start();

// init the physical strip's GPIOs and reassign their pixel data
// pointer to use the virtual strip's pixel data.
ws2812fx_Pin1.init();
ws2812fx_Pin1.setPixels(LED_COUNT, ws2812fx.getPixels());
ws2812fx_Pin2.init();
ws2812fx_Pin2.setPixels(LED_COUNT, ws2812fx.getPixels() + (LED_COUNT * ws2812fx.getNumBytesPerPixel()));

// config a custom show() function for the virtual strip, so pixel
// data gets sent to the physical strips's LEDs instead
ws2812fx.setCustomShow(myCustomShow);
}

// update the physical strips's LEDs
void myCustomShow(void) {
ws2812fx_Pin1.show();
ws2812fx_Pin2.show();
}

void loop() {
  // put your main code here, to run repeatedly:
  static unsigned long saved_millis = 0;

  ws2812fx.service();

  // this code snippet will alternate segment 0 and segment 1 every ten seconds
  if(millis() > saved_millis + 10000) { // every ten seconds
    if(ws2812fx.isActiveSegment(0)) { // if segment 0 is active
      ws2812fx.swapActiveSegment(0,1); // swap in segment 1
    } else {
      ws2812fx.swapActiveSegment(1,0); // swap in segment 0
    }
    saved_millis = millis();
  }
}