I'm really new to Arduino and am probably missing something super simple.
The below code works fine for my project with one small issue...
I want the LED strip to light up and then fade over and over if I hold down the button.
Currently, if I hold down the button it will light the LED strip once, fade down and then stays off. I want it to fade then come on again after a second.
I've been trying for a day but can't figure it out. Any help would be greatly appreciated
Here's my code:
#include <FastLED.h>
#include <ezButton.h>
#define NUM_LEDS 30
#define DATA_PIN 5
ezButton button(7);
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
}
void loop(){
FastLED.clear ();
button.loop();
//int btnState = button.getState();
//delay(50);
if(button.isPressed())
for( int colorStep=0; colorStep<255; colorStep++ ) {
int r = 0;
int b = 255-colorStep++;
int g = 0;
for(int x = 0; x < NUM_LEDS; x++){
leds[x] = CRGB(r,g,b);
}
FastLED.show();{
}
}
}
for( int colorStep=0; colorStep<255; colorStep++ )
inside the If button is pressed block, just do 1 step if button is pressed and at the next loop, if the button is still pressed you modify colorStep and build the display again
wire your button like this: pin D7 --- button --- GND
(typed here, so no guarantee)
I'm not using ezButton.h, I think it's not the best library out there in terms of capabilities. I'd recommend @bricoleau's library in French or the OneButton library from Matthias Hertel or Bounce2 from Thomas Fredericks
Thanks for the code, it's helped a bunch but I'm still not quite there.
I have reversed parts of the code so that the leds light up full then fade out. I have adjusted the fade speed to as fast as I can but I still need to increase it more.
Also, I need the leds to go completely off and then a delay between the next fade.
If I try and introduce a delay the code breaks and the leds just stay lit.
Here's your modified code:
Thanks for helping me with this
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
const byte buttonPin = 7;
byte colorStep = 1;
unsigned long lastUpdate;
const unsigned long updatePeriod = 1;
void fillStrip(byte c) {
for (byte px = 0; px < NUM_LEDS; px++)
leds[px] = CRGB(0, c, 0);
FastLED.show();
}
void setup()
{
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP); // wire pin D7 --- button --- GND
FastLED.addLeds<WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
FastLED.clear ();
lastUpdate = millis();
}
void loop()
{{FastLED.clear ();}
if (digitalRead(buttonPin) == LOW) { // pressed
if (millis() - lastUpdate >= updatePeriod) {
fillStrip(--colorStep);// get to the next color.
lastUpdate = millis();
if (digitalRead(buttonPin) == HIGH) {
fillStrip(colorStep=0);
}
}
}
}
OK so you don't want any pause in between updates, just when you hit black again. Try something like this (typed here, untested)
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
const byte buttonPin = 7;
byte colorStep = 0;
unsigned long lastUpdate;
const unsigned long pauseDuration = 1000; // in ms ie 1 second
void fillStrip(byte c) {
for (byte px = 0; px < NUM_LEDS; px++)
leds[px] = CRGB(0, c, 0);
FastLED.show();
}
void black() {
FastLED.clear ();
FastLED.show(); // not sure if this is neeed after clear
}
void setup()
{
pinMode(buttonPin, INPUT_PULLUP); // wire pin D7 --- button --- GND
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
black();
lastUpdate = millis();
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // pressed
if (colorStep == 0) { // if we are at 0, there is a pause check if we waited long enough
if (millis() - lastUpdate >= pauseDuration) {
fillStrip(++colorStep);
}
} else {
fillStrip(++colorStep); // get to the next color (no waiting time, as fast as loop spins)
lastUpdate = millis();
}
} else {
black();
}
}
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
const byte buttonPin = 7;
byte colorStep = 0;
unsigned long lastUpdate;
const unsigned long pauseDuration = 500; // in ms ie 1 second
void fillStrip(byte c) {
for (byte px = 0; px < NUM_LEDS; px++)
leds[px] = CRGB(0, c, 0);
FastLED.show();
}
void black() {
FastLED.clear ();
FastLED.show(); // not sure if this is neeed after clear
}
void setup()
{
pinMode(buttonPin, INPUT_PULLUP); // wire pin D7 --- button --- GND
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
black();
lastUpdate = millis();
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // pressed
if (colorStep == 0) { // if we are at 0, there is a pause check if we waited long enough
if (millis() - lastUpdate >= pauseDuration) {
fillStrip(--colorStep);
}
} else {
fillStrip(--colorStep); // get to the next color (no waiting time, as fast as loop spins)
lastUpdate = millis();
}
} else {
black();
}
}
If you want to adjust the fade time you need to either put a delay when you display something of if you want this to be non blocking (will react faster to button changes) do as was done in the first code by testing against millis
This is as fast as it gets if you only decrement by 1, there is no delay involved unless you are at black level.
Try going 5 by 5 (careful on the initial value if you want go hit 0)
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
const byte buttonPin = 7;
byte colorStep = 0;
unsigned long lastUpdate;
const unsigned long pauseDuration = 300; // in ms ie 1 second
void fillStrip(byte c) {
for (byte px = 0; px < NUM_LEDS; px++)
leds[px] = CRGB(c, 0, 0);
FastLED.show();
}
void black() {
FastLED.clear ();
FastLED.show(); // not sure if this is neeed after clear
}
void setup()
{
pinMode(buttonPin, INPUT_PULLUP);// wire pin D7 --- button --- GND
FastLED.addLeds<WS2811, DATA_PIN, BGR>(leds, NUM_LEDS);
black();
lastUpdate = millis();
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // pressed
if (colorStep == 0) { // if we are at 0, there is a pause check if we waited long enough
if (millis() - lastUpdate >= pauseDuration) {
fillStrip(colorStep = colorStep - 2);
}
} else {
fillStrip(colorStep = colorStep - 2); // get to the next color (no waiting time, as fast as loop spins)
lastUpdate = millis();
}
} else {
black();
}
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
const byte buttonPin = 7;
int colorStep = 0;
unsigned long lastUpdate;
const unsigned long pauseDuration = 300; // in ms
void fillStrip(byte c) {
for (byte px = 0; px < NUM_LEDS; px++)
leds[px] = CRGB(c, 0, 0);
FastLED.show();
}
void black() {
FastLED.clear ();
FastLED.show(); // not sure if this is neeed after clear
}
void setup()
{
pinMode(buttonPin, INPUT_PULLUP);// wire pin D7 --- button --- GND
FastLED.addLeds<WS2811, DATA_PIN, BGR>(leds, NUM_LEDS);
black();
lastUpdate = millis();
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // pressed
if (colorStep <= 0) { // if we are at 0, there is a pause check if we waited long enough
black();
if (millis() - lastUpdate >= pauseDuration) {
colorStep = 255;
fillStrip(colorStep);
}
} else {
fillStrip(colorStep); // get to the next color (no waiting time, as fast as loop spins)
colorStep = colorStep - 2;
lastUpdate = millis();
}
} else {
black();
}
It would be easier to read with a small state machine and there would be no useless displays. Left as an exercise