I am making a project with 3 layers of leds, one on top of the other, 8 leds per strip. Im trying to figure out how to replace the delay() function so that i can add a momentary pushbutton in the future, already knowing that a delay() in the for loop will prevent other actions of my pushbutton.
This simple code below has one led go up each strip, one strip at a time, to make it look like its spiralling up the project ive created. I want to keep that effect.
I dont have the pushbutton written into the code yet. Also, i know about using millis(), but ive tried every combination.
Is there something in the FastLED library that could help me?
My end goal will be to switch through various lighting functions, about 12 different ones, without getting stuck at any delays.
Here is the basic code i have:
#include <FastLED.h>
#define NUM_STRIPS 3
#define NUM_LEDS 8
#define COLOR_ORDER GRB
#define LED_TYPE WS2812B
CRGB leds[NUM_STRIPS][NUM_LEDS];
//Pin locations for LED strips
const int lowerLEDs = 5;
const int middleLEDs = 6;
const int upperLEDs = 7;
void setup() {
delay(3000); //For recovery
//Add led strip arrays
FastLED.addLeds<LED_TYPE, lowerLEDs, COLOR_ORDER>(leds[0], NUM_LEDS);
FastLED.addLeds<LED_TYPE, middleLEDs, COLOR_ORDER>(leds[1], NUM_LEDS);
FastLED.addLeds<LED_TYPE, upperLEDs, COLOR_ORDER>(leds[2], NUM_LEDS);
currentTime = millis();
}
void loop() {
for(int x = 0; x < NUM_STRIPS; x++) {
for(int i = 0; i < NUM_LEDS; i++) {
leds[x][i] = CRGB::Red;
FastLED.show();
leds[x][i] = CRGB::Black;
delay(100); //THIS IS WHAT I WANT TO GET RID OF.
}
}
}
You can't use for loops, so you need to pick what your for loops do for you, and implement the equivalent using the technique in the blink without delay example in the IDE.
What? I use them in most of my FastLED projects.
For example:
// Function to light up all LEDs as gray, but with every
// tenth LED green and every hundredth is yellow.
void lightEmUp() {
fill_solid(leds, NUM_LEDS, CRGB::DimGrey);
for (int i = 0; i < NUM_LEDS; i++) {
int j = i % 10; //j==0 every ten steps
if (j == 0) leds[i] = CRGB::Green;
j = i % 100; //j==0 every hundred steps
if (j == 0) leds[i] = CRGB::Yellow;
}
FastLED.show();
}
for(int i = 0; i < NUM_LEDS; i++) {
leds[x][i] = CRGB::Red;
FastLED.show();
leds[x][i] = CRGB::Black;
delay(100); //THIS IS WHAT I WANT TO GET RID OF.
}
Compare that code with the 'for' loop posted by OP. Note the big, fat 100 ms delay in the latter. Not to mention 'FastLED.show()' getting called on every iteration.
You could just replace the delay, with a timed loop where you check the button. If pressed then jump out and go onto the next pattern. It's effectively the same approach as per the solution in #3.
#include <FastLED.h>
#define NUM_STRIPS 3
#define NUM_LEDS 8
#define COLOR_ORDER GRB
#define LED_TYPE WS2812B
#define DELAY 100
CRGB leds[NUM_STRIPS][NUM_LEDS];
//Pin locations for LED strips
const int lowerLEDs = 5;
const int middleLEDs = 6;
const int upperLEDs = 7;
const int myButton = 8;
void setup() {
delay(3000); //For recovery
//Add led strip arrays
FastLED.addLeds<LED_TYPE, lowerLEDs, COLOR_ORDER>(leds[0], NUM_LEDS);
FastLED.addLeds<LED_TYPE, middleLEDs, COLOR_ORDER>(leds[1], NUM_LEDS);
FastLED.addLeds<LED_TYPE, upperLEDs, COLOR_ORDER>(leds[2], NUM_LEDS);
// currentTime = millis();
pinMode (myButton, INPUT_PULLUP);
}
void loop()
{
pattern_1();
//pattern_2();
//pattern_3();
}
void pattern_1()
{
for(int x = 0; x < NUM_STRIPS; x++)
{
for(int i = 0; i < NUM_LEDS; i++)
{
leds[x][i] = CRGB::Red;
FastLED.show();
leds[x][i] = CRGB::Black;
unsigned long onTime = millis();
while (millis() - onTime < DELAY)
{
if (digitalRead(myButton) == LOW)
return;
}
}
}
}
Thanks everybody for all the feedback and possible solutions!!
I'll go through and try each different option thats been presented, i cant thank you enough. Im pretty new to programming so i'm excited to learn some things.
I just thought it would work best to separate the three levels of the project, one strip per level.
It's like a tower with three floors.
Do you think I could get easier results making one long strip 24 LEDs long?
I'm new to Fast LED and everything so I wasn't sure if I could seperate the levels as one strip for different patterns