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,515
  • 19
  • 27
  • 29

1 Answers1

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;}
}