LOCODUINO

Forum de discussion
Dépôt GIT Locoduino

dimanche 26 février 2017

39 visiteurs en ce moment

Bibliothèque ScheduleTable

. Par : Jean-Luc

La gestion du temps a déjà fait l’objet d’un article « Comment gérer le temps dans un programme ? ». Les applications pour nos réseaux nécessitent fréquemment d’enchaîner des actions avec des temporisations entre elles, actionner un moteur d’aiguillage à solénoïde, gérer des animations lumineuses ou mécaniques, etc. Mais force est de constater que les choses restent complexes quand il s’agit d’ordonnancer dans le temps de nombreuses tâches que l’on veut multiplexer sur le même Arduino. Les programmes deviennent rapidement des usines à gaz dont la complexité devient difficilement maîtrisable.

Devant ce constat, nous vous proposons une bibliothèque originale permettant d’ordonnancer des actions dans le temps. Nous espérons qu’elle vous facilitera la tâche.

Qu’est ce qu’une Schedule Table

Une Schedule Table ou table d’ordonnancement en français est une structure permettant d’ordonnancer des actions dans le temps. Elle possède une période, c’est à dire une durée, et peut recevoir une ou plusieurs actions. Par exemple on peut représenter une table d’ordonnancement de période 32 comme ceci :

PNG - 4.9 ko

On dispose ensuite des actions aux dates voulues à l’intérieur de la table d’ordonnancement. Supposons par exemple que nous voulions faire une table d’ordonnancement pour un feu routier. Le feu reste rouge pendant 16 secondes. Puis il passe au vert et le reste pendant 14 secondes. Puis il passe à l’orange et le reste pendant 2 secondes. Les actions sont allumerRouge(), allumerVert() et allumerOrange() et sont disposées comme suit dans la table d’ordonnancement.

PNG - 19.1 ko

Ensuite, pour effectuer le cycle du feu, il suffit de répéter la table d’ordonnancement à l’infini, le 0 de la répétition suivante coïncidant avec le 32 de la répétition courante. Comme ceci :

PNG - 22.8 ko

Voilà nous avons posé les bases du fonctionnement. La bibliothèque ScheduleTable permet de définir des tables d’ordonnancements, de donner leur période, d’y placer des actions, de les démarrer pour un nombre de répétitions infini, de les démarrer pour un nombre de répétitions fixé, et de les stopper.

Créer une table d’ordonnancement

Après avoir importé la bibliothèque, ce qui insère un #include <ScheduleTable.h> en tête de votre sketch, nous pouvons créer autant de tables d’ordonnancement que nous le désirons comme ceci :

  1. ScheduleTable cycleClignote(1,500);

Le premier argument est le nombre maximum d’actions que peut contenir la table d’ordonnancement, ici 1, et le second sa période, en millisecondes, ici 500, soit 0,5 secondes.

Ajouter des actions

Deux types d’actions sont possibles : soit l’appel d’une fonction qui ne renvoie aucune valeur et ne prend aucun argument, soit un objet instance d’une classe dérivée de ScheduleTableAction.

Voyons tout d’abord les actions qui sont des appels de fonction. Définissons une fonction pour changer l’état de la fameuse DEL   de la broche 13 :

  1. void toggleDEL13()
  2. {
  3. }

Nous pouvons ajouter des actions dans la table d’ordonnancement à concurrence du nombre maximum. Ceci est fait dans setup(). Par exemple, pour changer l’état de la DEL   13 après 250ms, on écrira :

  1. cycleClignote.at(250, toggleDEL13);
Si la date d’une action est plus grande que la période de la table d’ordonnancement, l’action ne sera pas exécutée.
 

Démarrer la table d’ordonnancement

Après avoir préparé la table d’ordonnancement, il faut la démarrer, comme ceci :

  1. cycleClignote.start();

Enfin, pour que les tables d’ordonnancement qui ont été préparées et démarrées fonctionnent, il faut les titiller dans loop() comme ceci :

  1. ScheduleTable::update(); // met à jour toutes les tables d'ordonnancement

Et voici le code complet du programme :

  1. #include <ScheduleTable.h>
  2.  
  3. ScheduleTable cycleClignote(1,500);
  4.  
  5. void toggleDEL13()
  6. {
  7. }
  8.  
  9. void setup() {
  10. pinMode(13, OUTPUT);
  11. cycleClignote.at(250,toggleDEL13);
  12. cycleClignote.start();
  13. }
  14.  
  15. void loop() {
  16. ScheduleTable::update();
  17. }

Télécharger

Gérer plusieurs tables simultanément

Beaucoup de choses pour faire clignoter une DEL, me direz vous. Nous allons compliquer les choses pour montrer l’intérêt de la bibliothèque. Supposons maintenant que vous vouliez faire un feu d’avertissement de chantier, du genre de ceux qui émettent une paire de flashs toutes les secondes en plus de la DEL 13. Connectons cette DEL sur la broche 8 et écrivons une fonction permettant de changer son état :

  1. void toggleDEL8()
  2. {
  3. }

Fixons la période à 2 secondes. 500 ms après le démarrage de la table d’ordonnancement, la DEL est allumée, éteinte 30 ms après puis rallumée 200 ms après et enfin éteinte 30 ms après. Les instants sont donc : 500, 530, 730 et 760. Construisons notre table d’ordonnancement, nous avons besoins de 4 actions :

  1. ScheduleTable cycleFlash(4,2000); // 4 actions, période de 2000 ms

Les actions sont ensuite positionnées :

  1. cycleFlash.at(500, toggleDEL8);
  2. cycleFlash.at(530, toggleDEL8);
  3. cycleFlash.at(730, toggleDEL8);
  4. cycleFlash.at(760, toggleDEL8);

puis la table d’ordonnancement démarrée :

  1. cycleFlash.start();

Voici le programme complet :

  1. #include <ScheduleTable.h>
  2.  
  3. ScheduleTable cycleFlash(4,2000);
  4. ScheduleTable cycleClignote(1,300);
  5.  
  6. void toggleDEL13()
  7. {
  8. }
  9.  
  10. void toggleDEL8()
  11. {
  12. }
  13.  
  14. void setup() {
  15. pinMode(8, OUTPUT);
  16. pinMode(13, OUTPUT);
  17.  
  18. cycleFlash.at(500, toggleDEL8);
  19. cycleFlash.at(530, toggleDEL8);
  20. cycleFlash.at(730, toggleDEL8);
  21. cycleFlash.at(760, toggleDEL8);
  22.  
  23. cycleClignote.at(150, toggleDEL13);
  24.  
  25. cycleFlash.start();
  26. cycleClignote.start();
  27. }
  28.  
  29. void loop() {
  30. ScheduleTable::update();
  31. }

Télécharger

Il est donc possible de préparer et de démarrer de multiples tables d’ordonnancement de manière indépendante les unes des autres.

Utilisation d’un objet au lieu d’une fonction

Nous venons de voir des actions qui sont des appels de fonction. Il est également possible de rendre un objet cible de l’action. Dans ce cas, la table d’ordonnancement appelle la méthode action de l’objet. La classe de l’objet doit hériter de la classe ScheduleTableAction comme ceci :

  1. class Led : public ScheduleTableAction
  2. {
  3. private:
  4. byte mPin;
  5.  
  6. public:
  7. Led(byte pin) : mPin(pin) {}
  8.  
  9. void begin()
  10. {
  11. pinMode(mPin, OUTPUT);
  12. digitalWrite(mPin, LOW);
  13. }
  14.  
  15. virtual void action()
  16. {
  17. digitalWrite(mPin, !digitalRead(mPin));
  18. }
  19. };

Vous pouvez vous référer à la série d’article de Thierry : « Le monde des objets (1) », « Le monde des objets (2) » et « Le monde des objets (3) » sur la programmation objet.

Nous pouvons ensuite instancier un objet de type Led et une table d’ordonnancement pour la faire clignoter :

  1. Led led13(13);
  2. ScheduleTable clignote(1,500);

puis démarrer la DEL, ajouter l’action et démarrer la table dans setup()

  1. void setup() {
  2. led13.begin();
  3. clignote.at(250, led13);
  4. clignote.start();
  5. }

Les fonctions de la bibliothèque

Déclaration d’une table d’ordonnancement

Une table d’ordonnancement est une instance de la classe ScheduleTable. Une table d’ordonnancement est déclarée de la manière suivante :

  1. ScheduleTable maTable(10, 10000);

ou 10 est le nombre d’actions que peut contenir la table au maximum et 10000 la période de la table en millisecondes. On peut également changer l’unité de temps ce qui peut être pratique si la table gère des durées importante. Dans ce cas un 3e argument donne le nombre de millisecondes que dure l’unité de temps. Ainsi la déclaration suivante :

  1. ScheduleTable cycleFeuTricolore(3, 32, 1000);

crée une table d’ordonnancement de 3 actions, les changements d’état du feu, dont la période est de 32 unités de temps, une unité de temps valant 1000 millisecondes soit 1 seconde. Les dates des actions seront données en secondes.

La période et l’unité de temps sont des nombres entiers sur 32 bits.

Positionnement des actions

Une action est positionnée dans le temps à une date relative au début de la table, et en utilisant l’unité de temps de la table. Pour cela, on utilise la méthode at. Le premier argument est la date où l’action est positionnée. Le second argument est l’action qui peut être soit une fonction, soit un objet dérivé de la classe ScheduleTableAction. Si maFonction est une fonction de la forme void maFonction(), on peut écrire :

  1. maTable.at(4765,maFonction); // pas de parenthèses après maFonction !

maFonction sera appelée quand la date 4765 sera arrivée.

De même si monObjet est une instance d’une classe dérivée de la classe ScheduleTableAction, on peut écrire :

  1. maTable.at(4765,monObjet);

la méthode action() de cet objet sera appelée quand la date 4765 sera arrivée.

Démarrage et arrêt d’une table d’ordonnancement

La méthode start(...) permet de démarrer une table d’ordonnancement. Deux formes sont possibles :

  1. maTable.start();

démarre maTable pour un nombre de périodes infini.

  1. maTable.start(n);

démarre maTable pour n périodes.

Il est également possible de stopper une table d’ordonnancement :

  1. maTable.stop();

Changement de la période

La période d’une table d’ordonnancement peut être changée au moyen de la méthode setPeriod(...) qui prend comme unique argument la nouvelle période de la table :

  1. maTable.setPeriod(15000);

Zip - 13.9 ko
Bibliothèque ScheduleTable

Après avoir téléchargé et décompressé l’archive, vous obtenez un répertoire nommé ScheduleTable-master. Renommez le pour retirer le -master et ne garder que ScheduleTable puis placer le dans le répertoire libraries de votre répertoire Arduino

3 Messages

Réagissez à « Bibliothèque ScheduleTable »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Bibliothèques »

Bibliothèque Servo

Bibliothèque SoftWare Serial

Bibliothèque Serial

Bibliothèque EEPROM

Bibliothèque Wire : I2C

Bibliothèque LCD

Bibliothèque ScheduleTable

Bibliothèque MemoryUsage

Bibliothèque EEPROMextent

Bibliothèque Commanders

Un décodeur d’accessoires universel (1)

Un décodeur d’accessoires universel (2)

Un décodeur d’accessoires universel (3)

Bibliothèque Accessories (1)

Bibliothèque Accessories (2)

Les derniers articles

Bibliothèque Accessories (2)


Thierry

Bibliothèque Accessories (1)


Thierry

Bibliothèque Commanders


Thierry

Bibliothèque MemoryUsage


Thierry

Bibliothèque Wire : I2C


Dominique, Guillaume

Bibliothèque Serial


Dominique, Guillaume, Jean-Luc

Bibliothèque SoftWare Serial


Dominique, Guillaume

Bibliothèque LCD


Dominique, Guillaume, Jean-Luc

Bibliothèque EEPROMextent


Thierry

Bibliothèque EEPROM


Dominique, Guillaume

Les articles les plus lus

Bibliothèque Wire : I2C

Un décodeur d’accessoires universel (1)

Bibliothèque Servo

Bibliothèque EEPROM

Bibliothèque Serial

Bibliothèque LCD

Bibliothèque Commanders

Bibliothèque ScheduleTable

Bibliothèque Accessories (1)

Bibliothèque Accessories (2)