Light LED strip in a specific order

Hello,

first of all I would like to let you guys know that I'm pretty new to arduino programming and electronics.

So I'm currently playing with a WS28128B/Neopixel LED strip and I'm trying to figure out how to light 18 LEDs in a specific order. For example I would like the first 6 LEDs to light up and then jump to the 10th and light the next 8 LEDs and so on. Basically this is the order of LEDs I'm trying to achieve: 1 2 3 4 5 6 10 11 12 13 14 15 16 17 18 7 8 9.

I have managed to succed with adding three "for loops" but I know this is somehow inefficient or the least elegant way to code this:

#include<FastLED.h>

#define NUM_LEDS 18
#define DATA_PIN 7

#define BRIGHTNESS 50
#define delayValue 500

CRGB leds[NUM_LEDS];


void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
  for(int i = 0; i < 6; i++){
    leds[i] = CHSV(0, 255, 255);
    FastLED.show();
    delay(delayValue);
  }
  for(int i = 9; i < 18; i++){
    leds[i] = CHSV(0, 255, 255);
    FastLED.show();
    delay(delayValue);
  }
  for(int i = 6; i < 9; i++){
    leds[i] = CHSV(0, 255, 255);
    FastLED.show();
    delay(delayValue);
  }
}

I have also tried to declare the order of the LEDs in the CRGB array like this:

CRGB leds[NUM_LEDS] = {0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 6, 7, 8};

and then just add one "for loop" thinking this would call the LEDs in the specified order:

for(int i = 0; i < NUM_LEDS; i++){
    leds[i] = CHSV(0, 255, 255);
    FastLED.show();
    delay(delayValue);
  }

As you might have already knew it this didn't work and at this point I'm pretty sure the numbers I've added in {} brackets are just values of the array and not the LEDs positions.

I'm missing out on something and/or my approach is wrong and I would like to ask you guys for help with this problem. Thank you! :slight_smile:

I can't give you a complete answer as I have not driven Neopixels with an Arduino, but I have driven them with a PIC. Have you realised that every time you update a string of Neopixels the whole string has to be re-written? You can't update LED #5 without updating all the others. They work by the controller passing data to the first one, which passed it to the second one, which passes it...right to the end.

I would approach this by having an array with the RGB colours stored for each pixel (so 18 in your case), then change the values in the array to the pattern I want displayed, then send all 18 to the LEDs. Then update the array with the new pattern I want and send that, all 18 of them.

This works becasue you can change the values stored in an array randomly, you can access any value in any order that you want. You then send the whole lot to the Neopixels.

Hope that helps.

Thank you for your answer.

So I have managed to resolve this by adding another array in which I declared the order of the LEDs. This made it possible for me to use only one "for loop" instead of the three "for loops" like above.

#include "FastLED.h"

#define DATA_PIN 7
#define NUM_LEDS 18

#define BRIGHTNESS 100

CRGB leds[NUM_LEDS];
int myLEDS[NUM_LEDS] = {0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 6, 7, 8};

int delayValue = 500;

void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
}

void loop() {
  for(int i = 0; i < NUM_LEDS; i++){
    leds[myLEDS[i]] = CHSV(0, 255, 255);
    FastLED.show();
    delay(delayValue);
  }
  FastLED.clear();
}

Altough this works I still don't understand why wouldn't this work when adding the LEDs order to the CRGB leds[] array.
Would this be the way to go when the LEDs should light up in a certain sequence?

void set( byte start, byte end, byte g, byte r, byte b ( {
    for( int i = start; i < end; i++ ) {
        leds[i] = CHSV(g, r, b);
        //delay(delayValue);     // this belongs with the caller
    }
    FastLED.show();   // having this inside the loop was messing you up
  }

Make sure the array is initialized to your desired start condition.

set( 0, 6, 0, 0xff, 0xff );
delay( );
             "
             "

dariusCurt:
Thank you for your answer.

I have managed to resolve this by adding another array in which I declared the order of the LEDs. Altough this works I still don't understand why wouldn't this work when adding the LEDs order to the CRGB leds[] array.
Would this be the way to go when the LEDs should light up in a certain sequence?

I'm glad you got it working. I can't really comment any further as I've not used the library you are using, so I can only help with the general principals.

Altough this works I still don't understand why wouldn't this work when adding the LEDs order to the CRGB leds[] array.

Because the way you had it:-

CRGB leds[NUM_LEDS] = {0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 6, 7, 8};

Simply defined the initial colour of each LED and not an order.
The trick is your:-

leds[myLEDS[i]] = CHSV(0, 255, 255);

Which says in words make the led whose number is given by
myLEDS[i]
into the colour 0, 255, 255

@boolrules - what that code will do is turn all the LEDs on at the same time, so it dosn't actually matter what order you set them. Now this is normally what you want to do but not for this OP.

Grumpy_Mike:
@boolrules - what that code will do is turn all the LEDs on at the same time, so it dosn't actually matter what order you set them. Now this is normally what you want to do but not for this OP.

It only turns on the LEDs from START until END indices. Which is what the OP specified.

The OP says:-

I'm trying to figure out how to light 18 LEDs in a specific order.

Your code lights all the LEDs at once because all the LEDs come on when you call the show method.

Grumpy_Mike:
The OP says:-Your code lights all the LEDs at once because all the LEDs come on when you call the show method.

First, I specified that the array be initialized to a known state. So if "off" for all LEDs is required, that should be initialized.
Now if you set a range of the array to some values other than zero, only that range will be lit when you write the entire array to the LEDs because the ones you did not write to (outside the range) will still be written with zeros and thus will still be "off".

What part of “in a specific order” are you having a problem with?
Your code will light groups of LEDs.

Anyway the OP has found his soloution, it is a correct one, it does what he wants so that should be the end of matters. The fact that your code does not do what he was asking for is your problem not mine. I think this thread is closed.

It's fine guys, I managed to find the solution and I hope this is the correct approach.

boolrules:

void set( byte start, byte end, byte g, byte r, byte b ( {

for( int i = start; i < end; i++ ) {
        leds[i] = CHSV(g, r, b);
        //delay(delayValue);    // this belongs with the caller
    }
    FastLED.show();  // having this inside the loop was messing you up
  }




Make sure the array is initialized to your desired start condition.



set( 0, 6, 0, 0xff, 0xff );
delay( );
            "
            "

I have to be honest and say that I didn't understand how your code works. I'm not saying it is wrong, it's just that I'm a beginner and I'm still learning these things.

I'm not sure if I should post this here or not, but I wouldn't want to start a new topic just for this small thing. I have managed to write this code which fades the LEDs from one color to the other(entire rainbow).

#include <FastLED.h>

#define DATA_PIN 7
#define NUM_LEDS 18
#define BRIGHTNESS 120

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
    static uint8_t hue = 0;
    FastLED.showColor(CHSV(hue++, 255, 255));
    delay(100); 
  }

I'm not sure if this is the correct way to do it but, again, it works. Now I would like the LEDs every time I power the arduino to start from a random value and not from 0, which is red. I gave the variable "hue" the value "random(0, 255)", but this makes the LEDs to somehow start from a pink color. Why is the code doing that and where am I wrong?

hue should stay between 0 and 255 so hue++ should take this into account. Use the modulo function aka % to do this.
The pink colour comes from the leds which don't know greys and soft colours. They turn to pink.

dariusCurt:
I'm not sure if this is the correct way to do it but, again, it works.

If it works it's the correct way to do it. Sometime I look back at code I wrote ages ago and am amazed at how clumsy it is. Doesn't matter, all part of learning! When you've learnt some more, go back and see if you can improve some of your old code.