Problem With Code Controlling LED brightness with single pushbutton

Hello this is not my code, it is a code copied out of a book to learn arduino called Getting Started with Arduino by Massimo Banzi. I believe it is copied perfectly except for me giving a few variables different names. It functions but not quite as he described it. It is supposed to turn off when you press the button. When you press it momentarily it turns back on, and when you hold it down, it adjusts the brightness until you let it go. My Mega board isn't doing this. When the light is on, it is constantly fading from 0 brightness to 255 and back to 0 and repeats. When you press the button it turns off. When you press it again, it simply returns to the fading state but the duration of the hold doesn't seem to change anything.

Here is the code:

const int LED = 3;
const int BUTTON = 7;
int val = 0;
int oldVal = 0;
int state = 0;
int brightness = 128;
unsigned long startTime = 0;

void setup(){
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT);
void loop(){
  val = digitalRead(BUTTON);
  if((val == HIGH) && (oldVal == LOW)){
      state = 1 - state;
      startTime = millis();
  if((val == HIGH) && (oldVal == HIGH)){      //this seems to the line not working in the code because if you take it out, it still function in the same, incorrect way
                                              //this should be only true when the button is held down, therefore only adjusting the brightness when you are pressing the button, but
                                              //it seems to act as if it is always true
    if(state == 1 && (millis() - startTime) > 500){
      if (brightness > 255){
        brightness = 0;
  oldVal = val;
  if(state == 1){
    analogWrite(LED, brightness);
    analogWrite(LED, 0);

Any help is greatly appreciated.
Thanks in advance!

Sounds like your button is wired backwards. You can fix that by re-wiring or you can just reverse all the boolean expressions having to do with the button.

I am not sure this was the issue. Based on the code ardunio is correctly reading the button when it changes from open to closed and changing accordingly. It just is just incorrectly entering the if loop involving val and oldVal. I did try to reverse the button but this didn't help. Thank you though

The code is valid. I don't see any differences from the example in the book?

Maybe you forgot a pull up resistor?

I went ahead and built this just to test it, and if I build it the way it's shown in the book, my button is indeed backwards - the line goes LOW when the button is held down. Knowing that... I was able to make the code work by basically reversing the HIGHs and LOWs....

#define LED 9 // the pin for the LED 
#define BUTTON 7 // input pin of the pushbutton

int val = 0; // stores the state of the input pin
int old_val = 0; // stores the previous value of "val" 
int state = 0; // 0 = LED off while 1 = LED on
int brightness = 128; // Stores the brightness value
unsigned long startTime = 0; // when did we begin pressing?

void setup() {
  pinMode(LED, OUTPUT); // tell Arduino LED is an output 
  pinMode(BUTTON, INPUT); // and BUTTON is an input 

void loop() {
  val = digitalRead(BUTTON); // read input value and store it 

  // check if there was a transition 
  if ((val == LOW) && (old_val == HIGH)) {
    state = 1 - state; // change the state from off to on

    startTime = millis(); // millis() is the Arduino clock

  // check whether the button is being held down 
  if ((val == LOW) && (old_val == LOW)) {
    // If the button is held for more than 500ms.
    if (state == 1 && (millis() - startTime) > 500) {
      brightness++; // increment brightness by 1
      delay(10); // delay to avoid brightness going
      // up too fast
      if (brightness > 255) brightness = 0;
  old_val = val; // val is now old, let’s store it 
  if (state == 1) { 
    analogWrite(LED, brightness);
  } else { 
    analogWrite(LED, 0); // turn LED OFF 

Thank you very much. It worked now. I also figured out I did have the polarity backwards but at the time I didn't know how to correctly reverse it. Thanks for your help.

To reverse it, basically you just move the resistor to the other side... (middle of the page where it says "Pullup Resistors" subject header.)

I would like to use the internal pull ups for this but don't want to risk a short, so I do it the way it is in the book.