FastLed nightmare

I have a FastLed project that is making NO SENSE.
I have 2 strips one of 240 LEDs and one of 120, both are APA102C strips. Both strips are starting in the middle and running to the opposite ends, strip start/end. A simple 4 LED cylon effect
The large strip preforms like it should (sort of, more later)
The small strip will run until it hits the beginning/end of the strip and dies. The first/last 4 LEDS stay lit and stop doing anything. The large strip hits the first/last LEDs and merrily changes direction back to the middle and reverse ad infinitum as they should.
Question 1: Why the heck does the small strip just die?

This program was modified from a program that was running under Adafruit on a Giga where I was getting acceptable performance and both strips were bouncing back and forth correctly. Because the Giga runs at 3.3V and doesn't work with 5V Arduinos, without adding yet more circuitry I switched over to an UNO which ran the program at about 1/10th the speed of the Giga. So I rewrote the prgram using FastLed which while slower was still usable UNTIL the small strip started dying.

I've played with using SPI and have seen virtually no difference so I am baffled about WHY this is happening.

Question 2: Why does FastLed not seem to work with user defined colors. In Adafruit if I defined Red as 0x0000FF and dim Red as0x000001 I got a vibrant Red block which then left behind a very dim Red. I fastLed the same definition results in a very bright Yellow Orange color.
Any ideas?????

FastLed code:

#include <FastLED.h>

#define NUM_LEDS1 240
#define NUM_LEDS2 120

#define DATA_PIN1 4
#define CLOCK_PIN1 5
#define DATA_PIN2 6
#define CLOCK_PIN2 7

#define c_red CRGB::Red
#define b_red CRGB::Black
#define c_blu CRGB::Blue
#define b_blu CRGB::Black
#define c_grn CRGB::Green
#define b_grn CRGB::Black
#define c_wht CRGB::White
#define b_wht CRGB::Black
#define low_p 10
#define mid_p 11
#define high_p 12
#define fly_p 13

int del = 30;
bool flag = true;
int lb = 121;//large back end rev counter l in the for loop is the large counter
int s = 61;  //small counter
int sb = 61; //small back end counter
CRGB curColor = c_red;
CRGB curBcolor = b_red;
int curDelay = 12;


// Define the array of leds
CRGB l_leds[NUM_LEDS1];
CRGB u_leds[NUM_LEDS2];


void checkButtons(){
  if (digitalRead(low_p)){
    curColor = c_red;
    curBcolor = b_red;
    curDelay = 8;
  }
  else if (digitalRead(mid_p)){
    curColor = c_grn;
    curBcolor = b_grn;
    curDelay = 6;
  } 
  else if (digitalRead(high_p)){
    curColor = c_blu;
    curBcolor = b_blu;
    curDelay = 4;
  } 
  else if (digitalRead(fly_p)){
    curColor = c_wht;
    curBcolor = b_wht;
    curDelay = 0;
  } 
}

void cylon(CRGB frgd, CRGB bkgd, uint16_t del){
  //backward
  flag = true;
  lb = 121; 
  s = 61;
  sb = 61;
  for(int l = 120;l > 0;l--){ 
    l_leds[l] = frgd;
    l_leds[lb] = frgd;
    l_leds[l+4] = bkgd;
    l_leds[lb-4] = bkgd;
    if (flag){
      u_leds[s] = frgd;
      u_leds[sb] = frgd;
      u_leds[s+4] = bkgd;
      u_leds[sb-4] = bkgd;
      flag = !flag;
      sb++;
      s--;
    } else flag = true;
    FastLED.show();
    lb++;
   delay(del);
 }
  //foward
  flag = true;
  lb = 240; 
  s = 0;
  sb = 120;
  for(int l=0;l<121;l++){ 
    l_leds[l] = frgd;
    l_leds[lb] = frgd;
    l_leds[l-4] = bkgd;
    l_leds[lb+4] = bkgd;
    if (flag){
      u_leds[s] = frgd;
      u_leds[sb] = frgd;
      u_leds[s-4] = bkgd;
      u_leds[sb+4] = bkgd;
      flag = !flag;
      s++;
      sb--;
    } else flag = true;
    FastLED.show();
    lb--;
    delay(del);
  }
}

void setup() {
  pinMode(low_p, INPUT);
  pinMode(mid_p, INPUT);
  pinMode(high_p, INPUT);
  pinMode(fly_p, INPUT);
  curColor = c_red;
  curBcolor = b_red;
  curDelay = 8;
  FastLED.addLeds<APA102, DATA_PIN1, CLOCK_PIN1, BGR, DATA_RATE_MHZ(24)>(l_leds, NUM_LEDS1);
  FastLED.addLeds<APA102, DATA_PIN2, CLOCK_PIN2, BGR, DATA_RATE_MHZ(24)>(u_leds, NUM_LEDS2);
}

void loop() {
  checkButtons();
  cylon(curColor,curBcolor,curDelay);
}

Adafruiit Code:

#include <Adafruit_DotStar.h>

#define clkspd 8000000
#define pix1 240
#define data1 4
#define clock1 5 
Adafruit_DotStar strip1(pix1, data1, clock1, DOTSTAR_BRG);

#define pix2 120
#define data2 6
#define clock2 7 
Adafruit_DotStar strip2(pix2, data2, clock2, DOTSTAR_BRG);

#define c_red 0x00FF00
#define b_red 0x000100
#define c_blu 0x0000FF
#define b_blu 0x000001
#define c_grn 0xFF0000
#define b_grn 0x010000
#define c_wht 0xFFFFFF
#define b_wht 0x010101
#define low_p 5
#define mid_p 6
#define high_p 8
#define fly_p 12

int del = 30;
bool flag = true;
int color = 1;
int bcolor = 1;
int curColor = c_red;
int curBcolor = b_red;
int curDelay = 12;


void checkButtons(){
  if (digitalRead(low_p)){
    curColor = c_red;
    curBcolor = b_red;
    curDelay = 12;
  }
  else if (digitalRead(mid_p)){
    curColor = c_grn;
    curBcolor = b_grn;
    curDelay = 8;
  } 
  else if (digitalRead(high_p)){
    curColor = c_blu;
    curBcolor = b_blu;
    curDelay = 4;
  } 
  else if (digitalRead(fly_p)){
    curColor = c_wht;
    curBcolor = b_wht;
    curDelay = 0;
  } 
}


void cylonR(uint32_t frgd, uint32_t bkgd, uint16_t del){
  //reverse
    flag = true;
    int lb = 121;//large back end rev counter l in the for loop is the large counter
    int s = 61;  //small counter
    int sb = 61; //small back end counter
    for (int l = 120;l > 0; l--){
      strip1.setPixelColor(l, frgd);
      strip1.setPixelColor(lb, frgd);
      if (l<121){
        strip1.setPixelColor(l+9,bkgd);
        strip1.setPixelColor(lb-9,bkgd);
      }
      strip1.show();
      if (flag) {
        strip2.setPixelColor(s,frgd);
        strip2.setPixelColor(sb,frgd);
        if (l<121){
          strip2.setPixelColor(s+9,bkgd);
          strip2.setPixelColor(sb-9,bkgd);
        }
      flag = !flag;
      s--;
      sb++;
      strip2.show();
      } else flag = true;
      lb++;
       delay(del);
     }
    //forward
    flag = true;
    lb = 240; 
    s = 0;
    sb = 120;
    for (int l = 0;l < 121; l++){
        strip1.setPixelColor(l,frgd);
        strip1.setPixelColor(lb,frgd);
        if (l>8){
          strip1.setPixelColor(l-9,bkgd);
          strip1.setPixelColor(lb+9,bkgd);
            }
        strip1.show();        
      lb--;   
      if (flag) {
        strip2.setPixelColor(s,frgd);
        strip2.setPixelColor(sb,frgd);
        if (l>8){
          strip2.setPixelColor(s-9,bkgd);
          strip2.setPixelColor(sb+9,bkgd);
        }
        flag = !flag;
        s++;
        sb--;
        strip2.show();
      } else flag = true;
      delay(del);   
    }
    delay(del);
  }




void setup() {
  pinMode(low_p, INPUT_PULLUP);
  pinMode(mid_p, INPUT_PULLUP);
  pinMode(high_p, INPUT_PULLUP);
  pinMode(fly_p, INPUT_PULLUP);
  curColor = c_red;
  curBcolor = b_red;
  curDelay = 12;

  strip1.begin() ;
  strip1.show() ;
  strip2.begin() ;
  strip2.show() ;
}

void loop() {
  checkButtons();
  cylonR(curColor,curBcolor, curDelay);
}
//>

Thanks,

Joe B

So why are you building this project if it does make no sense at all?
You should avoid such words. You discourage people to help you right from the start

1 Like

what does that mean? Are the leds of the shorter strip damaged?
Is the process of "dying" still in progress?
How many LEDs are still alive?

You should calm down and then write a new objective description of what is happening

1 Like

I've been posting on this for about 2 months so YES I am frustrated. NO what the code is doing makes ZERO sense. Criticism at this point should best be kept. What I need is suggestions which is why I posted all the code. I have 4 days to get this running. If you don't underestand what I am saying I don't have the time to re-phrase it.
SHEESH

I know the feeling, but the code always do what you wrote :slight_smile:
Take a break...

1 Like

I have no idea if it is this.... but I found that sometimes Fastled doesn't like you writing a position in the led strip that is past the end of the defined strip.

So IF my old man eyes are reading that right, your 240 Leds are being run backwards and forwards using the value of 121 as the counter? (from centre). Therefore, adding and subtracting 4 from that position value will run outside the defined 240 leds.

But I might be wrong

Have you tied reducing the counter from say 121 and 61 to 100 and 50... just to see if you get the same issue?

I reduced your strips to 16 and 8 respectively, with suitable defines instead of magic numbers. Here's what your array indices were:

Setup Entered---------------------
l = 8 lb = 9 s = 5 sb = 5
l = 7 lb = 10 s = 4 sb = 6
l = 6 lb = 11 s = 4 sb = 6
l = 5 lb = 12 s = 3 sb = 7
l = 4 lb = 13 s = 3 sb = 7
l = 3 lb = 14 s = 2 sb = 8
l = 2 lb = 15 s = 2 sb = 8
l = 1 lb = 16 s = 1 sb = 9
l = 0 lb = 16 s = 0 sb = 8
l = 1 lb = 15 s = 1 sb = 7
l = 2 lb = 14 s = 1 sb = 7
l = 3 lb = 13 s = 2 sb = 6
l = 4 lb = 12 s = 2 sb = 6
l = 5 lb = 11 s = 3 sb = 5
l = 6 lb = 10 s = 3 sb = 5
l = 7 lb = 9 s = 4 sb = 4
l = 8 lb = 8 s = 4 sb = 4

All I can say is, for an array of length 16, location 16 is beyond the array end, similarly for an array of length 8, locations 8 and 9 are out of bounds.
You're trashing memory, so all bets are off, whether or not FastLED "likes" you doing it. It won't actually know, because it only works on the array length you've declared, which is 240/120. Ooops!
Modified code available if you request it, or I can point you to Wokwi.
..edits..
Well, since I have to walk away for a while, here's your code in Wokwi. You may not like what I did with your defines, but it does make life easier.
Joe's Fastled
You can run it there, and the Serial Output window will open, with the content listed above. I'll leave it up until this time tomorrow.

It makes perfect sense. Undefined Behavior is always invoked when you access beyond an array's bounds.

2 Likes

FYI... Adafruit does internal array bounds checking to avoid accesses outside the array. FastLED does not do internal bounds checking so you get what you write.

2 Likes

@joebataz suspiciously silent, for one seeking help. I suppose it's to be expected.
'ignore'
There. problem solved.

Life is a beach, and then you die.

OP should choose a less stressful hobby.

This tells me the addressable size of the small strip is bigger than the number of pixels. You can tell exactly how "too big" like this: Inside loop(), make the small strip light pixels slow enough to count them out loud... say "1, 2, 3, ..." and when you get to the "dead" part, keep counting out loud until you see the loop. Subtract one from the total count. That is exactly how big the sketch has been told the addressable size it. Been there, done that. Come back here with the data.

1 Like

OR,

I could have been madly rewiring/rewriting/rebuilding my project while keeping an ear out for the delivery of a computer and too busy to revisit a place where I got a plethora of suggestions, none of which solved my problem.

But I do appreciate the DRY comments......

The problem (at least the most egregious one) is that your code is accessing beyond the bounds of the CRGB array. The solution is to fix the code so it doesn't do that. Once that's done, report back, post the new code, and let us know if problems persist (or new ones show up).

Which is pretty obvious, and easy to fix, if you just look at the Wokwi output. Debugging 101. SHEESH, indeed!

xfpd,

If you check the code you will see I have both strips at the correct and verified by hand-count length. OK I cheated, there is a solder join every thirty pixels. 8 joints for the large strip, 4 joints for the small one.
What I finally resigned myself to doing was to rewire my control box to use DPST switches with grounds being sent to the "brain' (main Mega) and re-replacing the Giga-UNO-Giga that runs the strip to using the Adafruit library which runs very fast on the Giga, but is a dog on the UNO and using the INPUT_PULLUP mode that I originally used on the Giga.
WOW, it actually is working! AND I have my bright colors of 0xFF0000, 0x00FF00, and 0x0000FF and the dim versions 0x010000, 0x000100, 0x000001. So now I have the look that I want but also have the brain interpreting things and communicating with other 5V Arduinos in the project just fine.

Thanks for the POSITIVE comments....

Joe B

gfvalvo,

I thought CRGB::Red and CRGB::DarkMaroon and CRGB::Black were ALL called out in the CRGBcolor charts. Read my other post, no need to post any code which hasn't already been posted, just change devices and some wiring.

The obvious is not always so which I why I wanted another set of eyes......
I'll see your SHEESH and raise you a GUFAW....

One step at a time. Keep it up.

That has nothing to do with what I was talking about. These are the CRGB arrays:

CRGB l_leds[NUM_LEDS1];
CRGB u_leds[NUM_LEDS2];

Your code is accessing beyond the bounds of at least one of them. Fix that. Then post the new code.