HI,
I wonder if someone could assist please.
I have some code using an ESP32 with 2 hardware buttons. Essentially when the device is powered on, you are given a small menu that states Button 1 runs a program and Button 2 shows the voltage of the device. A long (2 sec) press of Button 2 puts the device into deep sleep.
It all sort of works, however when Button 1 is pressed, the main program only runs once. If I press Button 1 again, it runs again and so on.
What is the best method to introduce another loop into 'second_loop()' so that it runs continuously if Button 1 is pressed once or until Button 2 is pressed again please.
Code snipet below of main parts and structure.
Many thanks ![]()
#include <TFT_eSPI.h>
//#define TFT_BL 4 // Display backlight control pin
#define ADC_EN 14
#define ADC_PIN 34
#define BUTTON_1 35
#define BUTTON_2 0
Button2 btn1(BUTTON_1);
Button2 btn2(BUTTON_2);
char buff[512];
int vref = 1100;
int btnCick = false;
void showVoltage()
{
static uint64_t timeStamp = 0;
if (millis() - timeStamp > 1000) {
timeStamp = millis();
uint16_t v = analogRead(ADC_PIN);
float battery_voltage = ((float)v / 4095.0) * 2.0 * 3.3 * (vref / 1000.0);
String voltage = "Voltage :" + String(battery_voltage) + "v";
Serial.println(voltage);
tft.fillScreen(TFT_BLACK);
tft.setTextDatum(MC_DATUM);
tft.setTextSize(2);
tft.drawString(voltage, tft.width() / 2, tft.height() / 2 );
}
}
void button_init()
{
btn1.setLongClickHandler([](Button2 & b) {
btnCick = false;
int r = digitalRead(TFT_BL);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.setTextDatum(MC_DATUM);
tft.setTextSize(1);
tft.drawString("Press again to wake up", tft.width() / 2, tft.height() / 2 );
espDelay(6000);
digitalWrite(TFT_BL, !r);
tft.writecommand(TFT_DISPOFF);
tft.writecommand(TFT_SLPIN);
//After using light sleep, you need to disable timer wake, because here use external IO port to wake up
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
// esp_sleep_enable_ext1_wakeup(GPIO_SEL_35, ESP_EXT1_WAKEUP_ALL_LOW);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0);
delay(200);
esp_deep_sleep_start();
});
btn1.setPressedHandler([](Button2 & b) {
Serial.println("Detect Voltage..");
btnCick = true;
});
btn2.setPressedHandler([](Button2 & b) {
btnCick = false;
Serial.println("btn press begin second loop");
second_loop();
});
}
void button_loop()
{
btn1.loop();
btn2.loop();
}
void setup() {
pinMode(ADC_EN, OUTPUT);
digitalWrite(ADC_EN, HIGH);
button_init();
esp_adc_cal_characteristics_t adc_chars;
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars); //Check type of calibration value used to characterize ADC
if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
Serial.printf("eFuse Vref:%u mV", adc_chars.vref);
vref = adc_chars.vref;
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
Serial.printf("Two Point --> coeff_a:%umV coeff_b:%umV\n", adc_chars.coeff_a, adc_chars.coeff_b);
} else {
Serial.println("Default Vref: 1100mV");
}
// Rest of Setup Code
}
void loop()
{
if (btnCick) {
showVoltage();
}
button_loop();
}
void second_loop()
{
tft.setTextDatum(TL_DATUM);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextColor(TFT_DARKGREY, TFT_BLACK);
tft.drawString("Build - ", 5, 115, 2);
tft.drawString((char *) build_date, 55, 115, 2);
// Main Second Loop Code
}