My goal - run light sequence function on momentary button press (button 2) continuously until another of the 3 momentary buttons are pressed.
/* switch
*
* Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
* press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's
* a minimum delay between toggles to debounce the circuit (i.e. to ignore
* noise).
*
* David A. Mellis
* 21 November 2006
*/
#include "FastLED.h"
int inPin = 8; // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13; // the number of the output pin
int state = HIGH; // the current state of the output pin
int reading; // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW; // the previous reading from the input pin
int pixelNumber;
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
//NEOPIXEL
#define LED_PIN 7
#define LEDPIN 7
#define LED_TYPE NEOPIXEL
#define NUM_LEDS 2
#define BRIGHTNESS 10
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET WS2811
bool gReverseDirection = false;
CRGBPalette16 gPal;
void setup()
{
pinMode(inPin, INPUT);
pinMode(inPinTwo,INPUT);
pinMode(inPinThree,INPUT);
pinMode(outPin, OUTPUT);
Serial.begin(9600);
// set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
void loop()
{
// BUTTON 1 - SOLID LIGHT
reading = digitalRead(inPin);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH){
state = LOW;
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();
}
else{
state = HIGH;
fill_solid(leds,NUM_LEDS,0xFAF6D1);
FastLED.show();
}
time = millis();
}
digitalWrite(outPin, state);
previous = reading;
// BUTTON 2 - GLITTER LIGHT
readingTwo = digitalRead(inPinTwo);
if (readingTwo == HIGH && previous == LOW && millis() - time> debounce){
if(state == HIGH){
state = LOW;
fadeToBlackBy( leds, NUM_LEDS, 10);
addGlitter(30);
FastLED.show();
}
else{
state = HIGH;
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();
}
time = millis();
}
digitalWrite(outPin,state);
previous = readingTwo;
// BUTTON 3 - MOVEMENT SENSOR LIGHT
readingThree = digitalRead(inPinThree);
if (readingThree == HIGH && previous == LOW && millis() - time> debounce){
if(state == HIGH){
state = LOW;
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();
}
else{
state = HIGH;
}
time = millis();
}
digitalWrite(outPin,state);
previous = readingThree;
}
//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
if( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB::White;}
}
The issue - the function seems to be only ran once (see button 2), which doesn't achieve the required effect. I realize that changing this if
statement to a while
statement would be beneficial, but I cannot figure out how to break out of this while loop upon button press. I know that setting state = LOW
will break the while loop but if I leave it in, the light sequence function never runs.
// BUTTON 2
readingTwo = digitalRead(inPinTwo);
if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
while(state == HIGH){
// state = LOW;
fadeToBlackBy( leds, NUM_LEDS, 10);
addGlitter(30);
FastLED.show();
}
while(state == LOW){
state = HIGH;
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();
}
Any help would be greatly appreciated!
1 Answer 1
I added int btnPress
which gets set on each button press. Then an if statement runs according to btnPress number. Thanks jsotola for the point in the right direction!
#include "FastLED.h"
int inPin = 8; // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13; // the number of the output pin
int state = HIGH; // the current state of the output pin
int reading; // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW; // the previous reading from the input pin
int previousTwo = LOW;
int previousThree = LOW;
volatile int change;
int btnPress;
int pixelNumber;
long time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
//NEOPIXEL
#define LED_PIN 7
#define LEDPIN 7
#define LED_TYPE NEOPIXEL
#define NUM_LEDS 2
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET WS2812B
void setup()
{
//BUTTON
pinMode(inPin, INPUT);
pinMode(inPinTwo,INPUT);
pinMode(inPinThree,INPUT);
pinMode(outPin, OUTPUT);
Serial.begin(9600);
// set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
btnPress = 1;
}
void loop()
{
// BUTTON 1 - SOLID LIGHT
reading = digitalRead(inPin);
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH){
state = LOW;
btnPress = 1;
}
else{
state = HIGH;
btnPress = 2;
}
time = millis();
}
digitalWrite(outPin, state);
previous = reading;
// BUTTON 2 - GLITTER LIGHT
readingTwo = digitalRead(inPinTwo);
if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
if(state == HIGH){
state = LOW;
btnPress = 3;
}
else{
state = HIGH;
btnPress = 4;
}
time = millis();
}
digitalWrite(outPin,state);
previousTwo = readingTwo;
// BUTTON 3 - MOVEMENT SENSOR LIGHT
readingThree = digitalRead(inPinThree);
if (readingThree == HIGH && previousThree == LOW && millis() - time> debounce){
if(state == HIGH){
state = LOW;
btnPress = 5;
}
else{
state = HIGH;
btnPress = 6;
}
time = millis();
}
digitalWrite(outPin,state);
previousThree = readingThree;
//BUTTON 1 - SOLID LIGHT
if (btnPress == 1){
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();Serial.println("pressed1");
}
if (btnPress == 2){
fill_solid(leds,NUM_LEDS,0xFfffff);
FastLED.show();Serial.println("pressed2");
}
// BUTTON 2 - GLITTER LIGHT
if (btnPress == 3){
fill_solid(leds,NUM_LEDS,CRGB::Black);
FastLED.show();Serial.println("pressed3");
}
if (btnPress == 4){
fadeToBlackBy( leds, NUM_LEDS, 10);
addGlitter(30);Serial.println("pressed4");
FastLED.show();
}
// BUTTON 3 - MOVEMENT SENSOR LIGHT
if (btnPress == 5){
fill_solid(leds,NUM_LEDS,CRGB::Black);Serial.println("pressed5");
FastLED.show();
}
if (btnPress == 6){
Serial.println("pressed6");
}
}
//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
if( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB::White;}
}
loop()
block .... keep track of thecurrent state
and theprevious state
(use the button presses to change thestate
variables .... run the LED control blocks depending on thestate
variablesstate = 1
... at beginning of loop() read button ... if it is pressed then incrementstate
... now the LEDs ... if state==1, run button1 code ... if state==2, run button1.else code and set state=3 ... if state==3, run button2 code ... if state==4, run button2.else code and set state=5 .... similarly for the rest of the code