No single press response and delayed long press

Hello there. I am am working on a motorbike dashboard that is going to have a clock that is run in the RTC memory so it still calculates even as it is in deep sleep. But I also want to have two buttons, one to increment the hours and one to increment the minutes.

The buttons worked first when i was using millis to test out the buttons (i know millis doesn't hold time in deep sleep). But when i moved on to use RTC memory, buttons stopped working properly. my program doesn't detect the press and release of the individual buttons, then when i do long press on either it takes a second before the increments start to happen and then continue for a second after I let go.

would really appreciate some advice or tips on this, still relatively new to this.

thank you

==My Current Code==

#include <Wire.h>
#include <LiquidCrystal.h>
#include <driver/twai.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>
#include <esp_sleep.h>
#include <esp32/rtc.h>

#define LCD_RS 13
#define LCD_EN 12
#define LCD_D4 11
#define LCD_D5 10
#define LCD_D6 9
#define LCD_D7 6

#define BUTTON1_PIN 18
#define BUTTON2_PIN 2

#define ACC_PIN 4

LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);

unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
const unsigned long debounceDelay = 100;
const unsigned long longPressDelay = 500;

RTC_DATA_ATTR int hour = 0;
RTC_DATA_ATTR int minute = 0;
RTC_DATA_ATTR int cHour = 0;
RTC_DATA_ATTR int cMinute = 0;
RTC_DATA_ATTR unsigned long lastClockUpdate = 0;
RTC_DATA_ATTR int lastDisplayHour = -1;
RTC_DATA_ATTR int lastDisplayMinute = -1;

bool button1State = HIGH;
bool button2State = HIGH;
bool lastButton1State = HIGH;
bool lastButton2State = HIGH;
bool button1Pressed = false;
bool button2Pressed = false;

const unsigned long repeatInterval = 200;

unsigned long button1PressTime = 0;
unsigned long button2PressTime = 0;
unsigned long lastRepeat1 = 0;
unsigned long lastRepeat2 = 0;
bool button1AutoRepeat = false;
bool button2AutoRepeat = false;

#define DS18B20_PIN 39
OneWire oneWire(DS18B20_PIN);
DallasTemperature sensors(&oneWire);

void enterDeepSleepOnAcc() {
    lastClockUpdate = esp_timer_get_time();
    //this function controls deep sleep
    esp_sleep_enable_ext0_wakeup((gpio_num_t)ACC_PIN, 1);
    Serial.println("Entering Deep Sleep, Waiting on ACC HIGH");
    lcd.clear();
    lcd.print("Sleep...");
    lcd.clear();
    delay(500);
    esp_deep_sleep_start();
}

void updateClockFromRtc() {
    int64_t now = esp_timer_get_time();
    int64_t elapsed = now - lastClockUpdate;
    if (elapsed > 0) {
        int minutesPassed = elapsed / 60000000LL;
        if (minutesPassed > 0) {
            cMinute += minutesPassed;
            if (cMinute > 59) {
                cHour += cMinute / 60;
                cMinute = cMinute % 60;
            }
            if (cHour > 23) {
                cHour = cHour % 24;
            }
            lastClockUpdate = now - (elapsed % 60000000LL);
        }
    }
}

void displayLcdScreen() {
    //get the temprature to display
    sensors.requestTemperatures();
    float tempC = sensors.getTempCByIndex(0);

    //format for the display
    //for the clock
    if (cHour != lastDisplayHour || cMinute != lastDisplayMinute) {
        lcd.setCursor(0, 0);
        char clock[6];
        snprintf(clock, sizeof(clock), "%02d:%02d", cHour, cMinute);
        lcd.print(clock);
        lcd.print("     ");
    }

    //for the temp sensor
    lcd.setCursor(0, 1);
    lcd.print("T:");
    lcd.print(tempC, 1);
    lcd.print("    ");
}

void setup() {
    Serial.begin(115200);
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);

    pinMode(BUTTON1_PIN, INPUT_PULLUP);
    pinMode(BUTTON2_PIN, INPUT_PULLUP);
    pinMode(ACC_PIN, INPUT);

    if (lastClockUpdate == 0) {
        cHour = hour;
        cMinute = minute;
        lastClockUpdate = esp_timer_get_time();
    }
    else {
        updateClockFromRtc();
    }


    if (digitalRead(ACC_PIN) == LOW) {
        enterDeepSleepOnAcc();
    }
}

void loop() {
    unsigned long currentMillis = millis();

    if (digitalRead(ACC_PIN) == LOW) {
        enterDeepSleepOnAcc();
    }

    bool reading1 = digitalRead(BUTTON1_PIN);
    bool reading2 = digitalRead(BUTTON2_PIN);

    updateClockFromRtc();
    displayLcdScreen();

    // --- Button 1 (Hour) ---
    if (reading1 != lastButton1State) {
        lastDebounceTime1 = currentMillis;
    }

    if ((currentMillis - lastDebounceTime1) > debounceDelay) {
        if (reading1 == LOW) {
            if (!button1Pressed) {
                button1Pressed = true;
                button1PressTime = currentMillis;
                button1AutoRepeat = false;
            }
            else {
                if (!button1AutoRepeat && (currentMillis - button1PressTime >= longPressDelay)) {
                    cHour = (cHour + 1) % 24;
                    lastClockUpdate = esp_timer_get_time();
                    button1AutoRepeat = true;
                    lastRepeat1 = currentMillis;
                    Serial.println("Button 1 Long Press Start");
                }
                else if (button1AutoRepeat && (currentMillis - lastRepeat1 >= repeatInterval)) {
                    cHour = (cHour + 1) % 24;
                    lastClockUpdate = esp_timer_get_time();
                    lastRepeat1 = currentMillis;
                    Serial.println("Button 1 Auto Repeat");
                }
            }
        }
        else if (button1Pressed) {
            // Button was released
            button1Pressed = false;
            if (!button1AutoRepeat) {
                cHour = (cHour + 1) % 24;
                lastClockUpdate = esp_timer_get_time();
                Serial.println("Button 1 Short Press");
            }
            button1AutoRepeat = false;
        }
    }

    // --- Button 2 (Minute) ---
    if (reading2 != lastButton2State) {
        lastDebounceTime2 = currentMillis;
    }

    if ((currentMillis - lastDebounceTime2) > debounceDelay) {
        if (reading2 == LOW) {
            if (!button2Pressed) {
                button2Pressed = true;
                button2PressTime = currentMillis;
                button2AutoRepeat = false;
            }
            else {
                if (!button2AutoRepeat && (currentMillis - button2PressTime >= longPressDelay)) {
                    cMinute = (cMinute + 1) % 60;
                    lastClockUpdate = esp_timer_get_time();
                    button2AutoRepeat = true;
                    lastRepeat2 = currentMillis;
                    Serial.println("Button 2 Long Press Start");
                }
                else if (button2AutoRepeat && (currentMillis - lastRepeat2 >= repeatInterval)) {
                    cMinute = (cMinute + 1) % 60;
                    lastClockUpdate = esp_timer_get_time();
                    lastRepeat2 = currentMillis;
                    Serial.println("Button 2 Auto Repeat");
                }
            }
        }
        else if (button2Pressed) {
            button2Pressed = false;
            if (!button2AutoRepeat) {
                cMinute = (cMinute + 1) % 60;
                lastClockUpdate = esp_timer_get_time();
                Serial.println("Button 2 Short Press");
            }
            button2AutoRepeat = false;
        }
    }

    // Only update state after processing
    lastButton1State = reading1;
    lastButton2State = reading2;
}

What is shown when you display the value read from the buttons?

do you expect millis() to work in deep sleep? doesn't your code rely on millis() while in deep sleep?

only for the buttons for when it is out of deep sleep. otherwise i am trying to use RTC memory

so the Serial monitor doesn't show that the buttons have been pressed or released individually. but do show the long press serial print in the monitor.

as for the LCD screen, nothing happens when an individual press is made but when you hold down the buttons then changes happen after a delayed time with the hours and minutes going up depending on which button you are holding down. then when you let go, it delays and continues to increment the clock for like a second after

Why are not able to add code to show those values so you can debug your program?

but the button code relies on millis() to run

I have. I have serial print for when the buttons are pressed (when they go LOW cause i have them on pullup) and then other code that prints a different message when they are released (as in when they detect as HIGH) but neither messages go to the serial monitor what I am having issues with is I cannot figure out why. I tried having copilot and Chatgpt to give it a look but they gave some updated code which is what is above and it didn't change anything.

    unsigned long currentMillis = millis();

    if (digitalRead(ACC_PIN) == LOW) {
        enterDeepSleepOnAcc();
    }

    bool reading1 = digitalRead(BUTTON1_PIN);
    bool reading2 = digitalRead(BUTTON2_PIN);

    updateClockFromRtc();

    displayLcdScreen();

    // Debounce button 1
    if (reading1 != lastButton1State) {
        lastDebounceTime1 = currentMillis;
    }
    if ((currentMillis - lastDebounceTime1) > debounceDelay) {
        if (reading1 != button1State) {
            button1State = reading1;
            if (button1State == LOW && !button1Pressed) {
                button1Pressed = true;
                button1Held = currentMillis; // Start timing
                Serial.println("Button 1 Pressed!");
            }
            if (button1State == HIGH && button1Pressed) {
                button1Pressed = false;
                cHour++;
                if (cHour > 23) cHour = 0;
                lastClockUpdate = esp_timer_get_time();
                Serial.println("Button 1 Released!");
            }
        }
    }

    if ((currentMillis - lastDebounceTime1) > longPressDelay) {
        // While button 1 is held, increment and print every interval
        if (button1Pressed && button1State == LOW) {
            if (currentMillis - button1Held >= debounceDelay) {
                cHour++;
                if (cHour > 23) cHour = 0;
                lastClockUpdate = esp_timer_get_time();
                button1Held = currentMillis; // Reset for next interval
            }
        }
   }

    // Debounce button 2
    if (reading2 != lastButton2State) {
        lastDebounceTime2 = currentMillis;
    }
    if ((currentMillis - lastDebounceTime2) > debounceDelay) {
        if (reading2 != button2State) {
            button2State = reading2;
            if (button2State == LOW && !button2Pressed) {
                button2Pressed = true;
                button2Held = currentMillis; // Start timing
                Serial.println("Button 2 Pressed!");
            }
            if (button2State == HIGH && button2Pressed) {
                button2Pressed = false;
                cMinute++;
                if (cMinute > 59) cMinute = 0;
                lastClockUpdate = esp_timer_get_time();
                Serial.println("Button 2 Released!");
            }
        }
    }

    if ((currentMillis - lastDebounceTime2) > longPressDelay) {
        // While button 2 is held, increment and print every interval
        if (button2Pressed && button2State == LOW) {
            if (currentMillis - button2Held >= debounceDelay) {
                cMinute++;
                if (cMinute > 59) cMinute = 0;
                lastClockUpdate = esp_timer_get_time();
                button2Held = currentMillis; // Reset for next interval
            }
        }
   }

    lastButton1State = reading1;
    lastButton2State = reading2;
}```

this was my loop before where it wasn't detecting my buttons going LOW

thanks for any responses. managed to figure things out. seems the temp sensor code was slowing things down cause i hadn't attached a temp sensor yet. I apologise for taking up your time and thank you

I am not going to try to compete with them, so good luck and goodby.