MTbutton: Exemple 3

Le programme va envoyer la lettre "A" à chaque appui sur le bouton câblé sur A0, le "B" si on appuie sur le bouton câblé sur A0, ... etc jusqu'au "F".

Les 6 boutons

On peut définir chaque bouton avec chacun une fonction d'envoi de la lettre correspondante. Mais il faut écrire 6 fois une fonction semblable. C'est tout à fait possible, mais ici, nous allons créer un nouveau bouton qui envoie une lettre. Ainsi on ne définit qu'une seule fois ce type de bouton. C'est un peu plus compliqué, il faut comprendre les objets du C++. Le but ici est surtout de montrer comment cela se fait. C'est intéressant si on a beaucoup de boutons identiques, ou si on a quelques boutons mais avec une fonction appelée importante.

Il faut comme dans tous les programmes qui utilisent MTobjets, inclure la bibliothèque utile. Ici on utilise comme seul objet le bouton poussoir (le nom de l'objet est MTbutton):

#include "MTbutton.h" // V1.0.0 Voir http://arduino.dansetrad.fr/MTobjects

Je conseille fortement de laisser le commentaire, si une autre personne voulait essayer le programme, elle aurait directement un lien de téléchargement. C'est valable pour toutes les bibliothèques que vous utilisez.

On va commencer par donner des noms symboliques aux broches utilisées. Ici, il y en a une par bouton:

const uint8_t PIN_BUTTON_A = A0;
const uint8_t PIN_BUTTON_B = A1;
const uint8_t PIN_BUTTON_C = A2;
const uint8_t PIN_BUTTON_D = A3;
const uint8_t PIN_BUTTON_E = A4;
const uint8_t PIN_BUTTON_F = A5;

Vous l'avez compris, quand on appuiera sur le bouton câblé en A0 c'est la lettre A qui sera envoyée et ainsi de suite.

Si on n'avait qu'un seul bouton, on appellerait une fonction "affiche" qui pourrait être définie par:

void affiche(void) // Fonction qui envoie la lettre A
{
  Serial.print("A");
}

On va définir une classe dérivée de MTbouton qui va envoyer une lettre si on appui sur un bouton. La nouvelle classe se définit ainsi:

// Définition d'une nouvelle classe
class MonBouton: public MTbutton
{
 public:
  MonBouton (uint8_t pin) // Nouveau constructeur
    :MTbutton(pin) // Qui appelle l'ancien constructeur
    {};
 private:
};

La lettre à envoyer va donc être différente pour chaque bouton, il faut donc la mémoriser dans une propriété de l'objet. Cette lettre sera passé en paramètre quand on construira un bouton. La nouvelle classe devient:

// Définition d'une nouvelle classe
class MonBouton: public MTbutton
{
 public:
  MonBouton (uint8_t pin, char p_lettre) // Nouveau constructeur
    :MTbutton(pin), lettre(p_lettre) 
    {};
 private:
  char lettre; // Lettre qui sera envoyée sur la voie série
};

Le nouveau constructeur appelle l'ancien dont on ne donne que le numéro de la broche. On n'utilise pas les fonctions callback. Et la lettre spécifique est rangée dans la propriété.

En définissant un nouveau type de bouton, au lieu de faire l'affichage par une fonction externe qui serait appelée à chaque appui, on va utiliser la fonction interne à l'objet "onSelect" qui est appelée à chaque appui. Dans notre nouvel objet, il va donc falloir la surcharger:

virtual void onSelect(void) // Fonction à surcharger qui envoie une lettre
{
  Serial.print(lettre);
}

La définition complète de notre nouvelle classe sera donc:

// Définition d'une nouvelle classe qui surcharge onSelect
class MonBouton: public MTbutton
{
 public:
  MonBouton (uint8_t pin, char p_lettre) // Nouveau constructeur
    :MTbutton(pin), lettre(p_lettre) 
    {};
 private:
  char lettre; // Lettre qui sera envoyée sur la voie série
  virtual void onSelect(void) // Fonction à surcharger qui envoie une lettre
  {
    Serial.print(lettre);
  }
};

Définissons maintenant nos boutons:

// Définition des boutons
MonBouton BoutonA(PIN_BUTTON_A, 'A'); // Ce bouton va donc envoyer la lettre 'A'
MonBouton BoutonB(PIN_BUTTON_B, 'B');
MonBouton BoutonC(PIN_BUTTON_C, 'C');
MonBouton BoutonD(PIN_BUTTON_D, 'D');
MonBouton BoutonE(PIN_BUTTON_E, 'E');
MonBouton BoutonF(PIN_BUTTON_F, 'F');

Setup() et loop()

On a tout fait pour les boutons, mais il faut aussi s'occuper de la console. Dans le setup(), il faut mettre (si la console est réglée sur 115200bauds):

void setup()
{
  Serial.begin(115200);
}

Il n'y a rien à faire de plus, loop() ne nous sert à rien. Il va rester vide. Mais vous pouvez y mettre un autre programme, celui que nous avons fait est indépendant. Donc:

void loop(){}

J'ai tout mis sur la même ligne mais vous pouvez en prendre deux ou trois. Même si la fonction est vide et ne nous sert à rien apparemment, il faut la définir. En fait, elle va servir de boucle d'attente quand notre programme ne va pas s'intéresser au bouton.

Programme complet

Voici donc le programme complet:

// Ce programme redéfinit des boutons pour envoyer des caractères. Ici on va
// dériver une nouvelle classe pour éviter de redéfinir plein de fonctions

#include "MTbutton.h" // V1.0.0 Voir http://arduino.dansetrad.fr/MTobjects

const uint8_t PIN_BUTTON_A = A0;
const uint8_t PIN_BUTTON_B = A1;
const uint8_t PIN_BUTTON_C = A2;
const uint8_t PIN_BUTTON_D = A3;
const uint8_t PIN_BUTTON_E = A4;
const uint8_t PIN_BUTTON_F = A5;


// Définition d'une nouvelle classe qui surcharge onSelect
class MonBouton: public MTbutton
{
 public:
  MonBouton (uint8_t pin, char p_lettre) // Nouveau constructeur
    :MTbutton(pin), lettre(p_lettre) 
    {};
 private:
  char lettre; // Lettre qui sera envoyée sur la voie série
  virtual void onSelect(void) // Fonction à surcharger qui envoie une lettre
  {
    Serial.print(lettre);
  }
};


// Définition des boutons
MonBouton BoutonA(PIN_BUTTON_A, 'A'); // Ce bouton va donc envoyer la lettre 'A'
MonBouton BoutonB(PIN_BUTTON_B, 'B');
MonBouton BoutonC(PIN_BUTTON_C, 'C');
MonBouton BoutonD(PIN_BUTTON_D, 'D');
MonBouton BoutonE(PIN_BUTTON_E, 'E');
MonBouton BoutonF(PIN_BUTTON_F, 'F');


void setup()
{
  Serial.begin(115200);
}

void loop(){}