Program to toggle L...
 
Notifications
Clear all

Program to toggle LED state with a single button?

1 Posts
2 Users
0 Reactions
2,289 Views
0
Topic starter

I'm working on an Arduino project where I need a single pushbutton to toggle between two states (like turning an LED ON and OFF) each time it's pressed. However, I'm running into issues where the button press either doesn't register correctly or rapidly toggles due to bouncing.

I've tried using digitalRead() in a simple if condition, but I suspect I need to debounce the button properly. Should I use delay(), or is there a better approach using millis()?

Here’s my basic code:

const int buttonPin = 2;
const int ledPin = 13;
bool ledState = false;

void setup() {
    pinMode(buttonPin, INPUT);
    pinMode(ledPin, OUTPUT);
}

void loop() {
    if (digitalRead(buttonPin) == HIGH) {
        ledState = !ledState;
        digitalWrite(ledPin, ledState);
        delay(200); // Debounce delay?
    }
}

Is there a more reliable way to debounce the button and avoid unwanted toggling? Any guidance would be appreciated!


1 Answer
0

It looks like the issue with your code is the button bouncing and the lack of state change detection. When you press the button, it may rapidly switch between HIGH and LOW due to mechanical bouncing, causing multiple unwanted toggles.

Problems in Your Code:

  • No Debouncing – The delay(200); tries to debounce but isn't ideal because it blocks the loop and prevents the Arduino from doing anything else during that time.
  • Direct Button Read Without Edge Detection – Since you're checking digitalRead(buttonPin) == HIGH, if you hold the button down even slightly too long, it keeps toggling instead of switching just once per press.

Try the program given below.

Better program to toggle LED state with a single button:

const int buttonPin = 2;
const int ledPin = 13;
bool ledState = false;
bool lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;

void setup() {
    pinMode(buttonPin, INPUT);
    pinMode(ledPin, OUTPUT);
}

void loop() {
    bool buttonState = digitalRead(buttonPin);

    // Check if button state has changed
    if (buttonState != lastButtonState) {
        lastDebounceTime = millis();  // Reset debounce timer
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
        // Only toggle if the button state is HIGH
        if (buttonState == HIGH) {
            ledState = !ledState;
            digitalWrite(ledPin, ledState);
        }
    }

    lastButtonState = buttonState;  // Update last button state
}

 

Why this program works:

  • Proper Debouncing: Uses millis() instead of delay() to wait until the button is stable.
  • Edge Detection: Toggles the LED only when the button changes from LOW to HIGH, preventing multiple triggers from a single press.
  • Non-Blocking: The Arduino can perform other tasks while waiting for a button press.

Let me know if you face any issues.


Share: