Parabéns a você caro leitor que chegou neste post se perguntando o que é Efeito Bouncing. Bom, estou aqui para lhe dizer que, caso nunca tenha ouvido falar disso mesmo que esteja familiarizado com a eletrônica e projetos com Arduino, muito provavelmente você já se deparou com ele antes, ou irá se deparar no futuro.
Esse fenômeno está muito presente em projetos com Arduino que envolvem o uso de botões. No post de hoje iremos lhe apresentar o efeito Bouncing e apresentar uma solução simples e prática para acabar de vez com esse problema. Veja só:
O Efeito Bouncing nada mais é que um fenômeno de trepidação. Ele é comum em Chaves, push buttons, reed-switch, entre outros. Usaremos aqui um push button para exemplificar o efeito.
Quando pressionamos o botão, forçamos o contato entre dois condutores. Note que estamos imprimindo força no botão, então esse movimento possui energia cinética. Você deve lembrar das suas aulas de física no ensino médio que quando temos colisões entre corpos, transferimos energia cinética entre eles. Esse fato faz com que o movimento que inserimos no botão passe para os contatos, que por sua vez levam tempo até se estabilizarem em uma posição de repouso (pleno contato entre eles). Até que esse repouso seja atingido podemos ter micro oscilações entre posições de contato fechado e aberto.
Note que tudo isso ocorre naqueles primeiros milissegundos após acionarmos o botão, e apesar de ser muito rápido para notarmos, o Arduino que está esperando um sinal do botão consegue ler essas oscilações e seu código pode apresentar problemas por causa disso.
Diagrama de uma onda quadrada com efeito bouncing
Bom, se é rápido demais para identificarmos esse efeito, como faremos? É bem simples, basta usarmos alguém que consegue ler essas oscilações, como o Arduino. Para demonstração, vamos montar um circuito bem simples: Um Arduino conectado a um botão em uma porta digital configurada como entrada, e um LED conectado a outra porta digital configurada como uma saída. Quanto ao código de identificação, vamos fazer o Arduino contar quantas vezes ele identificou uma mudança de estado na porta digital que está conectado ao botão e depois nos retornar essa informação.
Vamos então ao circuito:
Circuito para teste do efeito bouncing
unsigned long time; // váriavel para receber valores da função milli() int cont = 0; // o contador de variações int entrada = 7; bool estado = LOW; // variável de estado do botão int aux = 1; void setup() { Serial.begin(9600); pinMode(led,OUTPUT); pinMode(entrada,INPUT); time = millis(); //iniciamos a variável com o primeiro valor do "cronometro" } void loop() { estado = digitalRead(entrada); if (estado==HIGH && aux==1){ cont++; aux = 0; } if (estado==LOW && aux==0){ cont++; aux = 1; } if (millis()-time>=500){ // imprime o número de variações a cada 0,5 segundo time=millis(); // guarda o novo ponto de inicio para a proxima analise Serial.print("variações = "); Serial.print(cont); Serial.print("\n"); cont = 0; } }
Debouncing é um método para contrapor o efeito Bouncing. É importante salientar que existem mais de um método de Debouncing, e como a nossa intenção aqui é simplificar o processo, vamos te apresentar dois métodos. Um por Software e outro por Hardware.
Aqui iremos fazer com que o Arduino “ignore” a oscilação causada pelo botão.
Usaremos para isso a função delay(), que é responsável por pausar todo o processamento do Arduino. Para que essa técnica funcione, nós precisamos de uma estimativa de duração da oscilação, pois vamos pausar o sistema durante esse intervalo de tempo após acionarmos o botão.
Esta estimativa pode ser feita por tentativa e erro, note que no exemplo abaixo usamos um tempo de 50ms. Esse período é suficiente para o debouncing, contudo também é pequeno o suficiente para não sentirmos atrasos na execução do código. Note também que se pressionarmos o botão não percebemos nenhum atraso. Para esse exemplo, usaremos o mesmo circuito discutido anteriormente.
int led = 4; int entrada = 7; int aux = 1; int cont =0; bool estado = LOW; // variável de estado do botão unsigned long time; // variável vara a função millis() void setup() { pinMode(led,OUTPUT); pinMode(entrada,INPUT); Serial.begin(9600); time = millis(); } void loop() { do{ estado_anterior = digitalRead(entrada); delay(50); estado = digitalRead(entrada); }while(estado_anterior != estado); // aqui definimos um intervalo de tempo de segurança usando a função delay(), para sair do loop é // necessário identificar uma constancia no estado do botão, ele precisa ser o mesmo durante 50 ms if (estado==HIGH && aux==1){ aux = 0; cont++; digitalWrite(led,HIGH); // este não é só um algoritimo de verificação, quando acionamos o botão também ascendemos um Led } if (estado==LOW && aux==0){ aux = 1; cont++; digitalWrite(led,LOW); } if (millis()-time>=500){ // imprime o número de variações a cada 0,5 segundo time=millis(); //guarda o novo ponto de inicio para a proxima analise Serial.print("variações = "); Serial.print(cont); Serial.print("\n"); cont = 0; } }
Já nesse caso, vamos absorver a energia da oscilação, mas para isso você precisa entender um pouco mais sobre capacitores. Quando ligados diretamente com uma fonte, os capacitores são capazes de se polarizar ao armazenar cargas elétricas e depois liberar essa mesma carga ao circuito quando necessário.
Quando associamos um capacitor ao botão, ao pressionarmos o botão e as oscilações ocorrerem, o capacitor irá absorvê-las enquanto está sendo carregado. A parte boa é que depois de carregado o resultado aparente para o Arduino será o mesmo do botão pressionado durante muito tempo.
No fim das contas, com o capacitor estamos atrasando o sinal produzido pelo botão.
Logo abaixo temos um esquema de ligação do capacitor, assim como o próprio circuito que usaremos nesse caso.
Esquemático de ligação do capacitor para debouncing via hardware
Exemplo de debouncing via hardware
Agora você deve ser capaz de identificar problemas causados pelo efeito Bouncing. Note que é muito importante identificá-lo em projetos mais complexos, pois essa oscilação causada pelos botões ou chaves quando conectados a aparelhos extremamente sensíveis, pode causar danos a esses equipamentos ao longo do tempo, além de causar erros em suas leituras e dados.
Para finalizar, proponho um exercício: construa o primeiro circuito deste post e também um algoritmo de Debounce usando a função millis() e não a função delay().
Diferente da função delay(), a função millis() não interrompe o processamento de dados do Arduino, mas sim conta o tempo. Pense em como podemos usar essa função e comente a sua solução nos comentários.
Você pode complementar o seu aprendizado aprendendo mais sobre resistores Pull-Up e Pull-Down. Isso vai te ajudar a nunca mais ter problemas com leituras incorretas no Arduino!
Esperamos que esse post tenha contribuído para seu aprendizado e se ficou alguma dúvida, deixe nos comentários.
Um forte abraço e até a próxima.
Tenha a Metodologia Eletrogate na sua Escola! Conheça nosso Programa de Robótica Educacional.
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!