kitesurfer1404 / WS2812FX

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

Virtual LED strip stops after more then 274 LEDs #359

Closed wilsnico240 closed 2 months ago

wilsnico240 commented 2 months ago

When total of leds on 5 strips (274 LED) is passed, it no longer works in virtual LED strip use .

moose4lord commented 2 months ago

Can you tell us what hardware you're using and how it is failing? If you could paste your sketch, that would be helpful too.

moose4lord commented 2 months ago

Actually now that I think of it, if you're using an ESP32, I think you're seeing the problem that has been reported over the past few weeks with the arduino-esp32 v3 core. See #402 and here.

Until this issue is resolved, you may want to use board manager to downgrade to arduino-esp32 v2.0.17.

wilsnico240 commented 2 months ago

I thank you for the quick answer and I use Arduino Uno R3 as hardware with 3 WS2812B LED strip of 3 meters 180 LEDs per strip and 2 WS2812B of 64 LEDs (8x8 matrix). Maximum number of LEDs that I can use so far is:

define LED_S_COUNT_P1 60

define LED_S_COUNT_P2 60

define LED_S_COUNT_P3 60

define LED_S_COUNT_P4 47

define LED_S_COUNT_P5 47

Below is the full script that I inject. I believe it has to do with the memory of Arduino R3 and hope that you can make me a little wiser here . (and help me find a solution for this Halloween project.)

include "WS2812FX.h"

define LED_PIN_V1 3

define LED_PIN_V2 7

define LED_S_PIN_P1 4

define LED_S_PIN_P2 5

define LED_S_PIN_P3 6

define LED_S_PIN_P4 8

define LED_S_PIN_P5 9

define LED_S_COUNT_P1 60

define LED_S_COUNT_P2 60

define LED_S_COUNT_P3 60

define LED_S_COUNT_P4 47

define LED_S_COUNT_P5 47

WS2812FX ws2812fx_v1 = WS2812FX(LED_S_COUNT_P1 + LED_S_COUNT_P2 + LED_S_COUNT_P3, LED_PIN_V1, NEO_GRB, 1, 1); WS2812FX ws2812fx_v2 = WS2812FX(LED_S_COUNT_P4 + LED_S_COUNT_P5, LED_PIN_V2, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls1 = WS2812FX(1, LED_S_PIN_P1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls2 = WS2812FX(1, LED_S_PIN_P2, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls3 = WS2812FX(1, LED_S_PIN_P3, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls4 = WS2812FX(1, LED_S_PIN_P4, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls5 = WS2812FX(1, LED_S_PIN_P5, NEO_GRB, 1, 1);

void myCustomShow(void) { ws2812fx_ls1.show(); ws2812fx_ls2.show(); ws2812fx_ls3.show(); ws2812fx_ls4.show(); ws2812fx_ls5.show(); }

void service1() { ws2812fx_v1.init(); ws2812fx_v1.setBrightness(20); ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_FIREWORKS, ORANGE, 2000); ws2812fx_v1.start(); ws2812fx_ls1.init(); ws2812fx_ls1.setPixels(LED_S_COUNT_P1, ws2812fx_v1.getPixels()); ws2812fx_ls2.init(); ws2812fx_ls2.setPixels(LED_S_COUNT_P2, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 ws2812fx_v1.getNumBytesPerPixel())); ws2812fx_ls3.init(); ws2812fx_ls3.setPixels(LED_S_COUNT_P3, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 + LED_S_COUNT_P2) ws2812fx_v1.getNumBytesPerPixel()); ws2812fx_v1.setCustomShow(myCustomShow); ws2812fx_v2.init(); ws2812fx_v2.setBrightness(150); ws2812fx_v2.setSegment(0, 0, ws2812fx_v2.getLength()-1, FX_MODE_BREATH, ORANGE); ws2812fx_v2.start(); ws2812fx_ls4.init(); ws2812fx_ls4.setPixels(LED_S_COUNT_P4, ws2812fx_v2.getPixels()); ws2812fx_ls5.init(); ws2812fx_ls5.setPixels(LED_S_COUNT_P5, ws2812fx_v2.getPixels() + (LED_S_COUNT_P4 * ws2812fx_v2.getNumBytesPerPixel())); ws2812fx_v2.setCustomShow(myCustomShow); }

void setup() { service1(); }

void loop() { ws2812fx_v1.service(); ws2812fx_v2.service(); }

wilsnico240 commented 2 months ago

Next code works perfectly for 2 WS2812B 180 LEDs strips.

include "WS2812FX.h"

include "FastLED.h"

define LED_PIN_V1 3

define LED_S_PIN_P1 4

define LED_S_PIN_P2 5

define LED_S_COUNT_P1 180

define LED_S_COUNT_P2 180

WS2812FX ws2812fx_v1 = WS2812FX(LED_S_COUNT_P1 + LED_S_COUNT_P2, LED_PIN_V1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls1 = WS2812FX(1, LED_S_PIN_P1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls2 = WS2812FX(1, LED_S_PIN_P2, NEO_GRB, 1, 1);

void myCustomShow(void) { ws2812fx_ls1.show(); ws2812fx_ls2.show(); }

void service1() { ws2812fx_v1.init(); ws2812fx_v1.setBrightness(20); ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_FIREWORKS, ORANGE, 3000); ws2812fx_v1.start(); ws2812fx_ls1.init(); ws2812fx_ls1.setPixels(LED_S_COUNT_P1, ws2812fx_v1.getPixels()); ws2812fx_ls2.init(); ws2812fx_ls2.setPixels(LED_S_COUNT_P2, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 * ws2812fx_v1.getNumBytesPerPixel())); ws2812fx_v1.setCustomShow(myCustomShow); }

void setup() { service1(); }

void loop() { ws2812fx_v1.service(); }

wilsnico240 commented 2 months ago

Next code works perfectly for 3 WS2812B 64 LEDs (8x8 matrix).

include "WS2812FX.h"

define LED_PIN_V1 3

define LED_S_PIN_P1 4

define LED_S_PIN_P2 5

define LED_S_PIN_P3 6

define LED_S_COUNT_P1 64

define LED_S_COUNT_P2 64

define LED_S_COUNT_P3 64

WS2812FX ws2812fx_v1 = WS2812FX(LED_S_COUNT_P1 + LED_S_COUNT_P2 + LED_S_COUNT_P3, LED_PIN_V1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls1 = WS2812FX(1, LED_S_PIN_P1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls2 = WS2812FX(1, LED_S_PIN_P2, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls3 = WS2812FX(1, LED_S_PIN_P3, NEO_GRB, 1, 1);

void myCustomShow(void) { ws2812fx_ls1.show(); ws2812fx_ls2.show(); ws2812fx_ls3.show(); }

void service1() { ws2812fx_v1.init(); ws2812fx_v1.setBrightness(20); ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_FIREWORKS, ORANGE, 2000); ws2812fx_v1.start(); ws2812fx_ls1.init(); ws2812fx_ls1.setPixels(LED_S_COUNT_P1, ws2812fx_v1.getPixels()); ws2812fx_ls2.init(); ws2812fx_ls2.setPixels(LED_S_COUNT_P2, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 ws2812fx_v1.getNumBytesPerPixel())); ws2812fx_ls3.init(); ws2812fx_ls3.setPixels(LED_S_COUNT_P3, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 + LED_S_COUNT_P2) ws2812fx_v1.getNumBytesPerPixel()); ws2812fx_v1.setCustomShow(myCustomShow); }

void setup() { service1(); }

void loop() { ws2812fx_v1.service(); }

moose4lord commented 2 months ago

Yeah you're definitely running out of memory on your Arduino UNO. With 2KB of memory, it only has the space to store data for a couple hundred LEDs. I created this test program for my Arduino Nano (which is similar to your UNO);

#include <WS2812FX.h>

#define LED_PIN_V1  4
#define LED_PIN_P1  4
#define LED_PIN_P2  5
#define LED_PIN_P3  6
#define LED_PIN_P4  7
#define LED_PIN_P5  8

#define LED_COUNT_P1   49
#define LED_COUNT_P2   49
#define LED_COUNT_P3   49
#define LED_COUNT_P4   50
#define LED_COUNT_P5   50
#define LED_COUNT_TOTAL (LED_COUNT_P1 + LED_COUNT_P2 + LED_COUNT_P3 + LED_COUNT_P4 + LED_COUNT_P5)

WS2812FX ws2812fx_v1 = WS2812FX(LED_COUNT_TOTAL, LED_PIN_V1, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p1 = WS2812FX(1,               LED_PIN_P1, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p2 = WS2812FX(1,               LED_PIN_P2, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p3 = WS2812FX(1,               LED_PIN_P3, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p4 = WS2812FX(1,               LED_PIN_P4, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p5 = WS2812FX(1,               LED_PIN_P5, NEO_GRB + NEO_KHZ800, 1, 1);

unsigned long lastMillis = 0;

void setup() {
  Serial.begin(9600);

  pinMode(LED_BUILTIN, OUTPUT);  // blinky LED
  delay(500);  // give some time for the Serial peripheral to initialize

  // initialize the virtual strip as you would any normal ws2812fx instance
  ws2812fx_v1.init();
  ws2812fx_v1.setBrightness(16);
  ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_COMET, RED, 2000, NO_OPTIONS);
  ws2812fx_v1.start();

  // init the physical strip's GPIOs and reassign their pixel data
  // pointer to use the virtual strip's pixel data.
  int numByesPerPixel = ws2812fx_v1.getNumBytesPerPixel();
  ws2812fx_p1.init();
  ws2812fx_p1.setPixels(LED_COUNT_P1, ws2812fx_v1.getPixels());
  ws2812fx_p2.init();
  ws2812fx_p2.setPixels(LED_COUNT_P2, ws2812fx_v1.getPixels() + (LED_COUNT_P1 * numByesPerPixel));
  ws2812fx_p3.init();
  ws2812fx_p3.setPixels(LED_COUNT_P3, ws2812fx_v1.getPixels() + ((LED_COUNT_P1 + LED_COUNT_P2) * numByesPerPixel));
  ws2812fx_p4.init();
  ws2812fx_p4.setPixels(LED_COUNT_P4, ws2812fx_v1.getPixels() + ((LED_COUNT_P1 + LED_COUNT_P2 + LED_COUNT_P3) * numByesPerPixel));
  ws2812fx_p5.init();
  ws2812fx_p5.setPixels(LED_COUNT_P5, ws2812fx_v1.getPixels() + ((LED_COUNT_P1 + LED_COUNT_P2 + LED_COUNT_P3 + LED_COUNT_P4) * numByesPerPixel));

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

  Serial.print("freemem: "); Serial.println(freeMemory());  // print the amount of free memory
}

void loop() {
  // update the virtual strip's pixel data by calling service() as you normally would
  ws2812fx_v1.service();

  // blink the built-in LED periodically to indicate the processor is still alive
  if(millis() > (lastMillis + 500)) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    lastMillis = millis();
  }
}

// update the physical strips's LEDs
void myCustomShow(void) {
  ws2812fx_p1.show();
  ws2812fx_p2.show();
  ws2812fx_p3.show();
  ws2812fx_p4.show();
  ws2812fx_p5.show();
}

/* MemoryFree function */
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;

int freeMemory() {
  int free_memory;

  if((int)__brkval == 0)
     free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}

With this test program 2KB of memory is only enough to support 247 LEDs. If I comment out the Serial commands, I reclaim about 190 bytes of memory and the max number of LEDs rises to 310. That's about as high as I can get.

To drive 668 LEDs as you propose will require a different processor. An Arduino Mega 2560 sounds like a good fit. Or an ESP8266/ESP32 would certainly be able to do that, although those are 3.3V processors, so you'd need to incorporate a voltage level shifter in your design.

wilsnico240 commented 2 months ago

Thank you for the explanation.I already suspected that it would be a memory problem in the Halloween project. I solved it by using 2 Arduino Uno. All 3 pumpkins, wall strips and ghost now have their working light show. code Arduino 1 (2 x 3m wall strips (360 leds totale)) :

include "WS2812FX.h"

include "FastLED.h"

define LED_PIN_V1 3

define LED_S_PIN_P1 4

define LED_S_PIN_P2 5

define LED_S_COUNT_P1 180

define LED_S_COUNT_P2 180

WS2812FX ws2812fx_v1 = WS2812FX(LED_S_COUNT_P1 + LED_S_COUNT_P2, LED_PIN_V1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls1 = WS2812FX(1, LED_S_PIN_P1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls2 = WS2812FX(1, LED_S_PIN_P2, NEO_GRB, 1, 1);

void myCustomShow(void) { ws2812fx_ls1.show(); ws2812fx_ls2.show(); }

void service1() { ws2812fx_v1.init(); ws2812fx_v1.setBrightness(20); ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_FIREWORKS, ORANGE, 2000); ws2812fx_v1.start(); ws2812fx_ls1.init(); ws2812fx_ls1.setPixels(LED_S_COUNT_P1, ws2812fx_v1.getPixels()); ws2812fx_ls2.init(); ws2812fx_ls2.setPixels(LED_S_COUNT_P2, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 * ws2812fx_v1.getNumBytesPerPixel())); ws2812fx_v1.setCustomShow(myCustomShow); }

void setup() { service1(); }

void loop() { ws2812fx_v1.service(); }

code Arduino 2 (3 pumpkins, 1 ghost, 1 x 1m (60led) wall strip (total 228 LEDs))

include "WS2812FX.h"

define LED_PIN_V1 2

define LED_PIN_V2 3

define LED_PIN_V3 9

define LED_S_PIN_P1 4

define LED_S_PIN_P2 5

define LED_S_PIN_P3 6

define LED_S_PIN_P4 7

define LED_S_PIN_P5 8

define LED_S_COUNT_P1 56

define LED_S_COUNT_P2 56

define LED_S_COUNT_P3 56

define LED_S_COUNT_P4 60

define LED_S_COUNT_P5 10

WS2812FX ws2812fx_v1 = WS2812FX(LED_S_COUNT_P1 + LED_S_COUNT_P2 + LED_S_COUNT_P3, LED_PIN_V1, NEO_GRB, 1, 1); WS2812FX ws2812fx_v2 = WS2812FX(LED_S_COUNT_P4, LED_PIN_V2, NEO_GRB, 1, 1); WS2812FX ws2812fx_v3 = WS2812FX(LED_S_COUNT_P5, LED_PIN_V3, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls1 = WS2812FX(1, LED_S_PIN_P1, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls2 = WS2812FX(1, LED_S_PIN_P2, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls3 = WS2812FX(1, LED_S_PIN_P3, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls4 = WS2812FX(1, LED_S_PIN_P4, NEO_GRB, 1, 1); WS2812FX ws2812fx_ls5 = WS2812FX(1, LED_S_PIN_P5, NEO_GRB, 1, 1);

void myCustomShow(void) { ws2812fx_ls1.show(); ws2812fx_ls2.show(); ws2812fx_ls3.show(); ws2812fx_ls4.show(); ws2812fx_ls5.show(); }

void service1() { ws2812fx_v1.init(); ws2812fx_v1.setBrightness(150); ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_BREATH, ORANGE); ws2812fx_v1.start(); ws2812fx_ls1.init(); ws2812fx_ls1.setPixels(LED_S_COUNT_P1, ws2812fx_v1.getPixels()); ws2812fx_ls2.init(); ws2812fx_ls2.setPixels(LED_S_COUNT_P2, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 ws2812fx_v1.getNumBytesPerPixel())); ws2812fx_ls3.init(); ws2812fx_ls3.setPixels(LED_S_COUNT_P3, ws2812fx_v1.getPixels() + (LED_S_COUNT_P1 + LED_S_COUNT_P2) ws2812fx_v1.getNumBytesPerPixel()); ws2812fx_v1.setCustomShow(myCustomShow); ws2812fx_v2.init(); ws2812fx_v2.setBrightness(20); ws2812fx_v2.setSegment(0, 0, ws2812fx_v2.getLength()-1, FX_MODE_FIREWORKS, ORANGE, 2000); ws2812fx_v2.start(); ws2812fx_ls4.init(); ws2812fx_ls4.setPixels(LED_S_COUNT_P4, ws2812fx_v2.getPixels()); ws2812fx_v2.setCustomShow(myCustomShow); ws2812fx_v3.init(); ws2812fx_v3.setBrightness(250); ws2812fx_v3.setSegment(0, 0, ws2812fx_v3.getLength()-1, FX_MODE_TWINKLE_FADE, WHITE); ws2812fx_v3.start(); ws2812fx_ls5.init(); ws2812fx_ls5.setPixels(LED_S_COUNT_P5, ws2812fx_v3.getPixels()); ws2812fx_v3.setCustomShow(myCustomShow); }

void setup() { service1(); }

void loop() { ws2812fx_v1.service(); ws2812fx_v2.service(); ws2812fx_v3.service(); }

wilsnico240 commented 2 months ago

Hope you like the Halloween code. If you want to see images of project in 3 weeks, let me know. Thanks again for the info.