LED limit with Adfruit / WS2812fx

Hey guys, so I have an Arduino Uno - I have wrote my sketch and tried to be as clean as I can with it, however on a single output pin I have about a 400 LED limit.

The issue is I need 2 out put pins and this limits me to 180 LEDS

Unfortunatly this isnt enough.

I wasn't sure if ram is the issue here or somthing else.

If I have LED_COUNT at 90 per pin it works, if I set at 100 per pin...non of them work at all ... I would think if it was a memory issue setting at 100 per pin would just make the first 180 light up?

Any advice welcome.

Craig

I would think if it was a memory issue setting at 100 per pin would just make the first 180 light up?

No.
Once you run out of memory, your code starts writing to memory that is being used for other things. So it is normal for the processor to crash.

The limit not only depends on how many LEDs you have but also on what memory your other code is using. Have you got any large arrays, or arrays that are say int when they could be byte?

The issue is I need 2 out put pins and this limits me to 180 LEDS

Not sure what you are doing but this is not true. It makes no difference how many pins you use, it is the total number of LEDs that is important.

So far Pin 6 has 90 LED asigned to it and Pin 7 has 80 LED assigned to it.

Even with just a basic effect or a static colour, if I add any more than 80 per pin then pin 2 just doesn't work any more.

#include <WS2812FX.h>
#include <Arduino.h>

#define LED_COUNT_STRIP_1 80 //Number of LEDs in the strip, strip 1
#define LED_COUNT_STRIP_2 80 //Number of LEDs in the strip, strip 2
#define LED_PIN_STRIP_1 7 //Which pin are the LEDs connected to, strip 1
#define LED_PIN_STRIP_2 6 //Which pin are the LEDs connected to, strip 2
#define BUTTON_PIN PD4 //These are the buttons or inputs for changing effects
#define BUTTON_PIN1 PD5 // ""

bool button_pressed_0 = false; // Required for different input or buttons and must be added below and must be added after "if(digitalRead(BUTTON_PIN) == 1 &&"
bool button_pressed_1 = false; // ""

WS2812FX ws2812fx_strip1 = WS2812FX(LED_COUNT_STRIP_1, LED_PIN_STRIP_1, NEO_GRB + NEO_KHZ800);
WS2812FX ws2812fx_strip2 = WS2812FX(LED_COUNT_STRIP_2, LED_PIN_STRIP_2, NEO_GRB + NEO_KHZ800);

void setup() {
pinMode(BUTTON_PIN, INPUT); //Defines the button type can be INPUT for 5v or INPUT_PULLUP for connecting to ground
pinMode(BUTTON_PIN1, INPUT); // ""

//This will run when the arduino is powered on once
ws2812fx_strip1.init();
ws2812fx_strip2.init();

ws2812fx_strip1.setBrightness(100);
ws2812fx_strip2.setBrightness(100);

ws2812fx_strip1.setColor(WHITE);
ws2812fx_strip2.setColor(WHITE);

ws2812fx_strip1.setSpeed(1000);
ws2812fx_strip2.setSpeed(1000);

ws2812fx_strip1.setMode(FX_MODE_CHASE_WHITE);
ws2812fx_strip2.setMode(FX_MODE_CHASE_WHITE);

ws2812fx_strip1.start();
ws2812fx_strip2.start();
}

void processButton() { //Button processing down below, insert code in this area for button presses

//---------------------------------------------------------------------------------------------------

//----------This is when the button 0 IS pressed -----------

if(digitalRead(BUTTON_PIN) == 1 && button_pressed_0 == false) {

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip1.setSegment(0, 0, 55, FX_MODE_COLOR_WIPE, ORANGE, 1000, false);
ws2812fx_strip1.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip1.setSegment(1, 89, 144, FX_MODE_COLOR_WIPE, ORANGE, 1000, false);
ws2812fx_strip1.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

button_pressed_0 = true;

//----------This is when the button 0 IS NOT pressed -----------

} else if(digitalRead(BUTTON_PIN) == 0 && button_pressed_0 == true) {

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip1.setSegment(0, 0, 55, FX_MODE_CHASE_WHITE, WHITE, 1000, false);
ws2812fx_strip1.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip1.setSegment(1, 89, 144, FX_MODE_CHASE_WHITE, WHITE, 1000, false);
ws2812fx_strip1.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

button_pressed_0 = false;

}

//---------------------------------------------------------------------------------------------------

//----------This is when the button 1 IS pressed -----------

if(digitalRead(BUTTON_PIN1) == 1 && button_pressed_1 == false) {

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip2.setSegment(0, 0, 55, FX_MODE_COLOR_WIPE, BLUE, 1000, true);
ws2812fx_strip2.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip2.setSegment(1, 89, 144, FX_MODE_COLOR_WIPE, BLUE, 1000, true);
ws2812fx_strip2.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

button_pressed_1 = true;

//----------This is when the button 1 IS NOT pressed -----------

} else if(digitalRead(BUTTON_PIN1) == 0 && button_pressed_1 == true) {

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip2.setSegment(0, 0, 55, FX_MODE_CHASE_WHITE, WHITE, 1000, true);
ws2812fx_strip2.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx_strip2.setSegment(1, 89, 144, FX_MODE_CHASE_WHITE, WHITE, 1000, true);
ws2812fx_strip2.resetSegmentRuntimes(); // This will make sure the segment always starts at the beginning

button_pressed_1 = false;

}

//---------------------------------------------------------------------------------------------------
//Button Number please add

}
void loop() {
processButton();
ws2812fx_strip1.service();
ws2812fx_strip2.service();
}

OK, first things first.

You should have read the forum instructions so now you need to go back and modify that post (not re-post it) - using the "More -> Modify" option below the right hand corner of your post - to mark up your code as such using the "</>" icon, not "quote". Just highlight each section of code (or output if you need to post that) from the IDE and click the icon.

In fact, the IDE itself has a "copy for forum" link to put these markings on a highlighted block for you so you then just paste it here in a posting window. But even before doing that, don't forget to use the "Auto-Format" (Ctrl-T) option first to make it easy to read. If you do not post it as "code" it can easily, be quite garbled and is always more difficult to read due to the font.

It is inappropriate to attach it as a ".ino" file unless it is clearly too long to include in the post proper. People can usually see the mistakes directly and do not want to have to actually load it in their own IDE. And even that would also assume they are using a PC and have the IDE running on that PC.

Also tidy up your blank space. Do use blank lines, but only single blanks between complete functional blocks.

Alright guys so I think I am somewhere figuring out whats going on here, either I am doing somthing wrong or neopixels use a LOT more memory than I thought.

So I have made a sketch to:

Light up 10 LEDs on Pin 5 in Red
Light up 10 LEDs on Pin 6 in Green
Light up 10 LEDs on Pin 7 in Blue

I get this error:

Sketch uses 22878 bytes (70%) of program storage space. Maximum is 32256 bytes.
Global variables use 1953 bytes (95%) of dynamic memory, leaving 95 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

This is my sketch, It to me looks really simple, I am not sure how to simplify it further?

It seems that each time I add an output pin it slashes the amount of LEDs I can use and Hikes up the memory usage.

#include <WS2812FX.h>
#include <Arduino.h>

#define LED_COUNT_STRIP_1 10             //Number of LEDs in the strip, strip 1
#define LED_COUNT_STRIP_2 10             //Number of LEDs in the strip, strip 2
#define LED_COUNT_STRIP_3 10             //Number of LEDs in the strip, strip 3

#define LED_PIN_STRIP_1 5                  //Which pin are the LEDs connected to, strip 1
#define LED_PIN_STRIP_2 6                  //Which pin are the LEDs connected to, strip 2
#define LED_PIN_STRIP_3 7                  //Which pin are the LEDs connected to, strip 2


WS2812FX ws2812fx_strip1 = WS2812FX(LED_COUNT_STRIP_1, LED_PIN_STRIP_1, NEO_GRB + NEO_KHZ800);
WS2812FX ws2812fx_strip2 = WS2812FX(LED_COUNT_STRIP_2, LED_PIN_STRIP_2, NEO_GRB + NEO_KHZ800);
WS2812FX ws2812fx_strip3 = WS2812FX(LED_COUNT_STRIP_3, LED_PIN_STRIP_3, NEO_GRB + NEO_KHZ800);

void setup() {
  ws2812fx_strip1.init();
   ws2812fx_strip1.setColor(RED);
  ws2812fx_strip1.start();

  ws2812fx_strip2.init();

  ws2812fx_strip2.setColor(GREEN);
  ws2812fx_strip2.start();

  ws2812fx_strip3.init();

  ws2812fx_strip3.setColor(BLUE);
  ws2812fx_strip3.start();
}


void loop() {
  ws2812fx_strip1.service();
  ws2812fx_strip2.service();
  ws2812fx_strip3.service();
  }

is there any reason to use that library?

when I try with Adafruit and some adoptions to the code using the objects in an array

// by noiasca
#include <Adafruit_NeoPixel.h>

const byte numPixels = 10;

Adafruit_NeoPixel pixels[] {
  {numPixels, 5, NEO_GRB + NEO_KHZ800},
  {numPixels, 6, NEO_GRB + NEO_KHZ800},
  {numPixels, 7, NEO_GRB + NEO_KHZ800},
 // {numPixels, 8, NEO_GRB + NEO_KHZ800},  // test commented out 
};

void setup() {
  for (auto &i : pixels)
    i.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)

  pixels[0].fill(0xFF0000);
  pixels[1].fill(0x00FF00);
  pixels[2].fill(0x0000FF);
//  pixels[3].fill(0xFFFF00);
  for (auto &i : pixels)
    i.show();
}

void loop() {
}

I get following results:

one strip
Der Sketch verwendet 2392 Bytes (7%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 41 Bytes (2%) des dynamischen Speichers, 2007 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

two strips:
Der Sketch verwendet 2470 Bytes (7%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 63 Bytes (3%) des dynamischen Speichers, 1985 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

three strips
Der Sketch verwendet 2448 Bytes (7%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 85 Bytes (4%) des dynamischen Speichers, 1963 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

four stripes:
Der Sketch verwendet 2460 Bytes (7%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 107 Bytes (5%) des dynamischen Speichers, 1941 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

so 22 byte globals per 10pixel stripe.

In another project I'm using the Adafruit library with 256 pixels with quite a complex program (a city traffic simulation) and it never crashes, even when running for days:

Global variables use 1953 bytes (95%) of dynamic memory, leaving 95 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

The message from the compiler does not include the memory usage for storing the data for the LEDs. This is because this memory is allocated by the running code and not defined as a something like a fixed array.
The compiler, while clever, can not know how much memory your code is going to ask for when it is run, so it can not tell you how much it is going to use.

So

so 22 byte globals per 10pixel stripe.

is not correct. The 10 LEDs are going to use 10 * 3 = 30 bytes more.

This is a way of measuring the memory in code that is running. Use it after you have allocated all your memory in the running code.

#include <WS2812FX.h>

This is not a library I have used. Where did it come from?

so 22 byte globals per 10pixel stripe.

have you seen that I explicit stated "globals"?
I haven't made a statement regarding heap, nor stack, nor free Memory.
IMHO my statement is correct.

Thanks for the replies I appreciate it,

So I am using this library because it is an extension of adafruit, It just gives more effects and options for the project that I am working on.

I'm still very new to coding and I did have a look at the fast LED library but a lot of it just went over my head A little bit too complicated for me.

I do think it is a memory issue though I have found that if I run the same code with just one pin output I can run approximately 400 LEDs however if I output to 2 pins I can only run 80led per pin then if I try a 3rd output I can only run 1 led per pin!

I think the library just uses a lot of memory unfortunately I have ordered an esp8266 which has more memory I'm hoping to move the code over to that

The WS2812FX library does appear to use a considerable amount of memory, each strip is using 623 bytes regardless of the number of LEDs used, so the total needed for a strip would be at least 623 bytes + 3 bytes per pixel.

Is there some reason you cannot wire all the LEDs as a single strip, and divide it into segments?

If you must run each strip off a separate output pin, FastLED can run multiple strips using a single memory buffer, but that is not always practical depending on the particular effect you are running on a strip.

I have ordered an esp8266 which has more memory I'm hoping to move the code over to that

You do know that on an ESP8266 you will need an additional level shifter to get a 5V signal from the 3V3 one you get from it. The type that is used for I2C is not suitable.

I have found that if I run the same code with just one pin output I can run approximately 400 LEDs however if I output to 2 pins I can only run 80led per pin then if I try a 3rd output I can only run 1 led per pin!

That is just stupid, it makes no sense at all, have you tried with the Adafruit library. Is the code any different than you posted in the initial post?

david_2018:
The WS2812FX library does appear to use a considerable amount of memory, each strip is using 623 bytes regardless of the number of LEDs used, so the total needed for a strip would be at least 623 bytes + 3 bytes per pixel.

Is there some reason you cannot wire all the LEDs as a single strip, and divide it into segments?

If you must run each strip off a separate output pin, FastLED can run multiple strips using a single memory buffer, but that is not always practical depending on the particular effect you are running on a strip.

That explains a lot, I guess goign to an esp8266 will fix the memory issue.

The fast led library doesn't support RGBW unfortunatly and with me being quite new to coding I am really quite strugglign with it, I did try but its a lot more complicated than this library.

Grumpy_Mike:
You do know that on an ESP8266 you will need an additional level shifter to get a 5V signal from the 3V3 one you get from it. The type that is used for I2C is not suitable.
That is just stupid, it makes no sense at all, have you tried with the Adafruit library. Is the code any different than you posted in the initial post?

Grumpy_Mike:
You do know that on an ESP8266 you will need an additional level shifter to get a 5V signal from the 3V3 one you get from it. The type that is used for I2C is not suitable.
That is just stupid, it makes no sense at all, have you tried with the Adafruit library. Is the code any different than you posted in the initial post?

Hi, is 5v actually needed? I was going to use a buck convertor to power it with the 5v it needs and the LED strips have thier own power supply?

As for the library being stupid, i honestly can't comment I am totally new to coding so I welcome any advice if I am doing somthing wrong.

5v actually needed

No but a signal in excess of 3v7 is.

Have you a link to that library?

Sure its here,

Thanks for that.

The library is an add on to the Adafruit library. From what I can see of the library it is not written so you can have multiple instances of it. That is you can only have a single instance so it will not work with the multiple instances you can have from the Adafruit libiary.

You need multiple instances in order to have multiple output pins. So I conclude that this library is not compatible with what you want to do.

I see you have raised an issue on the GitHub but it is not concerned with your problems here.