Go Down

Topic: Programming LED strips (Read 613 times) previous topic - next topic

messy87

Feb 22, 2020, 10:56 pm Last Edit: Feb 23, 2020, 04:06 pm by messy87
Hello,

I am building lots of displays and props and things for music and art events and would like to use strips of WS2812B RGB led strips. I ahve some example patterns written by other people which work ok but I would like to learn how to control the leds much more precicely myself sot hat I can provide any effect I am asked to do.

I am using the attached "fastled" library.

I am trying to start with the very basics and then build up but I get stuck quite quickly. I can turn individual leds on and off, make them flash and set the colour etc but Im hitting ym head over how to refer to a whole bunch of leds at once.

In the examples from the library it has a variable called NUM_LEDs and in those examples whatever I set the variable to works. Unfortuantly those example are all very complex (to me) and have load of other stuff going on so I cant pick out quite how that var can be used in a basic way.

Also, confusingly even in the basic examples where they light leds by individually calling them rather than using the variable, they still define the variable even though it doesnt seem to have any effect on the sketch.


The below turns on the first 5 leds and sets them red but how on earth do I do the same thing so that I only refer to "NUM_LEDS". That way increasing or decreasing the number of leds that turn on just by adjusting the variable rather than having to put a new line in for each and every led?

Code: [Select]

#include "FastLED.h"
#define NUM_LEDS 5
#define DATA_PIN 5
#define CLOCK_PIN 13

CRGB leds[NUM_LEDS];

void setup() {
   // sanity check delay - allows reprogramming if accidently blowing power w/leds
   delay(2000);

   FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
   
}

void loop() {
   leds[0] = CRGB(255,0,0);
   leds[1] = CRGB(255,0,0);
   leds[2] = CRGB(255,0,0);
   leds[3] = CRGB(255,0,0);
   leds[4] = CRGB(255,0,0);

   FastLED.show();
   delay(1000);
}



Its frustrating me to have to come to the forum with this because I feel like the answer is so basic but Iv tried everything I can think of :(

UKHeliBob

Code: [Select]

#define NUM_LEDS 5


#define DATA_PIN 5
#define CLOCK_PIN 13

CRGB leds[NUM_LEDS];

Note how the number of LEDs defined for NUM_LEDS is used when creating the array of LEDs.  Basically the code says "there are 5 LEDs, please allocate memory for them"

In the example posted the actual number of LEDs is not used again but the loop() function could have been written as
Code: [Select]

void loop() {
  for (int led = 0; led < NUM_LEDS; led++)
    {
       leds[led] = CRGB(255,0,0);
    }
   FastLED.show();
   delay(1000);
}


If at a later date the number of LEDs was changed to say 10 then only the #definition of NUM_LEDS would need to be changed
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Grumpy_Mike

Also note that NUM_LEDS is not a variable, it is a constant, that is why, by convention it is in all capital letters.
It is created with a #define which means whenever the compiler sees the name NUM_LEDS it replaces it with the letter 5.

If you were to make this 4 with your code you would find the last LED would not light up. Anything greater than 5, with you still having 5 LEDs and you would see no difference.

messy87

#3
Feb 23, 2020, 12:32 pm Last Edit: Feb 23, 2020, 04:07 pm by messy87
aaah I think I kinda get it. Could someone pick it apart a bit more tho?...


Code: [Select]

  for (int led = 0; led < NUM_LEDS; led++)   

    {
       leds[led] = CRGB(255,0,0);
    }
   FastLED.show();
   delay(1000);
}



so the "for" statement repeats the block of code between the brackets. In the first line its defining the initialization condition and increment.

Does initialization just mean what state its in at the beggining? in this case 0.

Then theres a condition thas tested for each loop - Im assuming here the condition is if led is less than NUM_LEDS?

Then theres the incriment if the condition is true - which I guess is "led++"  Does the double pluss just mean add 1? What would a single plus mean?


leds[led] = CRGB(255,0,0);  the leds here, which is the integer that the for statement was refering to - does that need to be declared at the beggining of the code or is mentioning it in the for statement all you need?
 
Code: [Select]

    {
       leds[led] = CRGB(255,0,0);
    }
   FastLED.show();
   delay(1000);
}

if the bit betweent he brackets is what gets repeated why is the .show and delay bit outside of it?



Thanks in advance for walking me through this with crayons :P I expect Ill be back soon with questions about the library itself but Ill leave that for later :D

PaulRB

#4
Feb 23, 2020, 01:15 pm Last Edit: Feb 23, 2020, 01:18 pm by PaulRB
Quote
Does initialization just mean what state its in at the beggining? in this case 0.
yes
Quote
Then theres a condition thas tested for each loop - Im assuming here the condition is if led is less than NUM_LEDS?
yes
Quote
Then theres the incriment if the condition is true - which I guess is "led++"  Does the double pluss just mean add 1?
yes
Quote
What would a single pluss mean?
It would not compile, with an error like "missing operand". A value is expected either side of "+".
Quote
leds[led] = CRGB(255,0,0);  the leds here, which is the integer that the for statement was refering to - does that need to be declared at the beggingin of the code or is mentioning it in the for staement all you need?
Its declared in the "for" statement. There, it has "int" before it. Putting a type in front of a variable name declares a new variable. In this case, the variable can only be used inside the for loop. if you try to use it outside the for loop, even after the loop, you will get a compile error. (Unless... there is another variable with the same name!)
Quote
if the bit betweent he brackets is what gets repeated why is the .show and delay bit outside of it?
Because they are not intended to be repeated in this case. You can put them inside the loop, in which case you would get an animated sequence of leds turning on one at a time. But that was not the intention here, the intention was just to switch them all on at once.

You should get a book on C coding.

messy87

brilliant, thanks very much!

I have tried to learn coding from books and things before but I have a terrible time trying to take the theory and apply it to a practical case.  The only way Iv ever managed to learn is by trying to do something and then when I hit a barrier, running off any trying to to find the soluton that particular questiona nd then carrying on tot he next barrier. Its a bit chaotic but I get there eventually :P

UKHeliBob

A for loop is a while loop in disguise, which may help you understand what is going on

Code: [Select]

for (int x = 0; x < 8; x++)
  {
    //code block here
  }

Is equivalent to
declare a variable named x and initialise its value to zero
while x is smaller than 8
  execute the code in the code block
  then increment the value of x
end of while

I hope that it goes without saying that any of the values used in the for loop can be variables that are currently in scope, that the limit test can be any valid C code that returns true/false and that the loop variable need not be simply incremented, rather it can be changed in any way you want
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

messy87

#7
Feb 23, 2020, 03:45 pm Last Edit: Feb 23, 2020, 04:05 pm by messy87
I was trying not to ask more questions so soon but I cant help it: (having too much fun).
I thought I understood how the loop works but then I ran into what seems like a contradiction.....


Heres a basic sketch;

Code: [Select]

#include "FastLED.h"
#define NUM_LEDS 14
#define DATA_PIN 5
#define CLOCK_PIN 13
#define BRIGHTNESS  20

CRGB leds[NUM_LEDS];

void setup() {
    // sanity check delay - allows reprogramming if accidently blowing power w/leds
    delay(2000);

    FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    FastLED.setBrightness(  BRIGHTNESS );

}

void loop() {

  for (int led = 0; led < NUM_LEDS; led++)
    {
       leds[led] = CRGB(255,0,0);
       FastLED.setBrightness(  BRIGHTNESS + 50);
       FastLED.show();
       delay(300);

       FastLED.setBrightness(  BRIGHTNESS );
       FastLED.show();
       delay(300);
    }
   
}




As I understand it, it is doing the following....


loop starts

led = 0  (this happens only once and not at the start of each loop)
is led less than 14? yes so increase led to 1 (although readint e above post, the incriment happens at the end of the loop?)

set led 1 to green and brightness 50
wait 300
set led 1 to brightness 20
wait 300

restart loop


led = 1
is led less that 14? yes so increase led to 2
set led 2 to green and brightness 50
wait 300
set led 2 to brightness 20
wait 300

restart loop



The thng is, after a loop that activates a led, that led keeps running the loop from then on. While led 2 is being dealt with, led 1 is still going with its brightness up and down.

When it gets all the way to led 14 they all just loop the brightness up and down continuously.

Each time the loop restarts its refering to a new Led so why do the previous leds keep running the command as well?



Then theres this next sketch where the loop behaviour acts differently althought more like what id expect....
The leds flash on and off once then the next one does and so on. The previous leds stay off until their turn comes around again to flash once.


Code: [Select]

void loop() {

  for (int led = 0; led < NUM_LEDS; led++)

    {

     leds[led] = CRGB(255,0,0);
     FastLED.show();
     delay(300);

     leds[led] = CRGB::Black;
     FastLED.show();
     delay(300);
    }
   
}



Since "black" is turning the led off, does that stop the loop on each led where brightness doesnt?

PaulRB

Can we just stop you there for a moment?

Have you not noticed that everyone who has replied and tried to help you is putting their code in code tags? We would appreciate the same in return.

messy87

Apologies, I tried to keep it neat with hyphens, didnt realise code tags were a thing :P

PaulRB

#10
Feb 23, 2020, 04:14 pm Last Edit: Feb 23, 2020, 04:20 pm by PaulRB
FastLED.setBrightness() affects the whole string (except the ones that are off).

Code tags are not only a thing. They are forum rules. You did read the rules before you posted, didn't you? ;)

Anyway, +1 karma for adding them in to your previous posts.

PaulRB

Quote
Since "black" is turning the led off, does that stop the loop on each led where brightness doesnt?
Sorry, I don't understand what you're asking there... What makes you say the loop stops? It doesn't stop...

messy87

#12
Feb 23, 2020, 04:56 pm Last Edit: Feb 23, 2020, 05:00 pm by messy87
Sorry, I don't understand what you're asking there... What makes you say the loop stops? It doesn't stop...
So in that sketch, led 1 turns green then turns off and stays off.
Then led 2 turns green, then off and stays off.

Led 1 stays off while led 2 turns on. Both led 1 and 2 stay off when led 3 lights and so on until it cycles through all 14 leds and it comes back to its turn again.



Where as in the first sketch, led 1 turns green and ups it brightness, then turns down its brightness.
At this point, rather than staying in the last condition of that loop (low brightness) it carrys on looping - brightness up and down.

Led 2 then turns on green and flashes, all the time led 1 carries on. This carries on untill all 14 leds are flashing upa nd down together.



So when I say "the loop stops" I dont mean the propper one that is cycling through the leds, I mean the "thing" that is happening to the leds in the first sketch that causes the leds to keep repeating the main loop as if they are the led the code counter is on - even when the code counter has moved on to leds further down the line.


Does that make sence?  I could upload videos of the lights to show what they are doing if it will help.

PaulRB

#13
Feb 23, 2020, 07:20 pm Last Edit: Feb 23, 2020, 07:30 pm by PaulRB
Ok, well, your by second sketch turns off the LEDs after each has flashed. The first sketch does not. So what you see is exactly what I would expect, from reading them. As I said in post #10, the brightness function affects all LEDs that are on. If you leave LEDs on, they will be affected. If you turn them off, they won't.

messy87

#14
Feb 23, 2020, 07:32 pm Last Edit: Feb 23, 2020, 08:18 pm by messy87
I think it got overlooked while i was editing :P



Code: [Select]

void loop() {

  for (int led = 0; led < NUM_LEDS; led++)
    {
       leds[led] = CRGB(255,0,0);
       FastLED.setBrightness(  BRIGHTNESS + 50);
FastLED.show();
delay(300);

     FastLED.setBrightness(  BRIGHTNESS );
     FastLED.show();
     delay(300);
    }
   
}


So, here the  "FastLED.setBrightness(  BRIGHTNESS + 50);" line effects every led, not just the one thats currently the int?

Is that because "FastLED.setBrightness" is calling a subroutine (if thats the word) in the library and that subroutine is written in a way as to effect all leds?[/code]

Go Up