Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Hold button to fade LED in and out which runs only once irregardless of hold length

Patrick398

New Member
Greetings.
Apologies for the stupidly simple question but rest assured i have been at this for days and have searched high and low across the internet.
I just want to fade an LED in and out while a button is being pressed. How long it takes the LED to fade in and out is dictated by a potentiometer. When the button is released the LED should reset to OFF irregardless of where it is in the fade in/out cycle.
The code i have so far does most of this but instead of resetting to OFF when the button is released it stays at whatever brightness it was at.
Also when the button is held for longer than a full fade in/out cycle it keeps repeating where as i just want it to happen once irregardless of how long the button is held. It seems so simple but my brain is melting. Any advice would be greatly appreciated!


Code:
int outputPin = 1;
int buttonPin = 0;
int fadeAmount;
int potVal;
bool wasPressed = false;


void setup() {
  pinMode(outputPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  digitalWrite(outputPin, LOW);

}

void loop() {

  potVal = analogRead (2); // read pot on attiny pin 3
  fadeAmount = map (potVal, 0, 1023, 20, 500);

  if (digitalRead(buttonPin) == LOW) {
    delay(15);
    if (digitalRead(buttonPin) == LOW) {
      wasPressed = true;


      if (wasPressed == true) {
        fadeLights();
      }
      if (wasPressed == false) {


        digitalWrite(outputPin, LOW);

      }
    }
  }

}


void fadeLights() {


  for ( int i = 0; i <= 255; i++) {
    analogWrite(outputPin, i);
    for ( int y = 0; y < fadeAmount; y++) {
      // if button is released
      if (digitalRead(buttonPin) == HIGH) {
        return;
      }
    }
  }

  for ( int i = 255; i >= 0; i--) {
    analogWrite(outputPin, i);
    for ( int y = 0; y < fadeAmount; y++) {
      // if button is released
      if (digitalRead(buttonPin) == HIGH) {
        digitalWrite (outputPin, LOW);
        return;
      }
    }
  }

}
 

danadak

Active Member
Just a thought but doing a flow graph rapidly reveals where flags are needed
for things like current state, button release, display update.....

I am somewhat dyslexic, and often wrestle with getting flags right in a design. Then
I do what I should have in the beginning, a flow chart. Or a state transition table so
from a current state you know what has to be done next as a result of a trigger event.

In your case you could have flags for ramp up, ramp down, trigger ramp, button set,
button release, button transitioning, fade in progress or complete.......and act off those accordingly.

Regards, Dana.
 
Last edited:

rjenkinsgb

Well-Known Member
Most Helpful Member
You have this line

if (wasPressed == false) {

inside this IF section:
if (digitalRead(buttonPin) == LOW) {
delay(15);
if (digitalRead(buttonPin) == LOW) {
wasPressed = true;

So it can never normally execute.

Move it to after the large IF section so its executed if the button is not pressed.

That should get you a bit further.

If you want it to not repeat, add something like
while (wasPressed) ;

before the end of the IF block, so it cannot exit until the button is released.
 

Patrick398

New Member
Thank you so much for the replies. That was really helpful and definitely made me think through things more clearly. After a bit more fiddling i've got what i'm after. I'll post it here in case it's useful to anybody else searching for the same thing in the future.
Thanks again!

Code:
int outputPin = 1;
int buttonPin = 0;
int fadeAmount;
int potVal;
bool wasPressed = false;




void setup() {
  pinMode(outputPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  digitalWrite(outputPin, LOW);

}

void loop() {

  potVal = analogRead (2); // read pot on attiny pin 3
  fadeAmount = map (potVal, 0, 1023, 20, 500); // map pot value to desired LED fade in/out speed

  if (digitalRead(buttonPin) == LOW) {
    delay(15);
    if (digitalRead(buttonPin) == LOW) {
      wasPressed = true; // trigger is detected



      if (wasPressed = true) {
        fadeLights(); // if trigger is detected run the fadelights code

        while (digitalRead(buttonPin) == LOW) {} //wait until there is another high to low transistion so
                                                // fade in/out only happens once

      }

    }

  }


}






void fadeLights() {


  for ( int i = 0; i <= 255; i++) { // start counter for brightness
    analogWrite(outputPin, i);
    for ( int y = 0; y < fadeAmount; y++) { //counter for fade amount
      // if button is released
      if (digitalRead(buttonPin) == HIGH) {
        delay (10);
        if (digitalRead (buttonPin) == HIGH) { // if button is released write output pin LOW
          digitalWrite(outputPin, LOW);;
          return;
        }
      }
    }
  }

  for ( int i = 255; i >= 0; i--) {
    analogWrite(outputPin, i);
    for ( int y = 0; y < fadeAmount; y++) {
      // if button is released
      if (digitalRead(buttonPin) == HIGH) {
        delay (10);
        if (digitalRead (buttonPin) == HIGH) {
          digitalWrite (outputPin, LOW);
          return;

        }
      }
    }
  }

}
 

Latest threads

EE World Online Articles

Loading
Top