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!

  • 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 – jsotola Sep 1 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? – MorningStar Sep 2 at 23:19
  • read the comment up to the first .... – jsotola Sep 3 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 – jsotola Sep 3 at 4:01
  • 1
    thanks for expanding your comment jsotola. I'll test it out and post progress. – MorningStar Sep 4 at 19:56
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;}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.