2

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!

VE7JRO
2,51519 gold badges27 silver badges29 bronze badges
asked Sep 1, 2019 at 0:25
5
  • 1
    do all of the button reading, debouncing and processing at the beginning of the loop() block .... keep track of the current state and the previous state (use the button presses to change the state variables .... run the LED control blocks depending on the state variables Commented Sep 1, 2019 at 2:20
  • I already use the button presses to change the state variables and the LEDS depending on them. Maybe I misunderstand your comment? Commented Sep 2, 2019 at 23:19
  • read the comment up to the first .... Commented Sep 3, 2019 at 3:29
  • 1
    this rough idea uses only one button ... read button only at begining of loop() ... expand it to your liking with more buttons ....use a state variable with 6 states ... in setup state = 1 ... at beginning of loop() read button ... if it is pressed then increment state ... 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 Commented Sep 3, 2019 at 4:01
  • 1
    thanks for expanding your comment jsotola. I'll test it out and post progress. Commented Sep 4, 2019 at 19:56

1 Answer 1

2

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;}
}
answered Sep 6, 2019 at 20:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.