Bouncing e Debouncing: Entenda e Resolva Problemas de Ruído nos Botões

Efeito bounce, o que é e como resolver via software

Objetivo

Explicar o conceito de bouncing (ruído gerado nos contatos dos botões) e como ele pode impactar negativamente o funcionamento de projetos com Arduino. O artigo também apresentará o conceito de debouncing, demonstrando como resolver esse problema de maneira eficiente por meio de software.

Serão mostradas três abordagens práticas e detalhadas: duas utilizando as funções nativas do Arduino, delay() e milis(), e uma terceira empregando a biblioteca externa Bounce2. O objetivo é fornecer soluções simples e eficazes, permitindo que o leitor compreenda e aplique o conhecimento em seus próprios projetos.

O que é Bouncing?

O efeito bounce, também conhecido como bouncing, refere-se a um fenômeno físico que ocorre ao pressionar ou soltar um botão. Os contatos metálicos dentro do botão "vibram" por um curto período antes de se estabilizarem, gerando múltiplos sinais ON/OFF em um intervalo de tempo muito curto (alguns milissegundos). Esses sinais podem ser interpretados erroneamente pelo Arduino como várias entradas, quando na verdade era esperado apenas um único comando.

O bouncing, ou "oscilações elétricas", ocorre principalmente em componentes que possuem contatos mecânicos, ou seja, em partes que se conectam fisicamente para completar um circuito, sendo eles:

  • Botões (Push Buttons): Os botões mecânicos são os componentes mais comuns onde o bouncing acontece. Quando pressionamos ou soltamos um botão, os contatos metálicos dentro dele não se conectam ou se desconectam de maneira instantânea. Em vez disso, ocorre uma série de rápidas oscilações (liga/desliga) antes que o contato se estabilize.

  • Chaves (Switches e Toggle Switches): As chaves mecânicas (como as de alavanca ou deslizantes) também apresentam bouncing devido à mesma razão: seus contatos metálicos oscilam ao mudar de posição. Apesar de menos perceptível em algumas aplicações, o problema é idêntico ao dos botões.

  • Relés: Os relés mecânicos, que atuam como interruptores controlados eletronicamente, possuem contatos que podem apresentar bouncing ao abrir ou fechar. Isso ocorre quando o relé comuta seus contatos para ligar ou desligar um circuito.

Problemas causados pelo bouncing:

O Arduino lê sinais digitais (0 ou 1) com muita velocidade e precisão. Quando ocorre bouncing, o Arduino pode interpretar essas oscilações como várias alterações de estado em um curto período de tempo. Isso pode:

  • Ativar funções repetidamente: Por exemplo, se um botão for programado para alternar um LED, o LED pode ligar e desligar várias vezes em um único clique.

  • Causar instabilidade no sistema: Comportamentos erráticos podem surgir em projetos com interrupções, contadores ou interfaces de controle.

  • Reduzir a confiabilidade do projeto: Especialmente em projetos críticos, como robótica ou automação.

O que é Deboucing?

Debouncing é o processo de eliminar ou reduzir os efeitos indesejados causados pelo "bouncing" (oscilações nos contatos mecânicos) em botões, chaves ou outros componentes de entrada. O objetivo principal do debouncing é garantir que um único acionamento de um botão ou chave seja interpretado corretamente pelo circuito ou software, evitando múltiplos sinais indesejados.

Existem duas formas principais de solucionar esse problema: via software, com a implementação de códigos que compensam de forma eficiente os saltos de tensão causados pelo bouncing, ou via hardware, adicionando componentes que "amortecem" as oscilações elétricas durante o curto intervalo em que o botão ainda não estabilizou completamente o contato no circuito.

Neste artigo, focaremos na abordagem de debouncing via software, que é mais prática, não exige o uso de componentes eletrônicos adicionais e é ideal para projetos e protótipos simples.

Debouncing via Software

Na abordagem via software, o problema do efeito bounce, ou bouncing, é resolvido diretamente no programa, utilizando algoritmos que ignoram as oscilações de contato geradas durante a ativação de um botão, chave ou outro componente. Isso é feito processando os sinais captados pelo microcontrolador, como o Arduino.

Como Funciona?

A ideia principal do debouncing via software é:

  • Aguardar um pequeno intervalo de tempo após detectar a mudança de estado de um componente (pressionado/solto).
  • Durante esse intervalo, ignorar quaisquer alterações no estado do componente.
  • Após o tempo de debounce, considerar o sinal estável.

Existem diferentes maneiras de implementar o debouncing via software, e aqui exploraremos três abordagens comuns:

  1. Usando delay().
  2. Usando millis().
  3. Usando uma biblioteca específica.

Exemplo 0 - Sem deboucing

Para exemplificarmos o uso do debouncing vamos criar um projeto simples para acender e apagar um led ao pressionar e soltar um botão (push button) utilizando um Arduino.

Montagem do Circuito

O circuito de exemplo será composto por um botão (push button) conectado a uma entrada digital do Arduino (porta digital 2) e um LED (de qualquer cor) conectado a uma saída digital do Arduino (porta digital 8). Para proteger o LED, utilize um resistor de 150Ω ou maior em série com ele.

Sketch (programação)

// Definições de pinos
const int buttonPin = 2; // Pino de entrada digital - botão (push button)
const int ledPin = 8;    // Pino de saída digital - LED

// Variáveis de controle
boolean state = 0;        // Armazena o estado do LED
boolean lastButtonState = HIGH; // Armazena o último estado do botão

void setup() {
  pinMode(ledPin, OUTPUT);         // Define o pino do LED como saída
  pinMode(buttonPin, INPUT_PULLUP); // Ativa o pull-up interno do Arduino para o botão
}

void loop() {
   boolean currentButtonState = digitalRead(buttonPin); // Lê o estado do botão

  if (currentButtonState != lastButtonState) {  // Se o estado mudou

    if (!digitalRead(buttonPin)) { // Confirma que o botão ainda está pressionado
      state = !state; // Inverte o estado do LED
      digitalWrite(ledPin, state ? HIGH : LOW);
    }
  }
  lastButtonState = currentButtonState; // Atualiza o último estado do botão
}

Se você executar o programa, perceberá uma certa inconsistência ao pressionar o botão, como o LED não acendendo ou apagando no momento esperado. Esse comportamento ocorre devido ao efeito bounce, ou bouncing, causado pelas oscilações naturais do mecanismo interno do botão (push button).

Exemplo 1 - Debouncing usando delay()

A abordagem mais simples para debouncing é usar a função delay(), que pausa o programa por um curto período (geralmente 50 a 200ms) após a detecção de um pressionamento. Isso é suficiente para permitir que os contatos do botão se estabilizem.

O tempo de pausa necessário pode variar conforme o tipo de botão utilizado. Para determinar o valor ideal, recomenda-se realizar testes com diferentes intervalos até encontrar aquele que ofereça o melhor desempenho. Nos testes realizados neste projeto, um intervalo de 50 ms foi suficiente para estabilizar a funcionalidade do circuito.

Sketch usando delay() para debouncing

// Definições de pinos
const int buttonPin = 2; // Pino de entrada digital - botão (push button)
const int ledPin = 8;    // Pino de saída digital - LED

// Variáveis de controle
boolean state = 0;        // Armazena o estado do LED
boolean lastButtonState = HIGH; // Armazena o último estado do botão

void setup() {
  pinMode(ledPin, OUTPUT);         // Define o pino do LED como saída
  pinMode(buttonPin, INPUT_PULLUP); // Ativa o pull-up interno do Arduino para o botão
}

void loop() {
   boolean currentButtonState = digitalRead(buttonPin); // Lê o estado do botão

  if (currentButtonState != lastButtonState) {  // Se o estado mudou
    delay(50); // Aguarda tempo de debounce

    if (!digitalRead(buttonPin)) { // Confirma que o botão ainda está pressionado
      state = !state; // Inverte o estado do LED
      digitalWrite(ledPin, state ? HIGH : LOW);
    }
  }
  lastButtonState = currentButtonState; // Atualiza o último estado do botão
}

Quando devo utilizar o deboucing com delay()

Ele é especialmente útil em projetos pequenos ou protótipos onde:

  • O código é simples e linear: Se o projeto envolve apenas algumas funcionalidades, como controlar um LED ou outro dispositivo básico, o uso de delay() é suficiente.

  • Não há necessidade de executar múltiplas ações simultaneamente: Como o delay() pausa completamente a execução do programa durante o intervalo especificado, ele funciona bem em situações onde o programa não precisa realizar tarefas concorrentes.

Exemplo 2 - Debouncing usando millis()

Essa abordagem é mais eficiente e permite o uso de debouncing sem bloquear o programa, como ocorre com o delay(). Utiliza o tempo registrado pela função millis() para ignorar alterações no estado do botão por um período. O uso de millis() permite que o Arduino realize outras tarefas enquanto espera pelo período de debounce.

Sketch usando millis() para debouncing

// Definições de pinos
const int buttonPin = 2;  // Pino do botão
const int ledPin = 8;    // Pino do LED
// Variáveis de controle
int buttonState = 0;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;  // Tempo para debounce em ms

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Configura o botão com resistor de pull-up interno
  pinMode(ledPin, OUTPUT);
}

void loop() {
  boolean currentButtonState = digitalRead(buttonPin);  // Lê o estado atual do botão

  if (currentButtonState != lastButtonState) {  // Se o estado mudou
    lastDebounceTime = millis();  // Reinicia o tempo de debounce
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {  // Verifica se passou o tempo de debounce
    if (currentButtonState != buttonState) {
      buttonState = currentButtonState;

      if (!buttonState) {  // Se o botão foi pressionado
        digitalWrite(ledPin, !digitalRead(ledPin));  // Alterna o LED
      }
    }
  }

  lastButtonState = currentButtonState;  // Atualiza o estado anterior do botão
}

Quando devo utilizar o deboucing com millis()

O uso da função millis() para implementar debouncing é recomendado em projetos onde o microcontrolador precisa realizar várias tarefas simultaneamente ou quando há a necessidade de responder a eventos em tempo real sem interromper o programa principal, como:

  • Monitoramento contínuo de sensores: Se o projeto precisa ler dados de sensores ou reagir a eventos em tempo real, delay() não permite que o microcontrolador processe essas leituras durante o intervalo de pausa.

  • Controle simultâneo de vários dispositivos: Projetos com múltiplos LEDs, motores, ou comunicação serial, por exemplo, podem apresentar atrasos ou perda de dados devido à pausa gerada pelo delay().

  • Desempenho crítico ou tempo real: Aplicações que exigem respostas rápidas e precisas, como robótica ou automação, não podem tolerar pausas de execução.

Portanto, quando há funcionalidades concomitantes, o uso de millis() para implementar debouncing é mais adequado. O método baseado em millis() permite ao microcontrolador continuar executando outras tarefas enquanto gerencia o tempo de pausa necessário para o debouncing. Isso é feito verificando se um intervalo de tempo pré-determinado já passou, sem interromper o loop principal do programa.

Essa abordagem é essencial em sistemas multitarefa, pois oferece mais flexibilidade e eficiência em projetos que envolvem várias ações acontecendo ao mesmo tempo.

Exemplo 3 - Debouncing biblioteca externa

Existem bibliotecas externas que facilitam o debounce, como a Bounce2. Ela encapsula toda a lógica de debouncing e simplifica a implementação. A biblioteca Bounce2 oferece uma solução fácil e eficiente para lidar com debounce de botões.

Como instalar a biblioteca Bounce2 na IDE do Arduino

  • Na IDE do Arduino, vá em Sketch (Rascunho) > Incluir Biblioteca > Gerenciar Bibliotecas.

  • Procure por "Bounce2" e clique em instalar.

Sketch usando a biblioteca Bounce2 para debouncing

#include <Bounce2.h>

const int buttonPin = 2; // Pino do botão
const int ledPin = 8;   // Pino do LED
Bounce debouncer = Bounce(); // Cria o objeto para debounce

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Configura o botão com resistor de pull-up interno
  pinMode(ledPin, OUTPUT);          // Configura o LED como saída
  debouncer.attach(buttonPin);      // Anexa o botão ao objeto
  debouncer.interval(50);           // Define o tempo de debounce (50 ms)
}

void loop() {
  debouncer.update(); // Atualiza o estado do botão

  if (debouncer.fell()) { // Detecta o pressionamento do botão
    digitalWrite(ledPin, !digitalRead(ledPin)); // Inverte o estado do LED
  }
}

Quando devo utilizar o deboucing com uma biblioteca externa

A biblioteca Bounce2 é uma excelente opção para implementar o debouncing via software em projetos com Arduino. Ela simplifica o processo de lidar com o problema do bouncing, oferecendo uma solução eficiente, reutilizável e fácil de integrar. A utilização dessa biblioteca é especialmente recomendada em situações onde gerenciar manualmente o debouncing (usando delay() ou millis()) se torna complicado, ou onde há a necessidade de gerenciar múltiplos botões ou switches. Veja alguns exemplos de aplicações:

Projetos com múltiplos botões ou switches:

  • Se o projeto envolve o uso de vários botões, chaves ou entradas digitais, gerenciar o debouncing manualmente pode tornar o código mais complicado e difícil de manter. A biblioteca Bounce2 simplifica o processo, permitindo que você implemente o debouncing de forma consistente para cada entrada.

Necessidade de código organizado e reutilizável:

  • A biblioteca encapsula toda a lógica de debouncing em uma classe, tornando o código mais organizado e reutilizável. Isso é útil em projetos de médio a grande porte, ou em projetos que podem ser reutilizados em outros sistemas.

Facilidade de implementação:

  • Se você é iniciante ou deseja implementar o debouncing de forma rápida e eficiente, a biblioteca Bounce2 oferece métodos simples e diretos para configurar e gerenciar o debouncing de botões.

Projetos com eventos específicos baseados no botão:

  • A biblioteca Bounce2 fornece métodos convenientes, como fell() e rose(), para detectar mudanças de estado no botão, como uma transição de HIGH para LOW (botão pressionado) ou de LOW para HIGH (botão solto). Isso é útil em projetos onde ações específicas precisam ocorrer quando o botão é pressionado ou liberado.

Manutenção de tempo de debounce padronizado:

  • Quando você precisa de um tempo de debounce consistente para vários botões ou deseja alterar o tempo de debounce facilmente, a Bounce2 permite configurar o tempo de debounce diretamente, sem precisar modificar manualmente o código.

Evitar conflitos em projetos complexos:

  • Em projetos onde várias funcionalidades acontecem simultaneamente (como LEDs piscando, comunicação serial, controle de motores ou leitura de sensores), a Bounce2 reduz a complexidade ao gerenciar automaticamente os tempos de debounce, liberando o microcontrolador para outras tarefas.

Referências

Como usar push button com Arduino (programação)

Como usar temporizadores no Arduino

Função delay() - Referência Arduino

Função millis() - Referência Arduino

Biblioteca Bounce2 - GitHub

O anúncio abaixo ajuda a manter o Squids Arduino funcionando

Comentários

×

Infomações do site / SEO








×

Adicionar Marcadores