Can someone help with my for and if loop

I have a small test program to lite up my two strips of Dotstars with are 72 pixels each (divided up in to group of 6 and spaced 12" apart). I've created and array to divide up the strips in to 6 pixel segments so that each strip has essentially 12 addressable groups.

Everything works correctly in that I've tested each of the strings individually in a loop, but when I try to create a test loop to turn them on and off sucessively, it Lights the first strips and then proceeds to the second string Leds[1] and only lights up the first group of 6 on that string.

I don't think this is a FastLED or Dotstar issue but more of a basic logic programming issue. I know this because the serial monitor print the first "if" condition ( leds[0] ) 12 times. It then enters the "else if" Leds[1] and prints the serial statement just once and then the program halts ( i.e. no more serial print statements and assume the main loop is halted?)

What am I missing here?

Here's a video of it

and here is my code

// Simple strand test for Adafruit Dot Star using FastLED

#include <FastLED.h>
#include <SPI.h>  // COMMENT OUT THIS LINE FOR GEMMA OR TRINKET
int32_t speed = 100;
int brightness = 80;
int seq_count = 0;

#define DATAPIN1 5
#define CLOCKPIN1 11
#define DATAPIN2 12  // to add second string eventually
#define CLOCKPIN2 2

#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 72
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];


/*
 leds0  (leds(0, 5);
 leds1  (leds(6, 11);
 leds2  (leds(12, 17);
 leds3  (leds(18, 23);
 leds4  (leds(24, 29);
 leds5  (leds(30, 35);
 leds6  (leds(36, 41);
 leds7  (leds(42, 47);
 leds8  (leds(48, 53);
 leds9  (leds(54, 59);
 leds10 (leds(60, 65);
 leds11 (leds(66, 71);

 leds12 (leds(72, 77);
 leds13 (leds(78, 83);
 leds14 (leds(84, 89);
 leds15 (leds(90, 95);
 leds16 (leds(96, 101);
 leds17 (leds(102, 107);
 leds18 (leds(108, 113);
 leds19 (leds(114, 119);
 leds20 (leds(120, 125);
 leds21 (leds(126, 131);
 leds22 (leds(132, 137);
 leds23 (leds(138, 144);
*/

//CRGB leds[NUM_LEDS];

int ledsarray[24] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138 };


void setup() {
  Serial.begin(115200);
  delay(1000);
  FastLED.addLeds<DOTSTAR, DATAPIN1, CLOCKPIN1 >(leds[0], NUM_LEDS_PER_STRIP);
  FastLED.addLeds<DOTSTAR, DATAPIN2, CLOCKPIN2 >(leds[1], NUM_LEDS_PER_STRIP);
  FastLED.setBrightness(brightness);
  FastLED.clear();
  FastLED.show();
  delay(1000);
}

void loop() {


  for (int x = 0; x < 24; x++) {
    if (x <= 12) {
      fill_solid(&(leds[0][ledsarray[x]]), 6, CRGB(255, 255, 255));
      Serial.println(" first group of twelve loop is entered to turn ON ");
      } 
      else if (x > 12 ) {
        fill_solid(&(leds[1][ledsarray[x]]), 6, CRGB(255, 255, 255));
        Serial.println(" second group of twelve loop is entered to turn ON ");
      }
      
      FastLED.show();
      delay(speed);
    }
    delay(1000);

 for (int x = 0; x < 24; x++) {
  Serial.println(" entering the turn OFF loop");
    if (x < 12) {
      fill_solid(&(leds[0][ledsarray[x]]), 6, CRGB(0, 0, 0));
      Serial.println(" first group of twelve loop is entered to turn OFF ");
      } 
      else if (x >= 12 ) {
        fill_solid(&(leds[1][ledsarray[x]]), 6, CRGB(0, 0, 0));
        Serial.println(" second group of twelve loop is entered to turn OFF");
      }
      FastLED.show();
      delay(speed);
    }
    

  /*
  //  alternate method  does not work correctly either =================================

  for (int x = 0; x < 12; x++) {
    fill_solid(&(leds[0][ledsarray[x]]), 6, CRGB(255, 255, 255));

    FastLED.show();
    delay(speed);
  }
  delay(1000);
  for (int x = 0; x < 12; x++) {
    fill_solid(&(leds[0][ledsarray[x]]), 6, CRGB(0, 0, 0));
    FastLED.show();
    delay(speed);
  }
  FastLED.clear();
  FastLED.show();
 delay(500);
 for (int x = 12; x < 24; x++) {
    fill_solid(&(leds[1][ledsarray[x]]), 6, CRGB(255, 255, 255));

    FastLED.show();
    delay(speed);
  }
  delay(1000);
  for (int x = 12; x < 24; x++) {
    fill_solid(&(leds[1][ledsarray[x]]), 6, CRGB(0, 0, 0));
    FastLED.show();
    delay(speed);
  }
*/
delay(2000);
}

what's leds[0] and leds[1]?? sorry need my glasses :grimacing:

Hello Delta_G, thanks for your response. If what you are suggesting is

for (int x = 0; x < 24; x++) {
    if (x < 12) {
      fill_solid(&(leds[0][ledsarray[x]]), 6, CRGB(255, 255, 255));
      Serial.println(" first group of twelve loop is entered to turn ON ");
      } 
      else if (x >= 12 ) {
        fill_solid(&(leds[1][ledsarray[x]]), 6, CRGB(255, 255, 255));
        Serial.println(" second group of twelve loop is entered to turn ON ");
      }
      
      FastLED.show();
      delay(speed);
    }
    delay(1000);

I've already tried this and it has the same effect other than it does not exit the else_if part of the loop and the "13th" led group does not turn on.

why do you have 78, 84, ...

if you address them with leds[1][ledsarray[x]] it should start at 0, shouldn't it?

try this

click to see the code
#include <FastLED.h>
const unsigned long speed = 100;
const byte brightness = 80;

const byte DATAPIN1 = 5;
const byte CLOCKPIN1 = 11;
const byte DATAPIN2 = 12;
const byte CLOCKPIN2 = 2;
const byte NUM_STRIPS = 2;
const size_t NUM_LEDS_PER_STRIP = 6*12; // needs to be a multiple of 6

CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];
int ledsarray[NUM_STRIPS][NUM_LEDS_PER_STRIP / 6] ;

void setup() {
  for (size_t strip = 0; strip < NUM_STRIPS; strip++)
    for (int groupStart = 0, n = 0; groupStart < NUM_LEDS_PER_STRIP; groupStart += 6, n++)
      ledsarray[strip][n] = groupStart;

  FastLED.addLeds<DOTSTAR, DATAPIN1, CLOCKPIN1 >(leds[0], NUM_LEDS_PER_STRIP);
  FastLED.addLeds<DOTSTAR, DATAPIN2, CLOCKPIN2 >(leds[1], NUM_LEDS_PER_STRIP);
  FastLED.setBrightness(brightness);
  FastLED.clear();
  FastLED.show();
  delay(1000);
}

void loop() {

  for (size_t strip = 0; strip < NUM_STRIPS; strip++)
    for (size_t group = 0; group < NUM_LEDS_PER_STRIP / 6; group++) {
      fill_solid(&(leds[strip][ledsarray[strip][group]]), 6, CRGB::White);
      FastLED.show();
      delay(speed);
    }
  delay(1000);

  for (size_t strip = 0; strip < NUM_STRIPS; strip++)
    for (size_t group = 0; group < NUM_LEDS_PER_STRIP / 6; group++) {
      fill_solid(&(leds[strip][ledsarray[strip][group]]), 6, CRGB::Black);
      FastLED.show();
      delay(speed);
    }
  delay(1000);
}

I may need glasses too, but it looks like you can end up addressing 144 LEDs on each strip.

      else if (x > 12 ) {
        fill_solid(&(leds[1][ledsarray[x - 12]]), 6, CRGB(255, 255, 255));
        Serial.println(" second group of twelve loop is entered to turn ON ");
      }

Maybe the second group shoukd be indexed by the first 12 entries.

That works. Thank you.

I understand now, when it gets to Led[1] the 12th led, it is assigning ledsarray value of 78 - which overshoots the pixel count of that second strip.

BTW - that should be (x >=12) not (X >12) or it will skip the 12th pixel.

Thanks again!

Yes. I was on my second slice of pizza when I thought it needed a second look for +/- 1 kinda thing.

a7

The wokwi example I’ve posted has also a 2D array for the groups for coherence with the 2D dimension of your LEDs. At the moment the rows hold the same data (both strips use groups of 6 leds) so in practice you could have only a 1D array for the group start indexes

Using a group array matching your strip structure makes it easier as you don’t have to think about >12 or >=12 or whatever

I looked closer at @J-M-L's solution.

I thought at first glance that the fact that ledsarray[i] is just 6 * i was being exploited to get rid of the array altogether.

I didn't think to eliminate it from my example, didn't even occur to me TBH, and when it did, I decided (!) I had left it there to retain maximum flexibility. The array would allow the grouped pixels to be of different sizes. One might imagine the look of groups that got smaller, or got bigger then smaller over the length of the strip.

a7

You don't need the else if (x >=12)..., what possible value can x be other than 12 or greater if it's not less than 12? Just use else.

True. Occasionally it makes sense to repeat a test in the else part, although my preference is to do all that accomplishes (inform/remind the reader) in a comment at that point.

Add my general non-use and non-reading of comments and we are back to just using else.

a7

Perry

I agree with you - “else” is a more logical assumption in the if statement.

Thanks all for your help on this.

1 Like

You don't really need the if statement, or the ledsarray, everything can be calculated from the value of x.

  for (int x = 0; x < 24; x++) {
    fill_solid(&(leds[x / 12][(x * 6) % NUM_LEDS_PER_STRIP]), 6, CRGB(255, 255, 255));
    FastLED.show();
    delay(speed);
  }
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.