ESP32 - Botão - Debounce

Quando um botão é pressionado/solto ou quando uma chave é alternada entre LIGADO e DESLIGADO, seu estado muda de LOW para HIGH (ou de HIGH para LOW) uma única vez. Isso está correto?

⇒ Não, não está. Isso acontece porque no mundo físico, quando você pressiona um botão uma única vez, o estado do botão alterna rapidamente entre LOW e HIGH várias vezes em vez de uma. Essa é uma característica mecânica e física. Esse fenômeno é conhecido pelo nome de chattering (trepidação). O fenômeno de trepidação faz com que o MCU (por exemplo, o ESP32) leia vários pressionamentos do botão em resposta a um único pressionamento real. Isso resulta em mau funcionamento. O processo para eliminar esse fenômeno é chamado de debounce. Este tutorial mostra como fazer isso.

Fenômeno de trepidação no ESP32

Este tutorial apresenta:

Sobre o Botão

Temos tutoriais específicos sobre o botão. O tutorial contém informações detalhadas e instruções passo a passo sobre a pinagem do hardware, o princípio de funcionamento, a ligação ao ESP32, o código do ESP32... Saiba mais sobre eles nos links a seguir:

Diagrama de Ligação

Diagrama de Ligação do Botão com ESP32

This image is created using Fritzing. Click to enlarge image

Se você não sabe como alimentar o ESP32 e outros componentes, veja as instruções no tutorial a seguir: Como alimentar o ESP32.

Para deixar tudo claro, vamos executar o código do ESP32 SEM e COM debounce, e comparar os resultados

Lendo o Botão sem Debounce

Passos Rápidos

  • Se esta é a primeira vez que você usa o ESP32, veja como configurar o ambiente para o ESP32 no Arduino IDE.
  • Faça a ligação como na imagem acima.
  • Conecte a placa ESP32 ao seu PC por um cabo USB Type-C
  • Abra o Arduino IDE no seu PC.
  • Selecione a placa ESP32 correta (por exemplo, ESP32 Dev Module) e a porta COM.
  • Copie o código abaixo e cole-o no Arduino IDE.
/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-button-debounce */ #define BUTTON_PIN 21 // GIOP21 pin connected to button // Variables will change: int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); if (lastState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if (lastState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last state lastState = currentState; }
  • Compile e faça upload do código para a placa ESP32 clicando no botão Upload no Arduino IDE
Carregar Código no Arduino IDE
  • Abra o Serial Monitor no Arduino IDE
Como abrir o Serial Monitor no Arduino IDE
  • Pressione o botão uma vez, mantenha-o pressionado por alguns segundos e depois solte.
  • Veja o resultado no Serial Monitor. Ele se parece com o abaixo:
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
The button is pressed The button is pressed The button is pressed The button is released The button is released
Ln 11, Col 1
ESP32 Dev Module on COM15
2

⇒ Como você pode ver, você pressionou e soltou apenas uma vez, mas o ESP32 leu vários pressionamentos e solturas.

※ Nota:

O fenômeno de trepidação não acontece todas as vezes. Se ele não acontecer, tente o teste acima várias vezes.

Lendo o Botão com Debounce

Passos Rápidos

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-button-debounce */ #define BUTTON_PIN 21 // GIOP21 pin connected to button #define DEBOUNCE_TIME 50 // the debounce time in millisecond, increase this time if it still chatters // Variables will change: int lastSteadyState = LOW; // the previous steady state from the input pin int lastFlickerableState = LOW; // the previous flickerable state from the input pin int currentState; // the current reading from the input pin // the following variables are unsigned longs because the time, measured in // milliseconds, will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // the last time the output pin was toggled void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch/button changed, due to noise or pressing: if (currentState != lastFlickerableState) { // reset the debouncing timer lastDebounceTime = millis(); // save the the last flickerable state lastFlickerableState = currentState; } if ((millis() - lastDebounceTime) > DEBOUNCE_TIME) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // if the button state has changed: if(lastSteadyState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if(lastSteadyState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last steady state lastSteadyState = currentState; } }
  • Compile e faça upload do código para a placa ESP32 clicando no botão Upload no Arduino IDE
  • Abra o Serial Monitor no Arduino IDE
Como abrir o Serial Monitor no Arduino IDE
  • Mantenha o botão pressionado por alguns segundos e depois solte.
  • Veja o resultado no Serial Monitor. Ele se parece com o abaixo:
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
The button is pressed The button is released
Ln 11, Col 1
ESP32 Dev Module on COM15
2

⇒ Como você pode ver, você pressionou e soltou uma vez, e o ESP32 leu um pressionamento e uma soltura. A trepidação foi eliminada.

Nós Simplificamos - Código ESP32 de Debounce de Botão com Biblioteca

Para facilitar para os iniciantes, principalmente ao fazer o debounce de vários botões, criamos uma biblioteca de botão chamada ezButton. Você pode aprender sobre a biblioteca ezButton aqui.

Código ESP32 de Debounce para um Único Botão

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-button-debounce */ #include <ezButton.h> #define DEBOUNCE_TIME 50 // the debounce time in millisecond, increase this time if it still chatters ezButton button(21); // create ezButton object that attach to pin GPIO21 void setup() { Serial.begin(9600); button.setDebounceTime(DEBOUNCE_TIME); // set debounce time to 50 milliseconds } void loop() { button.loop(); // MUST call the loop() function first if (button.isPressed()) Serial.println("The button is pressed"); if (button.isReleased()) Serial.println("The button is released"); }

Código ESP32 de Debounce para Vários Botões

Vamos escrever o código de debounce para três botões.

O diagrama de ligação

Diagrama de Ligação da Biblioteca de Botão com ESP32

This image is created using Fritzing. Click to enlarge image

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-button-debounce */ #include <ezButton.h> #define DEBOUNCE_TIME 50 // the debounce time in millisecond, increase this time if it still chatters ezButton button1(21); // create ezButton object that attach to pin GPIO21; ezButton button2(22); // create ezButton object that attach to pin GPIO22; ezButton button3(23); // create ezButton object that attach to pin GPIO23; void setup() { Serial.begin(9600); button1.setDebounceTime(DEBOUNCE_TIME); // set debounce time to 50 milliseconds button2.setDebounceTime(DEBOUNCE_TIME); // set debounce time to 50 milliseconds button3.setDebounceTime(DEBOUNCE_TIME); // set debounce time to 50 milliseconds } void loop() { button1.loop(); // MUST call the loop() function first button2.loop(); // MUST call the loop() function first button3.loop(); // MUST call the loop() function first if (button1.isPressed()) Serial.println("The button 1 is pressed"); if (button1.isReleased()) Serial.println("The button 1 is released"); if (button2.isPressed()) Serial.println("The button 2 is pressed"); if (button2.isReleased()) Serial.println("The button 2 is released"); if (button3.isPressed()) Serial.println("The button 3 is pressed"); if (button3.isReleased()) Serial.println("The button 3 is released"); }

Vídeo

Conhecimento Adicional

  • O valor de DEBOUNCE_TIME depende do hardware. Hardwares diferentes podem usar valores diferentes.
  • O debounce também deve ser aplicado para chave liga/desliga, chave de fim de curso, reed switch, sensor de toque ...

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!