Botões recebendo muitos eventos

12

Estou escrevendo um mp3 player que grava informações em um monitor LCD. Gostaria de convertê-lo do teclado para o uso de botões, mas estou constantemente recebendo pressionamentos de teclas. Eu tentei puxar para cima e para baixo / para cima, mas ainda estou obtendo o mesmo resultado. Alguém sabe de imediato se este é um problema conhecido ou estou apenas fazendo algo errado? Ah, eu também estou fazendo isso inteiramente em C usando a fiação PI.

linuxgnuru
fonte
1
Apenas para adicionar ao pote de soluções de software, confira nosso amigo em microcontroladores. arduino.cc/en/Tutorial/Debounce
Cammy_the_block 25/11/14
Aqui está um trecho de algo que escrevi há algum tempo. if(digitalRead(data) && millis()-startTime > 10){e defina startTime sempre que entrar no loop.
Cammy_the_block
apenas me perguntando; o que exatamente eu definiria startTime?
Linuxgnuru #
Algum tempo sorta contador. O Arduino tem a função millis que fornece tempo desde o início.
Cammy_the_block 26/11/14
Ah ok, o mesmo acontece wiringPi wiringpi.com/reference/timing
linuxgnuru

Respostas:

12

Os botões e interruptores mecânicos podem sofrer oscilações, onde alternam rapidamente entre aberto e fechado por vários milissegundos.

Você pode tentar rebater o botão / chave no software ou hardware.

Provavelmente o mais simples em software.

Se o nível mudar (ativado ou desativado ou desativado), aguarde x milissegundos e leia o gpio novamente. Se ainda estiver no novo estado, assuma que é uma transição real. O valor de x pode ser algo como 20.

Para soluções de hardware, procure esse tipo de postagem

joan
fonte
8

Aproveite o tempo para ler o guia de rebate de Jack Ganssle . A primeira página ilustra o problema detalhadamente, e a segunda, como lidar com ele em hardware ou software. Não existe um método de rejeição "perfeito", mas existem muitos métodos ruins!

Esse é um problema que você encontrará repetidamente se fizer a interface do software com os comutadores, portanto vale a pena dedicar um tempo para entendê-lo, e o artigo de Jack é a maneira mais concisa que eu já vi de fazer isso.

rolinger
fonte
2

Em aplicativos que possuem um ticker de sistema, eu geralmente implemento um registro de turno.

unsigned char button_checker;

// inside the system ticker

button_checker <<= 1; 
button_checker += INPUT;

if (button_checker == 0xFF) 
{ 
    // button was pressed 
}

Obviamente, você deve realizar o evento de pressionar o botão apenas em uma borda ascendente.

vsz
fonte
1
Esse é um método interessante. Facilmente personalizado (mascarando os bits mais significativos do button_checker) para exigir um número variável de leituras consecutivas.
joana