MTclock: Exemple 2

Ce programme va envoyer régulièrement toutes les secondes une lettre sur la console. Il y a 5 letrres à envoyer de A à E.

Principe: Un monostable A attend 1s puis envoie la lettre A et déclenche le deuxième monostable B. Ce dernier attend 1s, envoie la lettre b et ainsi de suite. Il y a 5 lettres à envoyer, on va utiliser 5 monostables. C'est plus à but pédagogique pour montrer que si MTobject possède une horloge simple et une double, on peut facilement faire des triples, quadruples, quintuples comme ici... Si on devait faire le meilleur programme répondant à cet énoncé, j'utiliserai un métronome et un compteur modulo 5 qui indiquerait la lettre à envoyer.

Envoi d'une lettre

On va donc utiliser 5 monostables que je vais nommer MonostableA, ... MonostableE. Ils sont tous bâtis sur le même modèle. Le monostableX appelle au bout d'une seconde la fonction envoiX qui écrit la lettre et déclenche le monostable suivant:

void envoiA(void) 
{
  Serial.print('A');
  MonostableB.start();
}

MTclock MonostableA(1000 milli_secondes, envoiA, 1 action_et_arret, MT_OFF);

Je n'ai pas mis de commentaires sur la fonction, elle me paraît suffisamment explicite. Pour la dernière ligne, cela définit une variable (un objet en réalité) nommé MonostableA de type MTclock. On peut ensuite définir les paramètres passés. On peut omettre les paramètres en partant de la fin si la valeur par défaut nous convient.

Le premier paramètre est le temps de retard. Il est exprimé en millisecondes et comme on veut 1s, il faut mettre 1000. Le milli_secondes est un mot commentaire ignoré par le compilateur. On reconnait ces mots à la présence d'un caractère "_" au milieu de plein de lettres minuscules sans avoir ce caractère en début.

Puis suit le nom de la fonction qui est appelée en fin de comptage. C'est envoieA.

On peut donner ensuite le nombre d'actions à faire. Ici on n'en fait qu'une seule (on écrit une seule lettre) et on s'arrête. C'est le dernier monostable qui va redéclencher MonostableA. On doit donc mettre le nombre 1. Pour ne pas le confondre avec une seconde, on rajoute le mot commentaire action_et_arret.

Enfin, on indique que les monostables sont "OFF", c'est à dire à l'arrêt au départ. Il s’activent les uns les autres. Toutefois il faut qu'il y en ait un (et un seul) qui soit actif. On va par exemple prendre le MonostableA actif au départ et son dernier paramètre sera MT_ON. Comme c'est la valeur par défaut et que c'est le dernier paramètre, on peut l'omettre. Mais le laisser est sans doute plus compréhensible.

Prédéfinition

Dans la définition d'un monostable, il y a un paramètre qui donne le nom de la fonction. Il faut donc que la fonction soit définie avant. Et dans la fonction appelée par le monostable A, il y a un appel par start pour le monostable B. Il faut donc définir le monostable B avant le A. E il faut de même définir le C avant le B, le D avant le C... Mais il faut aussi définir le A avant le E. On est coincé! La solution est donc de prédéfinir par exemple la fonction envoieE en ne donnant au début que son entête. Le reste sera défini à la fin. Cela donne alors:

void envoiE(void); // Prédéfinition car elle contient référence à monostableA
MTclock MonostableE(1000 milli_secondes, envoiE, 1 action_et_arret, MT_OFF);

void envoiD(void) { Serial.print('D'); MonostableE.start(); }
MTclock MonostableD(1000 milli_secondes, envoiD, 1 action_et_arret, MT_OFF);

void envoiC(void) { Serial.print('C'); MonostableD.start(); }
MTclock MonostableC(1000 milli_secondes, envoiC, 1 action_et_arret, MT_OFF);

void envoiB(void) { Serial.print('B'); MonostableC.start(); }
MTclock MonostableB(1000 milli_secondes, envoiB, 1 action_et_arret, MT_OFF);

void envoiA(void) { Serial.print('A'); MonostableB.start(); }
MTclock MonostableA(1000 milli_secondes, envoiA, 1 action_et_arret, MT_ON);

void envoiE(void) { Serial.println('E'); MonostableA.start(); }

Le reste

Il faut comme dans tous les programmes qui utilisent MTobjets, inclure la bibliothèque utile. Ici on utilise comme seul objet une horloge utilisée en monostable (le nom de l'objet est MTclock):

#include "MTclock.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.

Il faudra aussi initialiser la liaison série:

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 métronome.

Programme complet

Voici donc le programme complet:

// Ce programme envoie 5 lettres en boucle sur la voie série

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

void envoiE(void); // Prédéfinition car elle contient référence à monostableA
MTclock MonostableE(1000 milli_secondes, envoiE, 1 action_et_arret, MT_OFF);

void envoiD(void) { Serial.print('D'); MonostableE.start(); }
MTclock MonostableD(1000 milli_secondes, envoiD, 1 action_et_arret, MT_OFF);

void envoiC(void) { Serial.print('C'); MonostableD.start(); }
MTclock MonostableC(1000 milli_secondes, envoiC, 1 action_et_arret, MT_OFF);

void envoiB(void) { Serial.print('B'); MonostableC.start(); }
MTclock MonostableB(1000 milli_secondes, envoiB, 1 action_et_arret, MT_OFF);

void envoiA(void) { Serial.print('A'); MonostableB.start(); }
MTclock MonostableA(1000 milli_secondes, envoiA, 1 action_et_arret, MT_ON);

void envoiE(void) { Serial.println('E'); MonostableA.start(); }


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

void loop(){}