Look at the Bounce2 library. It does the button debouncing without using delay()...
#define SCR_WD 128
#define SCR_HT 160
#include <SPI.h>
#include <Adafruit_GFX.h>
#if (__STM32F1__) // bluepill
#define TFT_CS PA2
#define TFT_DC PA1
#define TFT_RST PA0
//#include <Arduino_ST7735_STM.h>
#else
#define TFT_CS 8
#define TFT_RST 7 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 6
#include <Arduino_ST7735_Fast.h>
#endif
#include <Bounce2.h>
Arduino_ST7735 lcd = Arduino_ST7735(TFT_DC, TFT_RST, TFT_CS);
byte menuPos, menuScreen, markerPos, menuStartAt;
const char* const menu[12] PROGMEM = {"Binary to Decimal", "Binary to Octal", "Binary to Hexa Deci", "Decimal to Binary", "Decimal to Ocatl", "Decimal to Hexa Deci", "Octal to Binary",
"Octal to decimal", "Octal to Hexa Deci", "Hexa-Decimal to Binary", "Hexa-Decimal to Ocatl", "Hexa-Deci to Decimal"
};
byte MENU_LENGTH = sizeof(menu) / sizeof(menu[0]);
#define btnEnt 4
#define btnUp 3
#define btnDwn 2
#define MENU_ROW_HEIGHT 12
#define LCD_ROWS 12
Bounce2::Button buttonEnter = Bounce2::Button();
Bounce2::Button buttonUp = Bounce2::Button();
Bounce2::Button buttonDown = Bounce2::Button();
const int debounceTime = 10;
void setup() {
Serial.begin(9600);
//pinMode(btnUp, INPUT_PULLUP);
//pinMode(btnDwn, INPUT_PULLUP);
//pinMode(btnEnt, INPUT_PULLUP);
buttonEnter.attach( btnEnt, INPUT_PULLUP );
buttonEnter.interval(debounceTime); // debounce time, ms
buttonEnter.setPressedState(LOW); // INPUT_PULLUP means LOW == pressed
buttonUp.attach( btnUp, INPUT_PULLUP );
buttonUp.interval(debounceTime); // debounce time, ms
buttonUp.setPressedState(LOW); // INPUT_PULLUP means LOW == pressed
buttonDown.attach( btnDwn, INPUT_PULLUP );
buttonDown.interval(debounceTime); // debounce time, ms
buttonDown.setPressedState(LOW); // INPUT_PULLUP means LOW == pressed
lcd.init();
lcd.fillScreen(BLACK);
delay(2000);
showMenu();
}
void loop() {
// update button state every time through loop
buttonEnter.update();
buttonUp.update();
buttonDown.update;
if (buttonDown.pressed()) {
if (menuPos < MENU_LENGTH - 1) {
menuPos++;
if (menuPos - menuStartAt > 12 )
menuStartAt++;
showMenu();
}
}
if (buttonUp.pressed()) {
if (menuPos > 0) {
menuPos--;
if (menuPos - menuStartAt < 0 && menuStartAt != 0)
menuStartAt--;
showMenu();
}
}
if (buttonEnter.pressed()) {
Serial.print("Running test "); Serial.println(menuPos);
switch ( menuPos ) {
case 0: test0(); break;
//case 1: test1(); break;
//case 2: test2(); break;
//case 3: test3(); break;
//case 4: test4(); break;
//case 5: test5(); break;
//case 6: test6(); break;
//case 7: test7(); break;
//case 8: test8(); break;
//case 9: test9(); break;
//case 10: test10(); break;
//case 11: test11(); break;
//case 12: test12(); break;
}
}
}
void showMenu() {
for (byte i = menuStartAt; i < (menuStartAt + LCD_ROWS); i++) {
byte markerY = (i - menuStartAt) * MENU_ROW_HEIGHT;
if (i == menuPos) {
lcd.setTextColor(BLACK);
lcd.fillRect(0, markerY, lcd.width(), MENU_ROW_HEIGHT, GREEN);
}
else {
lcd.setTextColor(WHITE);
lcd.fillRect(0, markerY, lcd.width(), MENU_ROW_HEIGHT, BLACK);
}
if (i >= MENU_LENGTH)
continue;
lcd.setCursor(3, markerY + 2);
lcd.print((char*)pgm_read_word(&(menu[i])));
}
}
void test0() {
lcd.fillScreen(BLACK);
lcd.setTextColor(WHITE);
lcd.setCursor(1, 1);
lcd.println(F("Waiting to \nregister sim \ncard"));
delay(3000);
showMenu();
}