Проблемы с таймером на millis() и кнопкой

Добрый день. Начал изучать программирование на ESP32, из учебных примеров сваял вот такую программку (прошу не кидать тапками, я прям новичок новичком):

#include <GyverOLED.h>

#include

GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;

int bStatus;

int emptyVal=0;

unsigned long timerPrev=0;

unsigned long timerNow;

bool state=false;

bool stateP=false;

bool stateN=true;

String text1, text2;

//функция вкл./выкл. светодиода

void ledSwitch(int num){

bool sw;

if (digitalRead(num)==1) digitalWrite(num, LOW);

else digitalWrite(num,HIGH);

}

void setup() {

pinMode(13,INPUT);

pinMode(25,OUTPUT);

digitalWrite(13,HIGH);

oled.init(21,22); // инициализация

oled.clear(); // очистка

oled.setScale(3); // масштаб текста (1..4)

oled.home(); // курсор в 0,0

oled.print(“Привет!”);

delay(1000);

oled.setScale(1);

// курсор на начало 3 строки

oled.setCursor(0, 3);

oled.print(“GyverOLED v1.3.2”);

// курсор на (20, 50)

oled.setCursorXY(20, 50);

float pi = 3.14;

oled.print("PI = ");

oled.print(pi);

}

void loop() {

bStatus=digitalRead(13); //при каждом цикле опрашивается состояние кнопки на пине 12

if (digitalRead(13)==HIGH){

stateP=!stateP;

stateN=!stateN;

timerNow=millis();

}

if (digitalRead(13)==LOW && timerNow-timerPrev>=100) { //если с момента таймерСейчас прошло 30млс и статус кнопки отпущена

//while (digitalRead(12)!=LOW) emptyVal=0;

text1=“timer=”+timerNow;

text2=“previous timer=”+timerPrev;

timerPrev=millis(); //сообщаем переменной прошлыйТаймер текущую точку времени

stateP=!stateP;

stateN=!stateN;

oled.clear();

oled.home();

oled.setScale(1);

oled.print(millis()/1000);

oled.print(" sec");

} //обнуляется состояние кнопки

}

Почему то кнопка срабатывает ровно до тех пор, пока не пройдет 130 секунд, после чего перестает реагировать вообще. Подскажите, в какую сторону копать?

При работе с кнопками важно отслеживать не столько текущий статус кнопки, сколько его изменение. Это общее замечание.

А теперь постарайтесь внятно объяснить, что делает ваша программа

по нажатию кнопки выводит на OLED-экран количество секунд, прошедших со старта программы. Через 130 секунд на экране появляется надпись “130 sec” и кнопка перестает реагировать.
За совет насчет изменения статуса - спасибо, буду копать в эту сторону. Подозреваю, не до конца я от дребезга избавился.

а пи зачем ?

Осталось из учебного примера.

Попробуйте закомментировать весь вывод на дисплей, секунды выводите в сериал.
Т.е. , разберитесь с кнопкой отдельно

P.S. А без Гайвера - работает!(не удержался, подкинул код в симуляторе))

P.P.S. @Bludkot , кнопка хоть и работает, но очень “кривая”.
@v258 очень хорошо разбирается в кнопках, советую прислушаться

Уберите все лишнее. Из этого блока, например,

int bStatus;
int emptyVal = 0;
unsigned long timerPrev = 0;
unsigned long timerNow;
bool state = false;
bool stateP = false;
bool stateN = true;
String text1, text2;

реально используется только timerPrev и timerNow, за каким лешим остальные захламляют код - неясно. Уберите их - разбираться в коде и искать ошибки логики будет гораздо проще.

Далее. Посмотрите на строку

bStatus=digitalRead(13); //при каждом цикле опрашивается состояние кнопки на пине 12

Кнопку нужно опрашивать только ОДИН раз за проход loop(), вы же делаете это три раза (и еще один раз закомментирован). Зачем вы считываете состояние в bStatus? Используйте ее вместо всех дальнейших digitalRead(13)

И третье - что мешает вам использовать готовую кнопочную библиотеку? Весь ваш код при этом сведется к нескольким строкам

С Гайвером, тоже, кстати, работает, если кнопку слишком часто не нажимать.

Спойлер

Но, если кнопку быстро нажать несколько раз - дисплей начинает глючить. Что говорит скорее не о кривой библиотеке дисплея, а о кривом коде, и, плохой обработке нажатий кнопки.

Не в этом проблема, но не надо так делать.

Спасибо всем, советы я учту, особенно про кнопки.
Ответы на некоторые вопросы:
Почему не использовать готовые библиотеки для кнопок?
Я только начал учиться и на момент написания темы не знал, точнее не подумал для них. Плюсом я старался понять подобное на простом уровне, чтобы знать, а не составлять библиотеки как кубики лего.
Кривой код.
Да, я знаю. Я - не волшебник, я только учусь.

Для кнопки есть библиотека от гайвера.
По большому счету она нафиг не нужна, но на одну кнопку можно назначить много действий.
Много действий нафиг не нужно, достаточно трёх-четырёх.
Поэтому я использую однократное, двух и трёхкратные нажатие для разных действий.
Типа так.
1 клик - влючить-выключить,
2 клика - следующее действие/трек/режим,
3 клика - запуск обновления прошивки.
Кнопка должна быть сенсорная.
Разберись с этой библой и пользуйся вечно.

1 лайк

Их вагон и маленькая тележка ))

2 лайка

Похоже, найден рецепт вечной жизни

5 лайков

Было бы у всех так просто.

1 лайк

А люди хотят кнопки. В уже готовых ус-вах кроме кнопок ничего нет. Да и не нужно там ничего кроме.

На практике ни кнопки, ни экраны не нужны
:wink:

Интересно, и кто придумал клавиатуры с 102 кнопками, если единственный вариант управления - одной кнопкой.

упс, НЕ потерялось

Ну это же НЕ единственный вариант управления устройствами.
Если требуется сложное управление всегда есть другие варианты…
Сенсорный экран с виртуальным кнопками.
Вэб страничка с возможностями, ограниченные лишь фантазиенй и возможносями html и скиптов.
Пульты радио, ик, блюпуп…
Да мля даже голосовое управление через алису не сложно прикрутить.

Что мешает поднять жопу с дивана и сделать?