WS2812B Fastled Theater chase

Hi new member here with a slight problem.I have a small program that uses 4 leds at a time moving along a strip of 150 WS2812B leds.It is working fine but I do not know how to add more leds to the sequence (i.e) 4 more led’s begin 1 second later and chase the first 4.Here is my code so far.

#include <FastLED.h>

// Define the array of leds

#define LED_DT 6
#define COLOR_ORDER GRB
#define LED_TYPE WS2812
#define NUM_LEDS 150
uint8_t max_bright = 255;
struct CRGB leds[NUM_LEDS];

void setup() {
delay (1000);
LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(max_bright);

}

void loop() {

for(int i=0;i<NUM_LEDS;i++) {
leds[i-4].setRGB (0, 0, 0);
leds*.setRGB ( 255, 255, 0);*
FastLED.show();
delay (50);
Thank you in advance for any help you can offer.I tried to upload a GIF with the effect I want but it would not upload.

This shouldn't be working as the index i-4 is negative if i is less than 4.
To do what you want to do, I would create a function that lits 4 consecutive leds:

void set4leds(int pos) {
 leds[pos].setRGB (0, 0, 0);
 leds[pos+1].setRGB (0, 0, 0);
 leds[pos+2].setRGB (0, 0, 0);
 leds[pos+3].setRGB (0, 0, 0);
 }

and call it with needed arguments. Before the first second, only one call with increasing position and after the first second, 2 calls to have the 2 bands chasing.

declare :

int index1;
int index2;
unsigned long initialtime;

in the setup :

index1 = 0;
index2 = 0;
initialtime = millis();

in the loop :

  FastLED.clear();
  set4leds(index1);
  index1 = (index1+1)%(NUM_LEDS-4);
  if (millis()-initialtime>1000) {
    set4leds(index2);
    index2 = (index2+1)%(NUM_LEDS-4); 
}
 FastLED.show();
 delay (50);

Hi lesept.Thank you for your reply.The code I have I changed very slightly from a program from the internet.I will try to find the original.In the original I was = to -1 which made one led move so I changed it to -4 and it worked.No idea how as I have had my Arduino for around 2 weeks and am just beginning to learn from scratch.I am not sure how I would implement your code.Would I just copy and paste this as is ? I don't think I would as I think I have to define parameters first.Please forgive the (noob) questions.I am 59 years old but very willing to learn.

Thank you again.

This is the effect I am trying to get number 16 in the list but with more space between them i.e 6 dark leds between the lit ones.

Bbkhawk:
This is the effect I am trying to get number 16 in the list but with more space between them i.e 6 dark leds between the lit ones.
https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectRunningLights

The person who wrote that tutorial is very responsive to questions.

You should have asked him.

.

Hi BbkHawk

Here is the code I suggest : it compiles OK but I didn’t try it.

#include <FastLED.h>

// Define the array of leds
#define LED_DT 6
#define COLOR_ORDER GRB
#define LED_TYPE WS2812
#define NUM_LEDS 150
uint8_t max_bright = 255;
struct CRGB leds[NUM_LEDS];

int index1;
int index2;
unsigned long initialtime;

void set4leds(int pos) {
  leds[pos].setRGB (0, 0, 0);
  leds[pos + 1].setRGB (0, 0, 0);
  leds[pos + 2].setRGB (0, 0, 0);
  leds[pos + 3].setRGB (0, 0, 0);
}

void setup() {
  delay (1000);
  LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(max_bright);
  index1 = 0;
  index2 = 0;
  initialtime = millis();
}

void loop() {
  FastLED.clear();
  set4leds(index1);
  index1 = (index1 + 1) % (NUM_LEDS - 4);
  if (millis() - initialtime > 1000) {
    set4leds(index2);
    index2 = (index2 + 1) % (NUM_LEDS - 4);
  }
  FastLED.show();
  delay (50);
}

However, it’s definitely not the same as the example from the website you cited. This should send 4 lit LEDs in the strip, followed by another group of 4 one second later.

The theater chase from tweaking4all seems to be like this :

  • One LED of each N LEDs (meaning the other N-1 are off)
  • Shift every LEDs by one to the right: do the shift N-1 times (due to periodicity)
    (I hope I explain clearly, I’m not native english speaker)

This can be done by playing with modulo (the % operator)

void setLEDs (int K,int N) {
  for (int i=0;i<NUM_LEDS;i++) {
    if (i%N == K)   leds[i].setRGB (127, 0, 0);  // set red LED
  }
}

This function should be called in the loop :

void loop() {
  FastLED.clear();
  for  (int i=0;i<N;i++) {
    setLEDs (i,N); }
  FastLED.show();
  delay (50);
}

The setup changes to

void setup() {
  delay (1000);
  LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(max_bright);
}

and you need to declare the period before the setup:
N = 5;
for example.

Try it ! :slight_smile:

Hi lesept,

Thank you very much for your time and reply.I will try this and let you know what happens.I tried the first sketch you gave to me which works but it only sends 4 leds then another 4 I second later.Once the first 8 reach the end of the strip it repeats.I tried to add more using index3 and so on but it only shows two sets of four.By the way your English is very good :slight_smile:

#include <FastLED.h>

// Define the array of leds
#define LED_DT 6
#define COLOR_ORDER GRB
#define LED_TYPE WS2812
#define NUM_LEDS 150
uint8_t max_bright = 255;
struct CRGB leds[NUM_LEDS];

int index1;
int index2;
int index3;
unsigned long initialtime;

void set4leds(int pos) {
leds[pos].setRGB (0, 0, 0);
leds[pos + 1].setRGB (255,255, 0);
leds[pos + 2].setRGB (255,255, 0);
leds[pos + 3].setRGB (255,255, 0);
}

void setup() {
delay (1000);
LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(max_bright);
index1 = 0;
index2 = 0;
index3 = 0;
initialtime = millis();
}

void loop() {
FastLED.clear();
set4leds(index1);
index1 = (index1 + 1) % (NUM_LEDS - 4);
if (millis() - initialtime > 1000) {
set4leds(index2);
index2 = (index2 + 1) % (NUM_LEDS - 4);
set4leds(index3);
index3 = (index3 + 1) % (NUM_LEDS - 4);
}
FastLED.show();
delay (50);
}

Yes, it's not that easy. The test "if 'millis()..." acts as a chronometer. If you want more than one, you should add more chronos as well. S maybe copy all the if block (the lines between the {} including the if) and change the 1000 to 2000, 3000 and so on. And of course as you did use index2, index3...

Hi lesept,
Thank you again.It compiled ok but led’s are still the same.I will try your second sketch and see if that works.
Once again thank you for your time and patience.

Hi again.I tried your second sketch but I was getting multiple errors.I will try to work on the original sketch you posted as that is practically there.
Thank you.

Hi lesept,

Just an update.I messed around with the timings in your first sketch and now have a very satisfactory result.
Thank you once again for all of your help.

Here is the second one : it compiles ok, please try it and tell me.

#include <FastLED.h>

// Define the array of leds
#define LED_DT 6
#define COLOR_ORDER GRB
#define LED_TYPE WS2812
#define NUM_LEDS 150
uint8_t max_bright = 255;
struct CRGB leds[NUM_LEDS];

int N = 5;

void setLEDs (int K, int N) {
  for (int i = 0; i < NUM_LEDS; i++) {
    if (i % N == K) leds[i].setRGB (127, 0, 0); // set red LED
  }
}

void setup() {
  delay (1000);
  LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(max_bright);
}

void loop() {
  FastLED.clear();
  for  (int i = 0; i < N; i++) {
    setLEDs (i, N);
  }
  FastLED.show();
  delay (50);
}

If it works, you’ll see red leds moving along your strip. Then we can play with it changing colors.
N = 5 is the interval between lit leds. Anyways, that’s what I’m trying to get…
delay(50) sets the speed : increase the number to decrease the speed.

I’m in France, so there’s almost no time difference with you. Also not much years… :wink:

Hi lesept,

I tried your new sketch.It compiled fine but all the leds on the strip are static and lit red i.e all the leds in the strip are on.
Ah good to know we are of similar age :slight_smile:

Hi, sorry for the delay, I’ve been busy working outside all day…

Move the line “int N = 5;” just before the line “FastLED.clear();” in the loop
And move the line “FastLED.clear();” in the setLEDs function, just before the line “for (int i=0 …” ← this was the mistake :slight_smile:

Hi lesept,

That just lights up every 5th led in the strand all static too.Thank you for your help though.I do not want you to waste too much time on this.Though your code is helping me understand so much.

That’s right : the line FastLED.show(); was not correctly placed too (I can’t run the code here, so I’ m kind of blind when checking it) :

#include <FastLED.h>

// Define the array of leds
#define LED_DT 6
#define COLOR_ORDER GRB
#define LED_TYPE WS2812
#define NUM_LEDS 150
uint8_t max_bright = 255;
struct CRGB leds[NUM_LEDS];


void setLEDs (int K, int N) {
  FastLED.clear();
  for (int i = 0; i < NUM_LEDS; i++) {
    if (i % N == K) leds[i].setRGB (127, 0, 0); // set red LED
  }
  FastLED.show();
}

void setup() {
  delay (1000);
  LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(max_bright);
}

void loop() {
  int N = 5;
  for  (int i = 0; i < N; i++) {
    setLEDs (i, N);
    delay (50);
  }
}

You can play with colors in the function, for example :

void setLEDs (int K, int N) {
  FastLED.clear();
  for (int i = 0; i < NUM_LEDS; i++) {
    int red = 255 * (i % N) / (N - 1);
    int blu = 255 - red;
    if (i % N == K) leds[i].setRGB (red, 0, blu); // set changing color
  }
  FastLED.show();
}

(unless I did other mistakes) this should chnage the color of the lit LEDs from red to blue, then back to red again.

Hi Bbkhawk
I found this library by chance, you might want to have a look as it proposes a great number of built-in LED effects. The user guide is available here.

Hi lesept,

Thank you very much.You certainly know your stuff :slight_smile: I will also take a look at the library.I hope you have a great day.

Thanks, the same for you.
Please keep me updated if the code from answer #15 works or not…