Button Dual function Problem

Hi guys, perhaps someone can help me. i have been hitting my head against the wall with something that should be quite simple.. I am a beginner in coding, so please be gentle :slight_smile:
Here is the problem what I want to do.
as soon as i press the button, the led should turn ON.
If it is a short press, the Led should change state to OFF. But if I keep the button pressed longer, the led should turn off as soon as I release the button.
Also, if the led is ON, it should turn OFF if I keep the button presses longer and then release it.

I have it nearly working like this, but there is a little problem. after power ON, the first short press turns the led ON and OFF. it doesn't latch.. next short presses the led behave as it should.
if i press the button long and the led was OFF, it turns ON, release it, the led turns OFF. next short press the led turns ON.. this is normal.
But if I press the button long when the led is already ON, release the button, the led turns OFF, but next short press the led turns ON and OFF, just like at power ON.. I don't know where the problem is..
here is the code. Thanks in advance for your help.. still a lot to learn :slight_smile:


// detectButtonPress
// Use millis to detect a short and long button press
// See baldengineer.com/detect-short-long-button-press-using-millis.html for more information
// Created by James Lewis
const byte led = 0;
const unsigned long shortPress = 20;
const unsigned long  longPress = 500;
bool ledState = true;

typedef struct Buttons {
    const byte pin = 4;
    const int debounce = 20;
    unsigned long counter=0;
    bool prevState = NOT_PRESSED;
    bool currentState;
} Button;
// create a Button variable type
Button button;
void setup() {
  pinMode(led, OUTPUT);
  pinMode(button.pin, INPUT_PULLUP);
void loop() {
    // check the button
    button.currentState = digitalRead(button.pin);
    // has it changed?
    if (button.currentState != button.prevState) {
        // update status in case of bounce
        button.currentState = digitalRead(button.pin);
        if (button.currentState == PRESSED) {
           digitalWrite(led, HIGH);
            // a new press event occured
            // record when button went down
            button.counter = millis();
        if (button.currentState == NOT_PRESSED) {
            // but no longer pressed, how long was it down?
            unsigned long currentMillis = millis();
            if ((currentMillis - button.counter >= shortPress) && !(currentMillis - button.counter >= longPress)) {
                // short press detected. 
                ledState = !ledState;
                digitalWrite(led, ledState);
            if ((currentMillis - button.counter >= longPress)) {
                // the long press was detected
                digitalWrite(led, LOW); 
        // used to detect when state changes
        button.prevState = button.currentState;

Well, it looks like I might have solved the problem.. I would still like you guys to have a look at the code because I am sure that what I did is correct, even if it seems to work :slight_smile: What i changed.

bool ledState = false; // changed it to "false"

This solved the problem at startup

if ((currentMillis - button.counter >= longPress)) {
                // the long press was detected
                digitalWrite(led, LOW); 
               [b] ledState = false;[/b]

Added the last line.. it solved the problem of the next short press after the button was held long when the LED was already ON.. it looks like I was telling the LED to turn OFF but somehow the code didn't know that it turned OFF.. :slight_smile:

Thank You

Any comments will be much appreciated..

Hello there!

Glad you found the problem. When you encounter a code problem, it often helps to draw out a flowchart of what the program is doing, and another of what you want it to do. See if there are any differences between them, and correct it.

I am really new to this.. Thanks for the tip..
This is still not complete. I still want some other functionality. working on it right now :slight_smile: