button switching direction

Hi, I have a problem with some code. It might be very easy to get it sorted but I got stuck.
I have a switch button that triggers 4 LEDs one after another.
When the sequence is completed the direction should revert.
so they have to go from 0 to 3 and when they are at 3 they have to go backwards to 0 and so on.

I am attaching the .ino

If anyone has some hints… it would be great!

Button_disco_AAA_01.ino (2.01 KB)

That seems a lot of code for a very simple task. At the same time it is a short sketch and it would have been easier to read if you had just included it directly in your post.

else if (buttonPushCounter>=4){
       buttonPushCounter=- buttonPushCounter;

Perhaps the second line should be

buttonPushCounter = 0;

...R

I tried that and it didn't work as it was resetting the button. I need to invert direction.
I think I sorted it somehow.
I am not happy with the code as well but for now I think it's ok.
Thanks anyway.

Post your current code with your attempt of inverting the direction.

if (buttonState == HIGH || (millis() - lastDebounceTime) > debounceDelay) {
positionLED += buttonPushCounter; // not =+
buttonPushCounter++; ← Not needed

Right here, positionLED is incrementing by 1 (or it should be). All you need to do is see if positionLED is greater than 3 or less than 0 and if it is multiply buttonPushCounter by -1.

It is that simple.

perhaps try a simpler approach…

const int buttonPin = 7;     // the number of the pushbutton pin CONST IS A CONSTANT THAT USES LESS COMPUTATIONAL POWER
const int ledPins[] ={6,9,10,11};      // the number of each LED pin into the array

int ledDirection = 1;
int lastButtonState;
int positionLED = 0;

unsigned long lastDebounceTime;  // the last time the output pin was toggled
unsigned long debounceDelay = 50UL;    // the debounce time; increase if the output flickers

void setup() 
{
  Serial.begin(9600); 
  for (int i=0; i < 4; i++)
  {
    pinMode(ledPins[i], OUTPUT);      
  }
  pinMode(buttonPin, INPUT); 
}


void loop()
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH && lastButtonState == LOW)
  {
    if (millis() - lastDebounceTime > debounceDelay) 
    {
      lastDebounceTime = millis();
      positionLED += ledDirection;
      if (positionLED == 0 || positionLED == 3) ledDirection = - ledDirection;
      for (int i = 0; i < 4; i++)
      {
        digitalWrite(ledPins[i], (i == positionLED ? HIGH : LOW));
      }
    } 
  }
  lastButtonState = buttonState;
}

Here is the code. I know it’s very ugly and I think there is an easier solution but for today I have to be happy with this.
I am not sure whether the debouncing is in the right place there.
I am just starting with arduino as you can see…

Any help is much appreciated!
smiley

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin = 7;     // the number of the pushbutton pin CONST IS A CONSTANT THAT USES LESS COMPUTATIONAL POWER
const int ledPins[] ={
  6,9,10,11 };      // the number of each LED pin into the array

// variables will change:
int buttonPushCounter = 0;  // counts the number of times I press the button.
int buttonPushDirection = 1;  // counts the number of times I press the button.
int buttonState = 0;         // variable for reading the pushbutton status
int lastButtonState = 0;    // stores the last status of the button
int positionLED=-1;


long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  // initialize the LED pin as an output:
  for (int i=0; i<=3;i++){
    pinMode(ledPins, OUTPUT);      
  }
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  
  // initialize serial communication:
  Serial.begin(9600); 

}

///////////////////////////////////////////////////////////////////////////////////////////

void loop(){

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // if the buttonState is different from the last Status then
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState!=lastButtonState) {
    lastDebounceTime = millis();
    // if button is pressed light is HIGH
    if (buttonState == HIGH || (millis() - lastDebounceTime) > debounceDelay) {
      positionLED+=buttonPushDirection;      
      if(positionLED>3)
      {
        positionLED=2;
        buttonPushDirection=-1;
      }
      if(positionLED<0)
      {
        positionLED=1;
        buttonPushDirection=1;
      }
      buttonPushCounter++;
      // turn LED on:
      digitalWrite(ledPins[positionLED], HIGH);
      Serial.println("on");
      Serial.print("LED on is:  ");
      Serial.println(positionLED);
      Serial.println(buttonPushCounter);
    } 
    else {
      // turn LED off:
      digitalWrite(ledPins[positionLED], LOW);
      Serial.println("off");
      Serial.println(positionLED);
      Serial.println(buttonPushCounter);
    }

  } 

  lastButtonState = buttonState;

}

if (buttonState == HIGH || (millis() - lastDebounceTime) > debounceDelay) {

This will cause problems. Make it && instead

if(positionLED>3)
{
positionLED=2;
buttonPushDirection=-1;
}
if(positionLED<0)
{
positionLED=1;
buttonPushDirection=1;
}

These could be condensed to just:

if(positionLED > 3 || positionLED < 0)
  buttonPushDirection *= -1;

Or you could just use Bulldog’s code.

Thanks to everybody there.
I'll try to have a look at Bulldog's code with more calm tomorrow.
:))

HazardsMind:

This will cause problems. Make it && instead

I tried && before but it gave me trouble.
I eventualy deleted that...
still working on it.

Bulldog code is very nice indeed.

you may be able to get some inspiration from my first Arduino sketch i put together:

http://www.ardiri.com/blog/arduino_my_first_custom_hack

  // iterate forwards through LEDs
  if (g_direction == 1)
  {
    g_led++;

    // have we had a led counter overflow?
    if (g_led == (ledPINBase+ledPINCount)) 
    {
      g_led == (ledPINBase+ledPINCount)-1;
      g_direction = -1;
    }
  }

  // iterate backwards through LEDs
  else
  {
    g_led--;
      
    // have we had a led counter underflow
    if (g_led == (ledPINBase-1)) 
    {
      g_led = ledPINBase;
      g_direction = 1;
    }
  }

effectively; you need a variable that stores your direction and you just invert it depending on your current value (when hit 0 or 3 in your case)