Question:
Comment est ce code anti-rebond de bouton-poussoir?
boardbite
2012-10-13 20:41:13 UTC
view on stackexchange narkive permalink

Je surveille un bouton poussoir avec un microcontrôleur où j'essaye de m'occuper de quatre choses ensemble:

  1. 50 ms de rebond lors du démarrage par poussée et 25 ms après la libération du push
  2. identifier un appui court, défini comme lorsque le bouton est relâché dans < 1 seconde
  3. identifier un appui long, défini comme quand 1 seconde s'écoule depuis le début du bouton poussoir
  4. dormir autant que possible sans rien faire d'autre

Voici un court pseudocode de ce que j'ai implémenté jusqu'à présent. Je pense que cela couvre tous ces cas.

Voyez-vous des améliorations possibles ou des problèmes potentiels? (Par exemple, je suis intéressé par tous les cas subtils qui pourraient être des angles morts pour mon approche.)

Pseudocode:

  Boucle principale {Sleep} Falling-Interrupt {Disable Falling-Interrupt Enable 50-millisecond-Debounce-Timer-Interrupt} 50-millisecond-Debounce-Timer-Interrupt {si l'état PushButton est toujours LOW {Enable Rising-Interrupt Enable 1000-millisecond-Hold-Timer-Interrupt}} 1000 -millisecond-Hold-Timer-Interrupt {Register as Pushbutton long-hold} Rising-Interrupt {if (Time since Falling-Interrupt < 1000 millisecond) {Register as Button Short-press} Désactiver 1000-millisecond-Hold-Timer-Interrupt Enable 25-millisecond-Debounce-Timer-Interrupt} 25-millisecond-Debounce-Timer-Interrupt {Enable Falling-Interrupt}  
Personnellement, j'évite les interruptions des routines de service chaque fois que je le peux. Je mettrais en place une interruption de 50 ms et ferais tout le traitement dans le principal, après le sommeil. 25 ms: pourquoi pas 50 ms? Aucun utilisateur ne le remarquera.
@WoutervanOoijen: Si j'évite d'utiliser les interruptions, comment puis-je détecter un événement de bouton-poussoir pendant le sommeil? Ou voulez-vous dire que je devrais minimiser le code réel à l'intérieur de l'ISR? [Et le 25 vs 50 ms était arbitraire; Je viens de l'utiliser pour permettre au lecteur de distinguer plus facilement le minuteur anti-rebond au début et le temporisateur anti-rebond à la libération]
@Inga `re: comment puis-je détecter un événement de bouton-poussoir pendant le sommeil?` Vous ne pouvez utiliser qu'une (1) interruption: la chute-interruption. Réveillez-vous sur cette interruption, faites le reste du débouncing dans la boucle principale. Revenez au sommeil, si le code indique que la pression sur le bouton n'était pas "réelle".
Un répondre:
Wouter van Ooijen
2012-10-13 22:31:29 UTC
view on stackexchange narkive permalink

Je ne peux pas mettre de code dans un commentaire, donc une réponse. Mon «cadre» pour les systèmes embarqués simples est la boucle principale avec interrogation. Pour minimiser la consommation de courant, la boucle principale peut attendre, disons 50 ms en mode veille. Je ne sais pas quel uC vous utilisez, je connais les PIC, qui peuvent se réveiller d'un sommeil par une interruption.

  configurer une interruption pour me réveiller toutes les 50 ms down_counter = 0 pour (;;) {sleep (); if (touche enfoncée) {down_counter ++; if (down_counter == 20) {(début de) long_down détecté}} else {if (down_counter > 1 && down_counter < 20) {(fin de) appui court détecté} down_counter = 0; }}  
C'est très élégant! La seule légère faiblesse que je vois est que dans votre approche, vous réveillez le microcontrôleur 20 fois, donc peut-être un peu plus de consommation d'énergie (alors que dans la mienne, l'uC ne se réveille que 2 ou 3 fois). Je serais intéressé par votre commentaire sur cet aspect, car tout ce que j'aime dans ce focus de boucle principale.
(Mais je suppose que c'est très peu de tirage au sort, étant donné que vous exécutez principalement seulement deux instructions à chaque réveil.)
L'une des règles de base de l'informatique est "n'optimisez pas si vous ne savez pas que vous avez un goulot d'étranglement". Ne calculez pas, ne mesurez pas. Je pense que le ratio de sommeil actif de mon approche est inférieur à 1: 1000 (peut-être beaucoup moins, mais c'est une estimation moins sûre). Quel est le rapport entre le courant actif et le courant de sommeil pour votre uC? Si c'est beaucoup plus que 1: 1000, vous ne remarquerez pas la différence.
C'est un Atmega1280, et le courant actif / sommeil est en effet autour du rapport 1000: 1. Je vais essayer cette approche et mettre à jour ma question en fonction du résultat.
Je pense vraiment que c'est la voie à suivre. La seule amélioration à laquelle je peux penser serait de se réveiller initialement du sommeil en détectant la première pression sur un bouton, puis de passer au réveil par minuterie. Une fois que la pression sur le bouton a été entièrement décodée, revenez pour activer le bouton.
@rocketmagnet: pourquoi? économiser quelques% de puissance par rapport à une solution plus simple?
@WoutervanOoijen - Ouais, c'est à peu près tout. Ce n'est pas vraiment une amélioration, mais c'était un peu le point. Il n'y a pas beaucoup d'amélioration à apporter à votre suggestion.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...