Flickering LED

This is a total noob question and I'm not sure if this is exactly the right place to ask it but here it goes.

I have a very simple setup with my arduino where I have one push button as an input and one LED as an output. When the button is pushed, I use a loop with analogWrite to gradually light up the LED as long as the button is pushed. As soon as the button is let go, the LED gradually dims until it turns off. So I can, for example, push the button until the LED lights up half way and then let it go and the LED will dim until it turns off, or until I push the button again to get it to become brighter again.

I'm 99% of the way there. I can get the LED to behave exactly the way I want it to, with one exception. Only when the LED is completely off and I push the button, the LED quickly blinks at full brightness for a moment before returning to being near off and slowly turning on as it should. I've included my code below:

const int button1Pin = 2;  // pushbutton 1 pin
const int ledPin =  11;    // LED pin
int y=0;

void setup()
{
  // Set up the pushbutton pins to be an input:
  pinMode(button1Pin, INPUT);

  // Set up the LED pin to be an output:
  pinMode(ledPin, OUTPUT);      
}


void loop()
{
  int button1State;  // variables to hold the pushbutton states

  button1State = digitalRead(button1Pin); // puts power level of button 1 into variable

   if (button1State == LOW) //if button1 is pushed
    { 
    while(y<=255 && button1State== LOW) //while LED is not fully lit and button 1 is pushed
    {
      analogWrite(ledPin, y);  // turn the LED on gradually
      delay(10);
      button1State = digitalRead(button1Pin); //check state of button
      y++; //step up y to increase brightness
    }
  }
  else
  {
    while(y>=0 && button1State==HIGH) //while LED is not completely off and button 1 is not pushed
    {
      analogWrite(ledPin, y);  // turn the LED on
      delay(10);
      button1State = digitalRead(button1Pin); //check state of button
      y--; //step down y to decrease brightness
    }
  }
}

Any help would be greatly appreciated. Thanks!

A quick question: What's the purpose of the while loop? The second condition would always be true. The first condition may be causing problems, because even if the LED is always increasing in brightness when you push the button.
I'm not sure if i'm able to explain it that well... but if you need a better e xplanation just ask...

P.S. no question is shameful/noob-ish. We all have first times! :slight_smile:

Hi! Thanks for the help!
My thought with that while loop you were talking about is that, I think that without the second condition, when I let go of the button, the brightness of the LED will keep increasing until it reaches maximum brightness. My thought was that because of that second condition, when I let go of the button, the loop will stop running and then go back to running void loop().

I'm not sure that I quite understand what you're saying about the first condition. I was playing with my circuit a little more and I've realized that there are in fact two problems.

One was the problem I described earlier where, only when the LED is completely turned off, the LED blinks before behaving as it should. I've found that the reverse is the case as well. When the LED is completely lit up and I let go of the button, the LED will momentarily flicker off before returning to full brightness and dimming down. Neither of these things happens when I push or let go of the button when the LED is at any brightness other than full brightness or no brightness. In these cases, the LEDs light up just as I would expect.

As a matter of interest, do you have the button connected with a resistor to pull it the other way when it's not pressed, like shown here or is it floating?

You might also find it useful in problems like this to adopt the approach shown co-incidentally in the link of using Serial to print various things back to the monitor on your PC so that you can see where in the code it really is at any instant, and what the values of variables are.

analogWrite(ledPin, y); // turn the LED on
delay(10);
button1State = digitalRead(button1Pin); //check state of button
y--; //step down y to decrease brightness
if (y<0) y=0; //<<<<<<<<<<<<<< insert this line
}
}
}

Try the above added line.
You are at -1 when you let go of the button.

You are at -1 when you let go of the button.

..... which you would have seen if you were sending "y" to the monitor :stuck_out_tongue:

while(y<=255 && button1State == LOW) //while LED is not fully lit and button 1 is pushed
{
analogWrite(ledPin, y); // turn the LED on gradually
delay(10);
button1State = digitalRead(button1Pin); //check state of button
y++; //step up y to increase brightness
Serial.println(y); //<<<<<<<< use Serial.print for debugging
}
}
else
{
while(y>=0 && button1State==HIGH) //while LED is not completely off and button 1 is not pushed
{
analogWrite(ledPin, y); // turn the LED on
delay(10);
button1State = digitalRead(button1Pin); //check state of button
y--; //step down y to decrease brightness
if (y<0) y=0; // Comment this line to see the problem on the serial monitor
Serial.println(y); //<<<<<<<< use Serial.print for debugging

Use Serial.println() to aid in troubleshooting code.

Your over complicating this. And make your button default low and make IF statement look for HIGH.
If button is high, increment counter (global var), send to LED.

Else button is low, decrement counter(same counter as before, starting point for decrement), send to LED.

Set limits, if counter < 0, set to zero. If counter > 255, set to 255.

Easy.

Edit: add debounce if needed.

Thanks for your help guys!

JimboZA, I do have a resistor connected to the button. Your advice about using Serial is definitely something I'm going to start doing! I hadn't gotten to the point in the tutorial where they introduced me to that yet, but I evidently already need it!

LarryD, thanks so much. I puzzled over this for a few minutes and I think I sort of understand why it's doing this.

Am I understanding things correctly if I say that with the analogWrite function, if I do analogWrite(LEDPin, 256), that is the same thing as analogWrite(LEDPin, 0)?

I still do not quite understand why the LED blinks. In particular, I understand that when I run through my while loops, the one with y++ leaves me with a final value of 256 (one more than 255) if I keep holding it and the while loop with y-- has a final value of -1 if I leave the button unpressed for long enough. The thing I'm puzzled about is why does this flickering happen the very first time that I press the button? I would have thought that since I set y=0 at the very start, that at least the first time, the loop would start with a value of y=0 and not a value of y=-1

HazardsMind, I think I understand what you're saying, and the thought had briefly flickered through my mind when I was thinking of another mini-project I wanted to work on. If I understand you correctly, you are saying that I can ditch my two while loops. Does that sound right?

Thanks for the help everyone!

I would have thought that since I set y=0 at the very start, that at least the first time, the loop would start with a value of y=0 and not a value of y=-1

..... All the more reason to implement Serial asap, then you can see if what you think is the same as the Arduino thinks 8)

There are multiple ways of doing this, once you get better at coding, you'll see just how many ways there are.

I would use If/else statements that way I can change the button state at any time.

You guys were all so helpful. Thanks so much!

Note:
analogWrite(ledPin, y); // turn the LED on >>>> if y=-1 this is the same as y=255 full bright

if y=-255 this is the same as y=0 full off
This function will operate on 0 to 255 and on 0 to -255
Since you were at -1 the LED was full bright for a split second.
When y was was incremented it went from -1 full bright to 0 full off.
Hence there was a short flash when you first pushed the button.

You only set y=0 in setup() this runs once at the start of the sketch.

the one with y++ leaves me with a final value of 256

No. y-- gave you the -1