Reconhecendo e Lidando com contato Retorno sobre o Raspberry Pi
Você pode precisar para lidar com salto de contato para o seu próximo projeto Raspberry Pi. Lendo um interruptor é bastante simples. Ele retorna um 0 ou um 1, dependendo se o interruptor for pressionado. Switches deve sempre ser conectado entre o / saída (GPIO) pino de entrada de entrada de uso geral e no solo e quer permitir que a resistência interna pull-up ou corrigir um resistor externo para eles. Quando um interruptor é fechado, ele faz um caminho para a terra. Você lê uma lógica baixa ou zero quando este caminho é feito.
Você pode ver outras modalidades em que um switch é conectado entre o pino de entrada GPIO e 3V3, mas isso não é recomendado porque interruptores são normalmente em fios longos. Encaminhamento longos fios conectados à terra é menos arriscado do que conectar a uma tensão de alimentação. Isto é como você ligar um interruptor.
Embora a mudança para terra com um resistor pull-up para uma alta tensão pode ler apenas 1 ou 0, a maioria dos switches são um pouco mais complexa. Por exemplo, pegue um saco de 1 libra de açúcar e deixá-lo cair de cerca de 6 polegadas em uma superfície dura como uma mesa. Ela atinge a superfície com uma pancada e pára. Agora tente a mesma coisa com uma bola de pingue-pongue, e você vai ver que ele salta. O primeiro salto da bola de pingue-pongue não é tão elevada como a altura que você deixou cair a partir, mas é bastante elevado. Em seguida, a bola cai e salta novamente, apenas ligeiramente inferior. Este continua com menores e menores alturas de salto até que a bola vem para descansar. Note-se que quanto menor o salto, mais curto é o tempo entre as rejeições bounces- acelerar até que a bola entra em repouso.
Interruptor contatos são assim - eles são superfícies rígidas se unindo rapidamente, e eles saltam. Tanto é assim que, se você examinar os níveis lógicos o interruptor dá para fora, você verá não um simples transição de uma alta para uma baixa, mas uma sucessão de transições cada vez mais perto juntos até um nível estável é atingido. Isto é conhecido como uma vantagem suja ou contato de rejeição.
Esta rápida mudança de 0 a 1 pode ser um problema se o computador estiver olhando para o interruptor muito rapidamente. Na verdade, isso acontece muito mais rapidamente do que um usuário pode pressionar um botão, mas às vezes as circunstâncias ou código vai deixar isso acontecer. Para ilustrar o problema, olhar para o código a seguir, ligar um interruptor entre GPIO 2 (pino 3) e solo (6 pinos). Este pino tem um resistor pull-up montada na placa.
# Bounce Problema mostra contacto salto # Autor: Mike Cookimport wiringpi2 timeimport como ioio.wiringPiSetupGpio () io.pinMode (2,0) # para inputlastPress = io.digitalRead (2) count = 0pressTime = time.time () print "push testes botão "while True: pressionar = io.digitalRead (2) se pressionar == 0 e lastPress = imprensa: count + = 1pressTime = time.time () se count> = 5: print" cinco prensas "count = 0lastPress = press
A técnica usada aqui é contar cinco prensas interruptor e, em seguida, imprimir quando o computador tem contado todos eles. Se você tentar fazer isso, você pode achar que ele imprime que detectou cinco prensas após quatro ou mesmo três prensas, bem como todos os cinco. Em suma, não é confiável, porque salto de contato está causando contagens erradas.
Para investigar esta mais profundo, você precisa para medir o intervalo entre as prensas. Isto é feito com o seguinte código.
# Bounce Measure # medidas tempo de contato intervalo # Autor: Mike Cookimport wiringpi2 timeimport como ioio.wiringPiSetupGpio () io.pinMode (2,0) # para inputlastPress = io.digitalRead (2) Intervalo count = 0startTime = time.time () = [0.0,0.0,0.0,0.0,0.0] print "teste botão" while True: pressionar = io.digitalRead (2) se pressionar == 0 e lastPress = imprensa: intervalo [contador] = time.time () - startTimecount + = 1startTime = time.time () se count> = 5: print "cinco prensas", intervalcount = 0startTime = time.time () lastPress = press
O intervalo entre cada imprensa chave é gravada em uma lista. Isto é derivado a partir do relógio de tempo de sistema e conta o número de segundos uma vez que o sistema inicializado. Subtraindo-se a hora do sistema a partir do momento da imprensa atual, você obter o tempo desde a última imprensa. O resultado da execução deste programa é mostrada aqui:
cinco prensas [1.2872810363769531, 0.25738978385925293,6.198883056640625e-05, ,27149009704589844, 6.699562072753906e-05] cinco prensas [2.247836112976074, 0.31453490257263184,0.32202887535095215, 0.2885620594024658, ,33057308197021484] cinco prensas [1.048125982284546, 3.504753112792969e-05,0.5636959075927734, 0,43523192405700684, ,4095041751861572] cinco prensas [14,676625967025757, 0.24735713005065918,0.24397802352905273, ,33951711654663086, ,34607601165771484]
Observe que o código não faz nenhuma tentativa para reduzir o número de bits significativos nas leituras, mas ter um olhar mais atento sobre alguns deles, e você verá que alguns final com um E-05. Essa é a maneira padrão de dizer 10 elevado à potência de -5 isso é conhecido como o formato de expoente e é a maneira padrão de números de ponto flutuante são mostrados na maioria da computação. Então, esquecendo o número ridículo de lugares após o ponto decimal, este número, 6.12e-05, é interpretado como 0.0000612 ou 61,2 microssegundos (EUA), que é a maneira mais rápida do que qualquer ser humano pode pressionar qualquer coisa. Este é um exemplo de salto de contato. Você não vê a cada salto porque o computador apenas amostras o nível lógico da linha em intervalos discretos.
A maneira de evitar que isso aconteça é a introdução de um tempo morto - isto é, ignorar o interruptor por um tempo específico após uma imprensa ocorreu. Em muitas ocasiões, isso vai acontecer naturalmente porque você pode ter uma declaração de impressão ou algum outro código que leva um pouco de tempo antes de o interruptor é olhado novamente. Se não, uma solução simples seria adicionar um atraso de apenas após a chave foi detectada para que nada seja feito durante o potencial tempo de ressalto.
No entanto, para o debounce final, você precisa fazer uma nota do tempo uma transição chave é detectado. Então, quando uma outra transição é detectado, apenas a tratá-lo como real, se um tempo específico tiver decorrido entre a última transição real e o tempo presente. Um exemplo disto é mostrado no seguinte código.
# Bounce Solução # Como lidar com a rejeição # Autor: Mike Cookimport wiringpi2 timeimport como ioio.wiringPiSetupGpio () io.pinMode (2,0) # para inputlastPress = io.digitalRead (2) count = 0pressTime = time.time () print "botão de teste" while True: pressionar = io.digitalRead (2) se pressionar == 0 e lastPress = prima e (time.time () - pressTime)> 0,025: count + = 1pressTime = time.time () se contagem> = 5: print "cinco prensas" count = 0lastPress = press
Aqui o segredo é o teste extra no E se declaração que verifica que pelo menos 25 milissegundos (ms) ter decorrido antes de uma transição é tomada como real.
Diferentes tipos de chaves mecânicas saltar para um grau diferente. Dependendo exatamente o que seu código é e quão rápido ele é executado, este pode ou não ser um problema. Se você fizer experiência transições "fantasmas" na leitura de um interruptor mecânico, é provável que seja salto de contato. Se assim for, você pode usar uma das técnicas descritas aqui para eliminar o efeito.