How would i go about making a set of leds flash a color once

How would i go about making a set of leds flash a color once then return to black then return to the color and then stay on that color?

I would do the flash color, and return to black in the setup(), and then just stay on colour in the loop. Something like this (if it were just 1 LED):

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

leds[0] = CRGB::Red;
FastLED.show();
delay(500);
leds[0] = CRGB::Black;
FastLED.show();
delay(500);
}

void loop() {
leds[0] = CRGB::Red;
FastLED.show();
}

what if i wanted to do an entire array of leds instead of just one

Define the array first, refer to the array in the setup and loop.

So:
#define array 80

leds[array].r = 255; leds[array].g = 255; leds[array].b = 255;

LEDS.show();

That still only does one LED, specifically, LED number 80, which is the 79th on the string.

I don’t use delay(), almost ever. It blocks your loop for the duration of the delay and if there’s other stuff that needs to be running, like checking for a button press, or serial input, they won’t. I use the millis() timer instead.

So, that leaves me with one way of doing it since I don’t like using delay() nor do I like to use setup() for running actual program code. Yes it can be done, I just never do it. Personal practice.

I also don’t continuously keep calling the LEDS function if the state of the array has not changed. Since the original request was to:
a) turn on a color
b) go dark
c) turn back on
… after that last step, nothing else changes, the array values remain the same, so there is no point in continuing to call any LEDS function. Add an if statement that throws you out.

// let’s assume 80 LEDs on a string
// let’s assume we want to flash the color blue

#define NUM_LEDS 80
volatile long lastRun = 0; // timer check
volatile uint8_t color = 0; // color check
const uint16_t pause = 500; // half a second

CRGB leds[NUM_LEDS];

void setup() {
// Do your FastLED controller setup
}

void loop() {
if (color < 3) {
// color == 0 → turn on a color
// color == 1 → go dark
// color == 2 → turn back on
if (millis() - lastRun > pause) {
if (!color) {
// first color run, turn strip blue
LEDS.showColor(CRGB::Blue);
color++;
} else if (color == 1) {
// second cycle, turn strip off
LEDS.showColor(CRGB::Black);
color++;
} else {
// we’ve done the first two cycles
// now turn strip on and leave it on
LEDS.showColor(CRGB::Blue);
color++;
}
// update the timer variable
lastRun = millis();
}
}
}

This does three things:

  1. the loop will run unimpeded from any delay() calls. So you could have a button trigger, a serial input, anything else happening while it’s waiting for 500ms to pass before needing to do anything with the leds array again.
  2. the LEDS function will only get called every 500ms (-ish, it’s not exactly 500, it drifts a bit.)
  3. the entire routine that affects the leds array will only run 3 times. After that, it will no longer get called, and you are effectively idling. The color check at the top will prevent the constant updates to the array. Since nothing else is happening with the array, there is no reason to keep calling those functions. So just bail out of it.

This can be expanded into allowing for different lengths of pauses between each state. So for example the initial flash can be 100ms long and the pause 50ms.

What i am trying to do is have a row of leds flash red for 2/5 of a second, go black for 2/5 of a second and then stay red, all of this is needs to happen because someone pushed a button? sorry for asking for so much help, im still new to this

Ashley mentioned one way to set ALL LED’s one colour with:

LEDS.showColor(CRGB::Black);

Another is:

fill_solid( leds, NUM_LEDS, CRGB::Red);

Another is:

for (int i=0; i<NUM_LEDS; i++) {
leds[i] = CRGB::Red;
}

Here’s some documentation:

Either way, you REALLY need to play with the examples provided with the FastLED library.

Also, when working on a project with more than one component (i.e. button and LED’s), learn how to do each individually, and then start getting them to work together.

Agreed, playing with the library is how you’d learn best. The difference between the .showColor() and .fill_solid() or other methods is that .showColor() does not require a call to LEDS.show() afterwards.

@Johnny_Woods_Masamun

inside the void loop(); you will be checking if a button is pressed and should store that result in some variable. for more info on exactly how to do this just look at the ‘Button.ino’ example sketch that came with the Arduino IDE.

if the buttton is pressed you would call a function that does what you want.
Here’s more-or-less what it would look like…

void loop(){

buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
Flash_red_once_and_steady_red();
}
… all your other instructions in the main loop…
}

void Flash_red_once_and_steady_red() {
fill_solid( leds, NUM_LEDS, CRGB::Red);
FastLED.show();
delay(400);
fill_solid( leds, NUM_LEDS, CRGB::Black);
FastLED.show();
delay(400);
fill_solid( leds, NUM_LEDS, CRGB::Red);
FastLED.show();
}
I know people don’t like using delay(); but if you are just counting milliseconds and not doing anything else that is useful in that time, might as well just use the simplest of instructions.

Or do it via an interrupt … again, different ways of skinning the proverbial cat.

const uint8_t intPin = 4; // set this to the interrupt pin you’re using

void setup() {
attachInterrupt(intPin, intHandler, RISING);
}

void loop() {
if (trigger) {
// do your LED flashing sequence
trigger = 0;
}
// do other stuff
}

static void intHandler() {
static unsigned long last_interrupt_time = 0; // for debounce purposes
unsigned long interrupt_time = millis(); // timer - I don’t like delay()s, remember? :slight_smile:
// debounce the button!
if (interrupt_time - last_interrupt_time > 200) {
trigger = 1;
last_interrupt_time = interrupt_time;
}
}

The main loop() will run constantly. When the interrupt fires (by someone pushing the button), it sets trigger = 1. The main loop() will see this and run through the flashing routine, reset trigger, and go idling again.

how would i go about resetting the color counter so that if i remove the signal to the pin and apply it again, it will restart the sequence. as it is, if you trigger it it will do it once and then you have to restart the program before it will do it again

So reset the counter in the trigger loop

how does one do that?

I don’t know what method you’re using. We presented several options to you above. Maybe if you show us what you have now, we can tell you where/how to reset it.

Im using your method with the millis

Yeah, but which method for the button. That’s the important part, where and how are you calling for and checking the button. That determines where in the loop you are and what happens at any given point. Note that this is easier if you’re using an interrupt trigger, but there are other ways of doing it without.

Figured an entire update of my current code would help with the questions
#include <FastLED.h>
#define NUM_LEDS 50
#define LED_PIN 5
#define BRIGHTNESS 75
#define LED_TYPE NEOPIXEL
#define COLOR_ORDER GRB
#define UPDATES_PER_SECOND 75
#define NUM_LEDS 80
volatile long lastRun = 0; // timer check
volatile uint8_t color = 0; // color check
const uint16_t pause = 500; // half a second
CRGB ledStrip[NUM_LEDS];
CRGBPalette16 currentPalette;
TBlendType currentBlending;
const int pin12 = 12;
const int pin11 = 11;
const int pin10 = 10;
const int pin9 = 9;
const int pin8 = 8;
const int pin7 = 7;
const int pin6 = 6;
const int pin5 = 5;

void setup() {
// put your setup code here, to run once:
delay(3000);
FastLED.addLeds<LED_TYPE, LED_PIN>(ledStrip, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
currentPalette = RainbowStripeColors_p;
currentBlending = NOBLEND;
pinMode(pin12, INPUT_PULLUP);
pinMode(pin11, INPUT_PULLUP);
pinMode(pin10, INPUT_PULLUP);

}

void StripFill (CRGB color, uint8_t from, uint8_t to) {
for (uint8_t i = from; i <= to; i++) {
ledStrip[i] = color;
}
}

/void leftStripWipe {
for(int i = NUM_LEDS; i++) {
ledStrip[i] = CRGB::Red;
FastLED.show();
ledStrip[i] = CRGB::Red;
FastLED.show();
delay(5);
}
}
/

void loop() {
// put your main code here, to run repeatedly:
int d12 = digitalRead(pin12);
int d11 = digitalRead(pin11);
int d10 = digitalRead(pin10);
if (d12 == 1 && d11 == 1 && d10 == 1) {
color == 0;
StripFill(CRGB::Black, 0, 50);
FastLED.show();
}

if (d12 == 0) {
for (int i = 0; i < NUM_LEDS; i++) {
ledStrip[i] = CRGB::Blue;
FastLED.show();
//ledStrip[i] = CRGB::Black;
//FastLED.show();
}
if (d10 == 0) {
int i;
for (int i = NUM_LEDS - 1; i >= 0; i–)
ledStrip[i] = CRGB::Blue;
FastLED.show();
ledStrip[i] = CRGB::Blue;
FastLED.show();
delay(5);
}
}
if (d11 == 0) {
if (color < 3) {
// color == 0 → turn on a color
// color == 1 → go dark
// color == 2 → turn back on
if (millis() - lastRun > pause) {
if (!color) {
// first color run, turn strip blue
LEDS.showColor(CRGB::Blue);
color++;
} else if (color == 1) {
// second cycle, turn strip off
LEDS.showColor(CRGB::Black);
color++;
} else {
// we’ve done the first two cycles
// now turn strip on and leave it on
LEDS.showColor(CRGB::Blue);
color++;
}
// update the timer variable
lastRun = millis();
}
}
}
}

Ok so I’m going to assume your d9, d10, and d11 are your button triggers. If so, that means d11 is what triggers the sequence in question. Small problem with the way that’s done. If you just press the button and let go, the sequence will run once and stop, so it just turns the strip on and done. Why? Because that button will only change state when you press it. Now, if you press AND HOLD, the sequence will run in its entirety. It’s a tricky thing when you’re using button triggers like you are here. Adding a reset for the color check will cause the whole sequence to fail.

Actually, you have a reset already at the very top, have you tried working with that?

At the top, you have a color = 0 where you check whether d9, d10, d11 == 1.