Fundamentos · 3 min de leitura

Como ligar um botão no Arduino: pull-up, pull-down e debounce

Como ligar um botão no Arduino? O interior de um botão de 4 terminais, resistores de pull-up e pull-down, INPUT_PULLUP, debounce e um exemplo que alterna um LED.

O botão é o componente mais simples para levar o toque do usuário a um projeto com Arduino. Pressionado, ele une dois contatos; solto, ele os separa. Por mais simples que pareça, se for ligado errado ele lê valores aleatórios ou conta um único toque várias vezes. Neste guia mostramos como ligar e ler um botão do jeito certo.

Botão de pressão
Chave tátil de 4 terminais. Os terminais são ligados internamente aos pares.

Por dentro de um botão de 4 terminais

O botão tátil de 6×6 mm, o que você mais vai usar na protoboard, tem 4 terminais, mas só 2 pontos de conexão: os pares de terminais opostos já são ligados internamente. Pressionar o botão une os dois pares. Se você encaixar o botão atravessado sobre o canal central da protoboard, cada par cai em fileiras separadas e fica fácil acertar a posição.

Se você não tem certeza da posição, coloque o multímetro em continuidade: os terminais que apitam sem pressionar são um par já ligado. Os terminais que só apitam ao pressionar são os que o botão chaveia.

Por que você precisa de um resistor de pull-up ou pull-down?

Quando o botão não está pressionado, o pino de entrada do Arduino não está ligado a nada; isso se chama entrada flutuante. Um pino assim capta ruído elétrico e lê valores HIGH ou LOW aleatórios. A solução é puxar o pino para um nível fixo através de um resistor:

MétodoLigaçãoSoltoPressionado
Pull-down10 kΩ do pino → GND, botão do pino → 5VLOWHIGH
Pull-up (externo)10 kΩ do pino → 5V, botão do pino → GNDHIGHLOW
INPUT_PULLUP (interno)Botão do pino → GND, sem resistorHIGHLOW

O jeito mais prático é pinMode(pin, INPUT_PULLUP): o resistor interno do Arduino, de cerca de 20–50 kΩ, é ativado e você só liga o botão entre o pino e o GND. A única diferença é que a lógica fica invertida: um toque é lido como LOW.

Debounce: por que um toque é contado várias vezes?

No instante em que os contatos metálicos do botão se tocam, eles vibram por alguns milissegundos e o circuito abre e fecha muitas vezes. Como o Arduino lê muito rápido, ele pode ver um toque como 3–5 toques. Isso se chama repique de contato (bounce). Para resolver no software, novas mudanças são ignoradas por cerca de 50 ms após a última mudança.

C++ (Arduino IDE)
1const int BUTTON_PIN = 2;   // buton pin ile GND arasında / button between pin and GND
2const int LED_PIN = 13;     // karttaki LED / onboard LED
3
4bool ledOn = false;
5int lastReading = HIGH;
6int stableState = HIGH;
7unsigned long lastChange = 0;
8
9void setup() {
10  pinMode(BUTTON_PIN, INPUT_PULLUP); // dahili pull-up / internal pull-up
11  pinMode(LED_PIN, OUTPUT);
12}
13
14void loop() {
15  int reading = digitalRead(BUTTON_PIN);
16  if (reading != lastReading) lastChange = millis();   // değişti / changed
17  if (millis() - lastChange > 50 && reading != stableState) {
18    stableState = reading;                              // 50 ms kararlı / stable for 50 ms
19    if (stableState == LOW) {                           // basıldı / pressed
20      ledOn = !ledOn;                                   // LED'i değiştir / toggle LED
21      digitalWrite(LED_PIN, ledOn ? HIGH : LOW);
22    }
23  }
24  lastReading = reading;
25}

Este código alterna o LED uma vez a cada toque; segurar o botão não fica alternando. Como usa millis() em vez de delay(), o loop nunca fica esperando e pode fazer outras tarefas ao mesmo tempo.

Erros comuns

  • Colocar o botão na posição errada: se você usa um par de terminais já ligado, o botão é lido sempre como pressionado. Gire-o 90°.
  • Não usar resistor: sem pull-up ou pull-down, a leitura muda aleatoriamente.
  • Esperar a lógica errada com INPUT_PULLUP: um toque é lido como LOW, não HIGH; escreva suas condições de acordo.
  • Usar um delay() longo para o debounce: o programa não consegue fazer nada durante esse tempo; temporizar com millis() é melhor.
  • Usar os pinos 34–39 em um ESP32: esses pinos não têm pull-up interno; adicione um resistor externo ou escolha outro pino.

Para posicionar corretamente o botão e o resistor na protoboard, veja O que é protoboard? e, para entender os valores do resistor de pull-up, O que é resistor?.

Perguntas frequentes

Qual resistor eu preciso para um botão?

10 kΩ é o padrão para pull-up ou pull-down. Com INPUT_PULLUP você não precisa de nenhum resistor externo.

Por que o botão é lido como LOW quando pressionado?

Com INPUT_PULLUP ou um pull-up externo, o pino fica normalmente em HIGH; o botão o liga ao GND, então ele é lido como LOW ao ser pressionado. Esse é o comportamento esperado.

Quanto tempo deve ter o debounce?

20–50 ms é suficiente para a maioria dos botões. Botões velhos ou de baixa qualidade podem precisar de 80–100 ms.

Como ler vários botões?

Ligue cada botão a um pino próprio e configure todos como INPUT_PULLUP. Para muitos botões, use um teclado matricial ou leia todos em um único pino analógico com resistores diferentes.

Ver todos os projetos
Controle de LED com botão (momentâneo)
#9Iniciante

Controle de LED com botão (momentâneo)

É como uma campainha: a luz fica acesa enquanto você pressiona o botão e apaga quando você solta. O Arduino monitora o botão continuamente; enquanto ele está pressionado, o LED fica aceso e apaga assi

4.8(113)
229
Ligar e desligar um LED com botão
#10Iniciante

Ligar e desligar um LED com botão

Pressione o botão uma vez para acender a luz e outra vez para apagar, como o interruptor do seu quarto. O Arduino detecta cada toque e inverte o estado do LED, aguardando um breve instante para que as

4.8(100)
167
Piano simples com buzzer e botões
#26Avançado
Premium

Piano simples com buzzer e botões

Monte seu próprio piano com oito botões. Cada botão corresponde a uma nota, da mais grave à mais aguda: dó, ré, mi, fá, sol, lá, si e dó agudo. A nota toca no buzzer enquanto você mantém o botão press

4.9(66)
88
Contador com display de 7 segmentos e botões
#43Avançado
Premium

Contador com display de 7 segmentos e botões

Um contador simples com três botões: ao pressionar um deles, o algarismo no display aumenta em um; com outro, diminui em um; e o terceiro zera a contagem. O display de 7 segmentos de um dígito conta d

4.6(35)
47
Controle de LED com botão no ESP32 (momentâneo)
#104Iniciante

Controle de LED com botão no ESP32 (momentâneo)

O LED acende enquanto o botão está pressionado e apaga ao soltá-lo. Mostra como usar o pino de entrada digital e o resistor pull-up interno do ESP32. O modo INPUT_PULLUP dispensa um resistor externo.

4.6(36)
55
Controle de LED com botão no ESP32 (alternância)
#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
Raspberry Pi Pico: ligar e desligar LED com botão
#156Iniciante

Raspberry Pi Pico: ligar e desligar LED com botão

Botão + LED — próximo nível! Ao contrário do projeto básico de botão, não é preciso manter o botão pressionado. Pressione e solte → LED aceso. De novo → LED apagado (alternância). O circuito é o mesmo (LED no GP14, botão no GP2), mas o código muda bastante. Aprenda detecção de borda (o instante da queda 1→0), rastreamento de estado e debounce (filtro de repique). led.toggle() alterna o estado em uma linha. Base para projetos interativos com botões (seletor de modo, IRQ, clique duplo).

0.0(0)
9
Raspberry Pi Pico: debounce de botão com IRQ ou consulta por software
#159Intermediário
Premium

Raspberry Pi Pico: debounce de botão com IRQ ou consulta por software

Você pressiona o botão uma vez e o código conta 3-4? Isso é oscilação dos contatos — os contatos metálicos oscilam por microssegundos! Compare 2 métodos de contagem lado a lado no Monitor Serial: consulta sem filtro (detecta as oscilações e conta a mais) e IRQ + debounce por software (contagem correta). Aprenda a física da oscilação dos contatos, debounce por software (ticks_diff() > 50ms), registro de interrupção com Pin.irq(), disparo IRQ_FALLING, rotinas ISR, global e…

0.0(0)
12