#105Iniciante

Controle de LED com botão no ESP32 (alternância)

Cada vez que o botão é pressionado, o estado do LED muda: se estiver aceso, apaga; se estiver apagado, acende. É o padrão clássico de alternância. Com debounce, eliminamos o ruído mecânico dos contatos do botão para garantir uma única mudança a cada pressionamento.

4.6(39)
57 concluído
Controle de LED com botão no ESP32 (alternância)
Pressione o botão uma vez e o LED acende; pressione de novo e ele apaga, como o interruptor de luz da sua casa. O ESP32 detecta o momento exato do pressionamento e ignora as pequenas oscilações dos contatos do botão, garantindo uma única mudança por vez. Aqui você aprende a lógica do botão liga/desliga presente em quase todo dispositivo.

Vídeo

Esquema do circuito

Controle de LED com botão no ESP32 (alternância) - Circuit

Código-fonte

C++ (Arduino IDE)
1// ─────────────────────────────────────────
2//   BlueGrays · bluegrays.com
3//   Controle de LED com botão no ESP32 (alternância)
4// ─────────────────────────────────────────
5// Cada aperto do botão alterna o LED: aceso vira apagado, apagado vira
6// aceso. Um debounce de 50 ms garante que um aperto dê exatamente uma
7// troca.
8//
9// Pinos:
10//   GPIO 5 -> LED vermelho (com resistor de 220 ohm)
11//   GPIO 4 -> Botão (outra perna no GND)
12
13const int LED_PIN = 5;      // Saída do LED
14const int BUTTON_PIN = 4;   // Entrada do botão
15
16bool ledState = false;               // O LED está aceso agora
17bool lastButton = HIGH;              // Leitura anterior do botão
18bool stableButton = HIGH;            // Estado estável do botão (após debounce)
19unsigned long lastChange = 0;        // Última vez que a leitura mudou (ms)
20const unsigned long DEBOUNCE = 50;   // Tempo de debounce (ms)
21
22void setup() {
23  pinMode(LED_PIN, OUTPUT);
24  pinMode(BUTTON_PIN, INPUT_PULLUP);  // Lê HIGH quando não está pressionado
25}
26
27void loop() {
28  bool buttonState = digitalRead(BUTTON_PIN);
29
30  // Reinicia o temporizador sempre que a leitura muda
31  if (buttonState != lastButton) lastChange = millis();
32
33  // Uma leitura que fica igual por DEBOUNCE ms conta como estável. O LED alterna uma vez, só quando
34  // o estado estável vira LOW (um novo aperto).
35  if (millis() - lastChange > DEBOUNCE && buttonState != stableButton) {
36    stableButton = buttonState;
37    if (stableButton == LOW) {
38      ledState = !ledState;
39      digitalWrite(LED_PIN, ledState);
40    }
41  }
42  lastButton = buttonState;
43}
44

Perguntas frequentes

Qual deve ser o tempo de debounce?

Para a maioria dos botões, 20–50 ms são suficientes. Se o tempo for curto demais, as oscilações dos contatos ainda serão detectadas; se for longo demais, pressionamentos rápidos e consecutivos não serão detectados.

Qual estado devo detectar para alternar o LED?

Detecte apenas o instante em que o botão é pressionado (a transição de HIGH para LOW, se estiver usando INPUT_PULLUP). Para evitar que o LED alterne repetidamente enquanto o botão estiver pressionado, armazene o estado anterior do botão em uma variável.

É correto usar `delay()` para debounce?

Funciona em projetos simples, mas delay() pausa a execução atual de loop(), atrasando outras operações no mesmo fluxo. Outras tarefas do ESP32 podem continuar em execução. A temporização com millis() é adequada para executar operações dentro de loop() sem bloqueá-lo.

É possível lembrar o último estado do LED após desligar e ligar?

Sim, no ESP32, você pode usar a biblioteca Preferences para gravar o estado na memória não volátil e lê-lo na inicialização. Assim, mesmo que a alimentação seja interrompida e volte, o LED inicia no último estado.