ESP32 и библиотечки кнопок

Наткнулся на то что запуске с ESP32 (конкретно использовалась плата ESP32 DEVKIT V1 ) библиотечка EncButton2 отрабатывает криво (в варианте с EncButton - аналогично). Короткие нажатия на кнопку она вообще не видит. Если делать более длительные нажатия (что-то вроде секунды), то клики, хоть и криво, начинают выводятся. Закомментированный кусок кода в конце скетча - вообще не отрабатывает…

С платой Аrduino Nano V3 все работает нормально.

Arduino IDE 2.0.4
EncButton 2.0.0

Пробовал использовать другую библиотечку - OneButton. С ней все примерно аналогично.
Как все же это дело можно заставить правильно работать с ESP32?

// Определение кнопок EncButton
#include <EncButton.h>

#define BTN_AMOUNT 3
#if defined(ESP32)
#define BTN_PWD1 4
#define BTN_PWD2 2
#define BTN_KDAV 15
#elif defined(ARDUINO_AVR_NANO)
#define BTN_PWD1 PD3
#define BTN_PWD2 PD4
#define BTN_KDAV PD5
#endif

EncButton<EB_TICK, BTN_PWD1> btnPWD1;
EncButton<EB_TICK, BTN_PWD2> btnPWD2;
EncButton<EB_TICK, BTN_KDAV> btnKDAV;

void setup() {
  Serial.begin(115200);

  Serial.println("Started");
}

void loop() {
  uint8_t noClick;
  uint8_t indBtn;

    btnPWD1.tick();
    btnPWD2.tick();
    btnKDAV.tick();

  // Serial.print(digitalRead(BTN_PWD1));Serial.print("-");
  // Serial.print(digitalRead(BTN_PWD2));Serial.print("-");
  // Serial.println(digitalRead(BTN_KDAV));

   if (btnPWD1.click()) Serial.println("Button PWD1 Click");
   if (btnPWD2.click()) Serial.println("Button PWD2 Click");
   if (btnKDAV.click()) Serial.println("Button KDAV Click");

  // for (indBtn = 0; indBtn < BTN_AMOUNT; indBtn++) {
  //   noClick = btn[indBtn].hasClicks();
  //   if (noClick > 0) {
  //     Serial.print("Button ");
  //     Serial.print(indBtn);
  //     Serial.print(" Click ");
  //     Serial.println(noClick);
  //   }
  // }
}

Попробуйте эту. Правда, с ESP32 я ее не тестировал, но с ESP8266 работает нормально

Любопытные определения. Кто вас учил делать так?

Ну, я уже несколько лет не брал в руки шашечки… Согласен, так делать неверно - на момент написания ошибку осознал, просто не подкорректировал свой пример. Но, в конкретном случае, к ошибке подобная запись не приводит.

Вашу библиотечку попробовал. Работает лучше прочих. Но… Глотает нажатия. Причем больше одиночные. Вот, смотрите на видео. То что кнопка срабатывают видно по отсвету красного светодиодика (в данном случае используются сенсорные, что планирутся переделать).

Меня вот что смущает - и те что я использовал ведь должны нормально работать - в интернете есть примеры с ними и ESP32. Про какую-то несовместимость нигде не упоминается. Используемый тип ESP-шки тоже самый обычный.

На какую-то неисправность ESP-шки я не грешу - других проблем с ней не было замечено…

От библиотеки зависит. Что там автор накропал …

Здесь он пины определяет

Сейчас проверить не могу, в процессе переезда, все свое барахло уже отвез, а сам еще тут )) Но такого быть действительно не должно. Для сенсорных кнопок можно еще интервал антидребезга установить нулевой

Кстати, уже пробовал - безразлично.

Весь проект сделан, работает, только физические кнопки остались. Нужны отработки нажатий, вплоть до тройных и удержание…

ESP8266 у меня есть, но Bluetooth-а у нее нет, а смысл использования ESP32 был именно в нем.

Пока остается Arduino Nano как запасной вариант в котором работают все кнопочные библиотеки - от него я хотя бы по USB к компу подключусь…

а можно схемку глянуть, уж не в “подтяжках” ли дело?

Кнопки на данный момент сенсорные - их подтягивать не надо. Да и все библиотечки по умолчанию включают подтяжку. Так что резисторов в схеме вообще нет. Есть лишь 1 кондер параллельно кнопке сброса, чтобы у данного модуля ESP32 работал автосброс при загрузке скетча…

А что обработка кнопок на ЕСП32 сильно отличается от обработки кнопок на других МК ?
В чем принципиальные различия ?

Есть принципиальные отличия у этой драной ESP32 по приоритету тасков, например. Дефолтовый таск в IDLE priority. И его может прижать к полу любой другой процесс.

Сейчас только чуть не нажрался - моргалка в одиночку нормально работает, а как побольше задач назапускаешь - все, крендец. Встать может просто посреди цикла (к примеру). Без всяких пояснений. А потом продолжить через случайный интервал.

Появляется понимание, что многозадачность - круто, но имеет “подводные камни”? Начинаем изучать приоритеты, семафоры, очереди и прочие мьютексы! :wink: :wink:

Нормальный контроллер, а ЕСП32 из них почти самый маленький, это уже не счет тактов и не ногодрыг, а вот-это-вот-всё. Точно как на писюке.
Любители Асма и ногодрыга - остаются на АВР. Кстати многие его именно за это и любят. Я без сарказма.


По сути: используй таскКриейтПиннедТоКор. И все задачи, которые хочешь видеть предсказуемыми вешай не на то ядро. на котором ВиФи. И разбери их по приоритетам.
А вместе с ВиФи вешай всякий сервис, который может быть прерван без вреда. Например вообще всё сетевое. И сервер и МКТТ и телеграм клиент и что-там еще есть у тебя. Тогда ядро без ВиФи ты увидишь более предсказуемым.

Сорри. а то многие меня алкашом считают! путаница запятых. точек, больших и маленьких букв связана с тем, что на кухне у меня клава залита всем, чем можно и нельзя и правый шифт почти не работает. Поэтому часто точка вместо запятой выходит.
Еще раз - Сорри!

Да я уже и с тасками и с очередями, но по-старинке - без дилэев. Тут-то и вляпался… Каждая задача на себя одеяло тащит и никому не отдаёт. Пришлось натыкать в лупы…

1 лайк

Я вроде писал об этом. Если ты предпочитаешь форум докам от Еспрессив. :wink: Первым оператором в for(;;) {} надо ставить delay(1).
И последним, после цикла vTaskDelete(NULL);

Исправил. Все оказалось довольно просто - была неверная инициализация класса в случае использования сенсорных кнопок. Сама по себе ESP32 была вообще не причем.

#include <OneButton.h>

#if defined(ESP32)
#define BTN_ACTIVE 0  // Сенсорные модули TTP223 (перемычки по умолчанию)
#define BTN_PWD1 4
#define BTN_PWD2 2
#define BTN_KDAV 15
#elif defined(ARDUINO_AVR_NANO)
#define BTN_ACTIVE 1  // Обычные кнопки от пина на землю
#define BTN_PWD1 3
#define BTN_PWD2 6
#define BTN_KDAV 7
#endif

OneButton btnPWD1(BTN_PWD1, BTN_ACTIVE);
OneButton btnPWD2(BTN_PWD2, BTN_ACTIVE);
OneButton btnKDAV(BTN_KDAV, BTN_ACTIVE);

void setup() {
  Serial.begin(115200);

  // Аттачим функции кнопки PWD1
  btnPWD1.attachClick(clickPWD1);
  btnPWD1.attachDoubleClick(doubleClickPWD1);
  btnPWD1.attachMultiClick(multiClickPWD1);
  btnPWD1.attachLongPressStart(longPressStartPWD1);
  btnPWD1.attachLongPressStop(longPressStopPWD1);

  // Аттачим функции кнопки PWD2
  btnPWD2.attachClick(clickPWD2);
  btnPWD2.attachDoubleClick(doubleClickPWD2);
  btnPWD2.attachMultiClick(multiClickPWD2);
  btnPWD2.attachLongPressStart(longPressStartPWD2);
  btnPWD2.attachLongPressStop(longPressStopPWD2);

  // Аттачим функции кнопки KDAV
  btnKDAV.attachClick(clickKDAV);
  btnKDAV.attachDoubleClick(doubleClickKDAV);
  btnKDAV.attachMultiClick(multiClickKDAV);

  Serial.println("Started");
}

void loop() {
  btnPWD1.tick(); btnPWD2.tick(); btnKDAV.tick();

//  Serial.println(digitalRead(BTN_PWD1));
}

// Функции обработки нажатий кнопки PWD1
void clickPWD1() {
  Serial.println("Button PWD1 1 click.");
}  // clickPWD1
void doubleClickPWD1() {
  Serial.println("Button PWD1 2 click.");
}  // doubleClickPWD1
void multiClickPWD1() {
  if (btnPWD1.getNumberClicks() != 3) return;
  Serial.println("Button PWD1 3 click");
}  // multiClickPWD1
void longPressStartPWD1() {
  Serial.println("Button PWD1 longPress start");
}  // longPressStartPWD1
void longPressStopPWD1() {
  Serial.println("Button PWD1 longPress stop");
}  // longPressStopPWD1

// Функции обработки нажатий кнопки PWD2
void clickPWD2() {
  Serial.println("Button PWD2 1 click.");
} // clickPWD2
void doubleClickPWD2() {
  Serial.println("Button PWD2 2 click.");
} // doubleClickPWD2
void multiClickPWD2() {
  if (btnPWD2.getNumberClicks() != 3) return;
  Serial.println("Button PWD2 3 click");
} // multiClickPWD2
void longPressStartPWD2() {
  Serial.println("Button PWD2 longPress start");
} // longPressStartPWD2
void longPressStopPWD2() {
  Serial.println("Button PWD2 longPress stop");
} // longPressStopPWD2

// Функции обработки нажатий кнопки KDAV
void clickKDAV() {
  Serial.println("Button KDAV 1 click.");
} // clickKDAV
void doubleClickKDAV() {
  Serial.println("Button KDAV 2 click.");
} // doubleClickKDAV
void multiClickKDAV() { // Заглушка. Чтобы убрать лишние клики
  if (btnKDAV.getNumberClicks() >= 3) return;
} // multiClickKDAV

Если интересен немного другой подход, можно тут почитать