Header Ads

PushButton class - part 1

Introduction
Dans l'article "commande à bouton poussoir", j'évoque le côté assez fastidieux de devoir sans cesse écrire les mêmes bouts de code pour capturer l'état des boutons (sans parler du déparasitage logiciel).

Lorsque j'ai commencé à écrire le code pour tester tous les boutons de mon montage, je me suis vite rendu compte qu'il serait fastidieux à rédiger dans son entièreté (voir article "Entrée Bouton - Résistance pull-up, pull-down et déparasitage").

J'ai donc décidé d'écrire quelques fonctions et/ou classes pour simplifier le code principal.

Des fonctions de traitement
Avant d'envisager la rédaction d'une classe, je me suis d'abord concentré sur le traitement général.
J'ai donc écris une structure de donnée et une série de fonctions de traitement.

Même si le  nom des fonctions est encore alambiqué, au terme de ce premier essai, le code principal est déjà beaucoup plus limpide.

Code principal
Comme il est possible de le constater ci-dessous, il n'y a aucun code de capture qui vient parasiter la compréhension du programme principal.
Le code principal attend simplement que l'on presse un bouton particulier avant d'envoyer toute une série d'information sur le port série.

int pinUp1 = 13;   // switch 5 - noir
int pinDown1 = 12; // switch 4 - bleu
int pinUp2 = 9;    // switch 2 - Violet
int pinDown2 = 8;  // switch 1 - Jaune
int pinBtn = 7;    // switch 3 - Vert

int pinLed = 3;    // gris

buttonData btnUp1, btnDown1;
buttonData btnUp2, btnDown2;
buttonData btn;
boolean ledState = false; // eteinte

void setup() {
  Serial.begin( 9600 );

  // Boutons
  btnUp1 = attachButton( pinUp1 );
  btnDown1 = attachButton( pinDown1 );
  btnUp2 = attachButton( pinUp2 );
  btnDown2 = attachButton( pinDown2 );
  btn = attachButton( pinBtn );
  // Led
  pinMode( pinLed, OUTPUT );
}


void loop(){
  // Update all the button statistics
  updateButton( &btnUp1 ); updateButton( &btnDown1 );  
  updateButton( &btnUp2 ); updateButton( &btnDown2 );  
  updateButton( &btn );
  
  // Wait the the user press the button "btn" to send the 
  // resume of operation over the serial port
  
  // When the btn is pressed
  if( pressedReadButton( &btn ) ) {
    Serial.println( " -----------------------------" );
    // make as many read as the btnUp1 has been pressed
    while( pressedReadButton( &btnUp1 ) ) {
      Serial.println( "Button Up1 pressed" );
    } 
    
    // what ever the down button has been pressed once or several times
    // just read it once
    if( pressedReadAllButton( &btnDown1 ) )
      Serial.println( "Button Down1 pressed (read only once)" );
    // following line should not send a message (because of the 
    // preceding pressedReadAllButton)
    if( pressedReadButton( &btnDown1 ) )
      Serial.println( "YOU SHOULD NOT SEE THIS MESSAGE! button down 1 pressed" );
      
    // Get information about the number of time the buttons 
    // Up2 & Down2 has been pressed 
    byte count = pressedReadCountButton( &btnUp2 );
    Serial.print( "button Up2 was pressed " );
    Serial.print( (int)count );
    Serial.println( " times" );

    count = pressedReadCountButton( &btnDown2 );
    Serial.print( "button Down2 was pressed " );
    Serial.print( (int)count );
    Serial.println( " times." );
    
    // Just for the FUN!
    // If button 2 has been pressed --> change the LED state
    if(count > 0) {
      ledState = !ledState;
      if( ledState )
        digitalWrite( pinLed, HIGH );
      else
        digitalWrite( pinLed, LOW );
    } 
  } 
}

Ce qui produit le résultat suivant:
-----------------------------

Button Up1 pressed

Button Up1 pressed

Button Up1 pressed

Button Down1 pressed (read only once)

button Up2 was pressed 2 times

button Down2 was pressed 6 times.

Le code source
Pour le moment, le code n'est qu'en version alpha (juste un test) et il y a encore du travail à réaliser.
source complète: ButtonTools.pde

Roadmap
A partir de ce code il est possible d'envisager quelques développements futurs.
  • Transformer le code de test en classe.
  • Maintenir un array de classe pour permettre l'appel de fonctions "globale" comme par exemple isAButtonPressed, updateAllButtons, etc.
  • Essayer de se greffer sur le timer (ou interruption) pour faire automatiquement l'appel à updateButton à la place du code principal (voir Servo.cpp) .
  • Ecrire une classe CursorButtons qui utilise deux boutons poussoir pour faire varier la valeur d'une variable (curseur) entre 0-255 ou 0-1024. 

Suite de l'article dans "Led Class - Part 3 | PushButton Class - Part 2