⬤ Iniciante

🔘 Botão de Pressão

⏱️ 25 min 🧩 Botão — Pino D4

Exercícios

📌 Pinagem na placa de interface

MóduloConector InterfacePino ArduinoNotas
🔘 Botão de Pressão BTN D4 Usar INPUT_PULLUP — lógica invertida: LOW = premido
ℹ️
Resistência pull-up interna
Ao declarar o pino com INPUT_PULLUP, o Arduino ativa internamente uma resistência de ~10 kΩ que mantém o pino em HIGH quando o botão está solto. Quando o botão é premido, o pino vai a GND → lê LOW. Esta lógica é invertida: LOW = premido, HIGH = solto.
HIGH → Botão SOLTO — pino puxado para 5V pela pull-up
LOW → Botão PREMIDO — pino ligado a GND

Exercício 1 — Ler estado do botão

Lê o estado do botão e imprime no Monitor Série. Usa o Serial Monitor (115200 baud) para observar a mudança de HIGH para LOW ao premir.

ex1_botao_leitura.ino
#define BOTAO 4

void setup() {
  // INPUT_PULLUP: botão solto = HIGH, premido = LOW
  pinMode(BOTAO, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Botao pronto. Prima para testar.");
}

void loop() {
  int estado = digitalRead(BOTAO);

  if (estado == LOW) {
    Serial.println("PREMIDO");
  } else {
    Serial.println("Solto");
  }
  delay(200);  // Evita inundar o Serial Monitor
}

Exercício 2 — Liga/desliga LED com botão

Enquanto o botão está premido, o LED branco fica ligado. Ao soltar, apaga. Controlo direto — sem estado interno.

ex2_botao_led.ino
#define BOTAO      4
#define LED_BRANCO 5

void setup() {
  pinMode(BOTAO,      INPUT_PULLUP);
  pinMode(LED_BRANCO, OUTPUT);
}

void loop() {
  if (digitalRead(BOTAO) == LOW) {   // Premido
    digitalWrite(LED_BRANCO, HIGH);    // Liga LED
  } else {                              // Solto
    digitalWrite(LED_BRANCO, LOW);     // Apaga LED
  }
}
💡
Nota de leitura: A condição digitalRead(BOTAO) == LOW é equivalente a !digitalRead(BOTAO) — as duas formas funcionam. A primeira é mais legível para iniciantes.

Exercício 3 — Toggle: alternar estado com cada pressão

Um clique liga o LED; outro clique apaga. Este padrão usa uma variável de estado e deteção da borda descendente (transição HIGH→LOW) para evitar múltiplas alterações durante uma única pressão.

ex3_botao_toggle.ino
#define BOTAO      4
#define LED_BRANCO 5

bool ledLigado    = false;
bool estadoAnterior = HIGH;  // Pull-up → começa HIGH

void setup() {
  pinMode(BOTAO,      INPUT_PULLUP);
  pinMode(LED_BRANCO, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  bool estadoAtual = digitalRead(BOTAO);

  // Detetar borda: de HIGH para LOW = nova pressão
  if (estadoAnterior == HIGH && estadoAtual == LOW) {
    ledLigado = !ledLigado;   // Inverte o estado
    digitalWrite(LED_BRANCO, ledLigado ? HIGH : LOW);
    Serial.println(ledLigado ? "LED LIGADO" : "LED APAGADO");
    delay(50);   // Debounce simples
  }

  estadoAnterior = estadoAtual;
  delay(10);
}
ℹ️
Debounce: Os botões mecânicos produzem múltiplos sinais rápidos (bounce) ao ser premidos. O delay(50) após detetar a pressão ignora esses pulsos espúrios. Para projetos mais avançados, usa a biblioteca Bounce2 para debounce robusto sem bloquear o loop.

Exercício 4 — Abrir a porta com o botão (campainha)

Simula a campainha da casa: ao premir o botão toca o buzzer, abre a porta (servo) por 3 segundos e fecha novamente. Combina botão + buzzer + servo.

ex4_botao_campainha.ino
#include <Servo.h>

#define BOTAO   4
#define BUZZER  6
#define SERVO_PORTA 10

Servo portaServo;

void setup() {
  pinMode(BOTAO,  INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  portaServo.attach(SERVO_PORTA);
  portaServo.write(0);    // Porta fechada
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(BOTAO) == LOW) {   // Botão premido
    Serial.println("Campainha! Abrindo porta...");

    // Toca campainha: 3 bips
    for (int i = 0; i < 3; i++) {
      tone(BUZZER, 1000, 150);
      delay(300);
    }

    // Abre porta (servo vai a 90°)
    portaServo.write(90);
    delay(3000);              // Porta aberta 3 segundos

    // Fecha porta
    portaServo.write(0);
    Serial.println("Porta fechada.");
    delay(500);                // Aguarda soltar o botão
  }
}

🏆 Desafios