Bidirectional Variable Speed LED Chaser

Hi all,
I'm doing a project that requires an LED chaser, which has variable speed (via potentiometer) and can have it's direction switched by one or two (ideally two but currently programmed for one) momentary switches. I've never coded before so I've been mixing and matching pre-existing code to get this far, but not sure why the button isn't reversing the direction of the chaser. I'm sure it's just a few simple lines of code I'm missing so if anyone could give me some pointers or even tell me what to add verbatim I'd be grateful and and you will have saved me a huge migraine.


int buttonPin =  13;     // the number of the pushbutton pin
int ledNum = 8;                           // define the number of the LEDs
int ledPin[] = {2, 3, 4, 5, 6, 7, 8, 9};  // create array for LED pins
int delayTime;                     // define a variable for the value of delay
int potPin = A0;                          // define the potentiometer pin
int  initial    = 0;       //hold current  initial
int oldstate    = 0;       //hold last  initial
int buttonstate = 0;      // variable for reading the pushbutton status

void setup() {
  for (int x = 0; x < ledNum; x++) {      // setting all LEDs as OUTPUT
    pinMode(ledPin[x], OUTPUT);
    pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
  }
}

void loop()  {
    //debouncing routline to read button
  buttonstate = digitalRead(buttonPin);  //state the  initial of button
    if(buttonstate == HIGH){               //check if it has been pressed 
    buttonstate = digitalRead(buttonPin);//state button again
    if(buttonstate == LOW){              //if it is 0 considered one press
     initial = oldstate + 1;        //increase  initial by 1
    }
  }else{                          //check if it has been NOT pressed
    delay(100);
      }                  
   switch (initial){               //react to button press a  initial
        case 1:
  for (int i = 0; i < 8; i++)   {
    delayTime = analogRead(potPin);       //getting the time delay from the potentiometer
    digitalWrite(ledPin[i], HIGH);        //turn on LEDs
    delay(delayTime);                     //time inverval
    digitalWrite(ledPin[i], LOW);         //turn off LEDs
    oldstate =  initial;                  //set oldstate  initial as current  initial
      }
      case 2:
  for (int i = 7; i >= 0; i--)   {
    delayTime = analogRead(potPin);       //getting the time delay from the potentiometer
    digitalWrite(ledPin[i], HIGH);        //turn on LEDs
    delay(delayTime);                     //time interval
    digitalWrite(ledPin[i], LOW);         //turn off leds
    oldstate =  initial;}
   }   }

Let's just start from the top. Why do initialize the button pin 'ledNum' times?

you will have saved me a huge migraine

Beginner confusion is not an ailment, it's medicine. This is how people learn.

Why not use the debounce routine from the Arduino digital example sketches instead of the one that is giving you trouble?

If you use pinMode(buttonPin, INPUT_PULLUP); you don't need an external pull-up or pull-down resistor.

You forgot the 'break;' at the end of 'case 1:'. Since you only have two cases, an 'if' might be better than a switch/case.

int buttonPin =  13;     // the number of the pushbutton pin
int ledNum = 8;                           // define the number of the LEDs
int ledPin[] = {2, 3, 4, 5, 6, 7, 8, 9};  // create array for LED pins
int delayTime;                     // define a variable for the value of delay
int potPin = A0;                          // define the potentiometer pin
boolean forward = true;       //hold current  initial
int oldstate    = 0;       //hold last  initial
int buttonstate = 0;      // variable for reading the pushbutton status

void setup()
{
  for (int x = 0; x < ledNum; x++)        // setting all LEDs as OUTPUT
    pinMode(ledPin[x], OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input
}

void loop()
{
  //debouncing routline to read button
  buttonstate = digitalRead(buttonPin);  //state the  initial of button
  if (buttonstate != oldstate)
  {
    oldstate = buttonstate;

    // The button state has changed
    if (buttonstate == LOW)      // if it is 0 considered one press
    {
      forward = ~forward;        // Switch direction
    }
  }

  if (forward)
    for (int i = 0; i < 8; i++)
    {
      delayTime = analogRead(potPin);       //getting the time delay from the potentiometer
      digitalWrite(ledPin[i], HIGH);        //turn on LEDs
      delay(delayTime);                     //time inverval
      digitalWrite(ledPin[i], LOW);         //turn off LEDs
    }
  else // reverse
    for (int i = 7; i >= 0; i--)
    {
      delayTime = analogRead(potPin);       //getting the time delay from the potentiometer
      digitalWrite(ledPin[i], HIGH);        //turn on LEDs
      delay(delayTime);                     //time interval
      digitalWrite(ledPin[i], LOW);         //turn off leds
    }
}

Thanks for your help, I didn't notice those errors in the code, and the structure you suggested does make a lot more sense. Unfortunately for some reason the button still isn't making the pattern direction change. The onboard LED for pin 13 turns off when I press the button so I know there's no wiring issue, so it's still a mystery to me why it's not working.

Is there some sketch we can't see?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.