1 Push button 2 variabler LED`s

Hello! I am total beginner in Arduino or at programming! Hope you can help me to guide in right direction why i cant get my sketch work.

So my idea is to use one pushbutton witch works as toggle switch to turn LED`s in three conditions, you push once it turn on one LED, push second time, both LEDs turn on and when you push third time both go off, and i want to use millis() for pushbutton debounce and switch case for led state change, but i cant figure out why i can get them turned on, I have multiple times readed and whatched youtube videos of examples of toggle switch, debounce, millis, switch state, but cant figure what I do wrong.

my sketch code:

int ButtonPin = 2;
int LedPin1 = 7;
int LedPin2 = 8;

int LedState = LOW;

int ButtonRead;
int ButtonState = 0;
int ButtonStateOld = 0;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;


void setup() {
  pinMode(ButtonPin, INPUT_PULLUP);
  pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
}

void loop() {
  ButtonRead = digitalRead(ButtonPin);  //Read value form ButtonPin
  if (ButtonRead != ButtonStateOld) {      //check if  ButtonRead differs from ButtonStateOld, check if button is pressed, whent from 111111... to 00000...
    lastDebounceTime = millis();                //if differs start  millis function
    ButtonStateOld = ButtonRead;            //assign 0 to ButtonStateOld 

  }

  if ((millis() - lastDebounceTime) > debounceDelay) {  //if statement fulfilled, that button is still pressed goes to next step
    if (ButtonRead == HIGH && ButtonStateOld  == LOW) { // check if button whent from 1 to 0 back to 1
      if (LedState == LOW) {
        LedState = LedState + 1;
      }

    }

    switch (LedState) {

      case 1:
        digitalWrite(LedPin1, HIGH);
        break;
      case 2:
        digitalWrite(LedPin1, HIGH);
        digitalWrite(LedPin2, HIGH);
        break;
      case 3:
        digitalWrite(LedPin1, LOW);
        digitalWrite(LedPin2, LOW);
        break;
    }

  }
  ButtonStateOld = ButtonRead; //assign 
}

Have you tried serial print debugging?

Also if buttonstate is low that means button pressed and you start with this state

yes, pushbutton gives me 1 or HIGH when not pressed and when I pres it, it gives me 0 or LOW, also LEDs work, if i open button example and change pins to my pins i can turn them on

It looks like your logic is reversed
You can use define to make it easier to read

Welcome to the forum.

Please do not mix HIGH and LOW with integer numbers.
The digitalRead() and digitalWrite() functions use HIGH and LOW.
If you need a number in your sketch, then make a new variable.

The variable names for a pin number can have "Pin" in the name to avoid confusion.

int ButtonPin = 2;                          // push button pin
int Led1Pin = 7;                            // led pin
int Led2Pin = 8;

A value or a state should not have "Pin" in the name. Your "ButtonPinRead" is a value or a state of the button, it does not identify the pin number.

This is good:

if (millis() - lastDebounceTime > debounceDelay)

This is also good:

if ( (millis() - lastDebounceTime) > debounceDelay)

But with this, my brain starts to hurt:

if(((millis() - lastDebounceTime) > debounceDelay))

Try pressing Ctrl+T in the Arduino IDE or right click and Format the text in Wokwi.

Why Tinkercad ? Have you tried Wokwi ?
I did not fix your sketch yet.
Your sketch in Wokwi: ThreeConditions.ino - Wokwi Arduino and ESP32 Simulator

[ADDED]
I just noticed that you have this twice:

ButtonStateOld = ButtonRead;

can you explain a little bit more about reversed logic?

didnt know that, I think that there is no difference between 0 and low, 0 = LOW, ty.

if(((millis() - lastDebounceTime) > debounceDelay))

yes to many () i fixed that, ty.

Tinkercad, just for wiring, i have Elego UNO R3.

this i taked from example in ArduinoIDE => example => 02Digital =>Debounce.

i did find similar code from internt where use delay but what I read delay is not good so i try to use millis(), so here is internet code:

// constants won't change. They're used here to set pin numbers:

const int buttonPin =  4;     // the number of the pushbutton pin

const int ledPin        = 13;      // the number of the LED pin
const int ledPin1      = 12;
const int ledPin2      = 11;

// variables will change:
int  initial    = 0;       //hold current  initial
int oldstate    = 0;       //hold last  initial
int buttonstate = 0;      // variable for reading the pushbutton status

void setup() {
  pinMode(ledPin, OUTPUT);   // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, 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 
    delay(50);
    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:                     //if  initial is 1
       digitalWrite(ledPin, HIGH);//on
       digitalWrite(ledPin1, LOW);//off
       digitalWrite(ledPin2, LOW);//off
       oldstate =  initial;               //set oldstate  initial as current  initial
       break;
     case 2:
       digitalWrite(ledPin, LOW);
       digitalWrite(ledPin1, HIGH);
       digitalWrite(ledPin2, LOW);
       oldstate =  initial;
       break;
     case 3:
       digitalWrite(ledPin, LOW);
       digitalWrite(ledPin1, LOW);
       digitalWrite(ledPin2, HIGH);
       oldstate =  initial;
       break;         
     default:                      //if  initial is not 1 2 3
       digitalWrite(ledPin, LOW);  //off
       digitalWrite(ledPin1, LOW);
       digitalWrite(ledPin2, LOW);
       oldstate = 0;                    //reset to all off/initial 0
       break;         
     }
}

When low is pressed and humans intuitively read high as pressed you can get confused. This is correct in that you use input pull-up and so this logic is blessed but sometimes if you are getting confused it is best to use the #define to change low to Pressed. It is not best practice but avoids confusion sometimes until you get the logic

Can you write two test-sketches ?
One that debounces and one that has three states with the leds.

The sketch for debouncing can show the result in the Serial Monitor. That was already mentioned in the first reply by pmagowan in post #2.

You can try the three states with the leds with a "artificial" button that does not bounce. Go to the project in Wokwi "ThreeConditions.ino", click on the button (while the simulation is not running) and then you see the options for the button. You can turn off the Bounce. Wokwi enables the Bounce by default, it is a pretty bad bounce (or it bounces really good) :face_with_raised_eyebrow: so if you can debounce the button in Wokwi, then the debounce will work in real life.

You have to be logged in in Wokwi to save a copy of my Wokwi project to your own projects and make changes. It is free.

When you combine the sketches, don't combine variables that have different meanings. You have now the same variable to remember the old button state before and after the debouncing.

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