Timer()

Timer est une classe de temporisateurs. Ce sont des horloges qui vont délivrer un événement onTime un certain temps après avoir été armés par start().

 

Exemples d'utilisation

Timer temporisateur(); // Crée temporisateur avec un comptage de 1s (par défaut)
Timer temporisateur(2000); // Crée temporisateur avec un comptage de 2s
Timer temporisateur = new Timer(); // Crée une instance dynamique temporisateur
Timer temporisateur = new Timer(500); // Pareil, sauf une durée de temporisation de 0,5s
new Timer(); // Crée une instance dynamique temporisateur sans pointeur dessus

temporisateur.actif=false; // Interdit, utiliser stop()
temporisateur.actif=true; // Interdit, utiliser start()
if (temporisateur.actif) ... // permet d'interroger son activité

temporisateur.duree=2000; // Change la durée de la temporisation.
temporisateur.duree = temporisateur.duree*2; // Double le temps de la temporisation

Serial.println("On en est à "+String(millis()-temporisateur.depart)+"ms"); // "On en est à 100ms":

temporisateur.onTimeFunction = & action; // Appel à void action(void) en fin de temporisation

temporisateur.start(); // Démarre (ou redémarre) le temporisateur

temporisateur.stop(); // Arrête le temporisateur

temporisateur.onTime(); // Ne fait rien par défaut!

 

Référence

class Timer
 public:
  Timer(unsigned long duree_ms=1000);
  boolean actif;
  unsigned long duree_ms;
  unsigned long depart;
  void (*onTimeFunction)(void);
  Clock *horlogeSuivante;
  void start(void);
  void stop(void);
  virtual void onTime(void);

Attributs et méthodes

Clock(): Constructeur, s'insère dans la liste des horloges gérées. duree_ms: période en ms
actif: false par défaut . Passe à true pendant la temporisation. Lecture seule
duree_ms: Durée de la temporisation exprimée en millisecondes
depart: Temps en ms depuis le début de la temporisation
*onTimeFunction: Pointeur sur une fonction sans paramètre et ne retournant rien qui sera appelée à chaque fin de temporisation
*horlogeSuivante: Pointeur sur l'horloge suivante dans la liste des horloges
start(): Permet de déclencher la temporisation. Réinitialise la temporisation si elle est en cours
stop(): Arrête la temporisation
onTime(): Appelée en fin de temporisation, elle peut être surchargée pour définir des comportements supplémentaires. Par défaut elle ne fait rien.

 

Voir aussi

- scanEvent(); Moteur de la gestion des événements
- Clock; Métronome (actions régulières)

 

Notes

Quand un temporisateur est créé, il est inactif. Lorsqu'on le déclenche par sa méthode start(), il déclenche une action, au bout du temps déterminé par "duree_ms". Pour avoir une action suivante, il faut le déclencher de nouveau. Un déclenchement en cours de temporisation remet le comptage à zéro.

Une fois la temporisation écoulée, il faut attendre que scanEvent() fasse son travail. Il faut donc éviter de bloquer loop avec l'utilisation de delay().

La durée du temporisateur est donnée par un entier long non signé (duree_ms). Naturellement la temporisation maximale est d'environ 50 jours. Pour avoir des temps plus longs, on peut ne déclencher l'action voulue que si le temporisateur a déclenché X fois.

La fonction onTime() n'a pas un gros intérêt pour écrire un programme sauf si on désire surcharger cette fonction en créant une classe fille. Voir les exemples complets.

 

Exemple

Dans les deux premiers exemples, deux temporisateurs changent la couleur de l'écran, noir 3 secondes, couleur 1/2 seconde. Il y a plusieurs façons de le faire, on peut la plupart du temps n'utiliser que la première forme. D'autres sont intéressantes si on a plusieurs temporisateurs identiques, mais dans l'exemple simplifié, comme c'est la mise en place qui me préoccupe, les programmes sont réduits, et l'intérêt de telles déclarations n'apparaît plus. Toutes les formes des appels sont semblables aux appels de Clock pour lesquels tout est détaillé. Reportez-vous à Clock pour plus de détail. Ici n'est décrit ce qui est le plus courant.

Le troisième exemple montre une utilisation des variables actif, depart et duree_ms. De plus elle montre un cas rare ou scanEvent() n'est pas tout seul dans le loop.

Premier exemple: déclaration statique

PecheuxGraph_ILI9341_8bits.zip\PecheuxGraph_ILI9341_8bits\examples\Documentation\Exemple-810-Timer-Statique\Exemple-810-Timer-Statique.ino (dans votre fichier téléchargé):

// Mise en place de deux temporisateur. L'un colorie l'écran au bout de 3
// secondes, l'autre efface l'écran au bout d'une demi-seconde. Il se
// déclenchent l'un l'autre. Du coup, l'écran se colorie une demi-seconde,
// s'éteint trois secondes...

#
  $menu = ":PG";
  include <PecheuxGraph_ILI9341_8bits.h> // Appel de la bibliothèque 

 
// Déclarations statique des instances
Timer temporisateurQuiAllume(3000); // Déclaration  d'un temporisateur, qui attendra 3s avant d'allumer l'écran
Timer temporisateurQuiEteint(500); // Déclaration  d'un temporisateur, qui attendra 1/2s avant d'éteindre l'écran


// Déclaration des fonctions qui feront ce qu'il faut faire toutes les fin de comptage
void fautAllumer(void) // Action à faire au bout de 3s
{
  clrscr(RANDOM_COLOR); // Allume l'écran
  temporisateurQuiEteint.start(); // Démarre son copain
}
void fautEteindre(void) // Action à faire au bout d'une demi-seconde
{
  clrscr(); // Eteint l'écran
  temporisateurQuiAllume.start(); // Démarre son copain
}


void setup()
{
  setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()

  // Associations des fonctions
  temporisateurQuiAllume.onTimeFunction=&fautAllumer;
  temporisateurQuiEteint.onTimeFunction=&fautEteindre;

  // Déclenchement la première fois d'un temporisateurs. Par défaut, ils sont désactivés.
  // Quand, l'un s'arrête, il se désactive et active son copain. Par contre il faut initier
  // la boucle
  temporisateurQuiAllume.start();
}


void loop()
{
  scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}

Deuxième exemple: Déclaration dynamique

PecheuxGraph_ILI9341_8bits.zip\PecheuxGraph_ILI9341_8bits\examples\Documentation\Exemple-811-Timer-Dynamique\Exemple-811-Timer-Dynamique.ino (dans votre fichier téléchargé):

// Mise en place de deux temporisateur. L'un colorie l'écran au bout de 3
// secondes, l'autre efface l'écran au bout d'une demi-seconde. Il se
// déclenchent l'un l'autre. Du coup, l'écran se colorie une demi-seconde,
// s'éteint trois secondes...

#
  $menu = ":PG";
  include <PecheuxGraph_ILI9341_8bits.h> // Appel de la bibliothèque 


// Déclarations dynamique des instances
Timer *temporisateurQuiAllume = new Timer(3000); // Déclaration  d'un temporisateur, qui attendra 3s avant d'allumer l'écran
Timer *temporisateurQuiEteint = new Timer(500); // Déclaration  d'un temporisateur, qui attendra 1/2s avant d'éteindre l'écran


// Déclaration des fonctions qui feront ce qu'il faut faire toutes les fin de comptage
void fautAllumer(void) // Action à faire au bout de 3s
{
  clrscr(RANDOM_COLOR); // Allume l'écran
  temporisateurQuiEteint->start(); // Démarre son copain
}
void fautEteindre(void) // Action à faire au bout d'une demi-seconde
{
  clrscr(); // Eteint l'écran
  temporisateurQuiAllume->start(); // Démarre son copain
}


void setup()
{
  setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()

  // Associations des fonctions
  temporisateurQuiAllume->onTimeFunction = &fautAllumer;
  temporisateurQuiEteint->onTimeFunction = &fautEteindre;

  // Déclenchement la première fois d'un temporisateurs. Par défaut, ils sont désactivés.
  // Quand, l'un s'arrête, il se désactive et active son copain. Par contre il faut initier
  // la boucle
  temporisateurQuiAllume->start();
}


void loop()
{
  scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}

Troisième exemple: Utilisation de actif, depart et duree_ms

PecheuxGraph_ILI9341_8bits.zip\PecheuxGraph_ILI9341_8bits\examples\Documentation\Exemple-812-Maison-Timer-duree\Exemple-812-Maison-Timer-duree.ino (dans votre fichier téléchargé):

// L'intérieur d'une maison est dessinée. Deux boutons de type PushZone
// permettent d'allumer la lumière pendant 6s

// En principe scanEvent() est seul dans loop(). Ici c'est une exception, on
// va profiter de loop pour afficher l'état du temporisateur.

#
  $menu = ":PG";
  include <PecheuxGraph_ILI9341_8bits.h>

// Définition des objets
PushZone bouton1(186, 124, 212, 152); // Définit une zone cliquable, notre bouton de droite
PushZone bouton2(8, 124, 34, 152); // Définit une zone cliquable, notre bouton de gauche
Timer minuterie(6000); // Minuterie principale de 6 secondes


void aiguilleDuChronometre(void) // Le chronomètre au dessus de la porte
{
  if (minuterie.actif) // Si on compte le temps
  {
    float angle = ((millis() - minuterie.depart) * PI) / (minuterie.duree_ms >> 1); // angle que fait la ligne à tracer
    line(214, 26, 214 + 9 * sin(angle), 26 - 9 * cos(angle), RED); // Augmente le camembert rouge
  }
}


// Quand on appuie sur un bouton, on déclenche la minuterie, on dessine le chronomètre,
// et on allume la lampe
void debutMinuterie()
{
  // Démarre la temporisation
  minuterie.start();
  // Dessin de la minuterie (pour faire patienter)
  fillCircle(214, 26, 10, GREY); // Corps du chronomètre (efface le rouge si il en avait)
  circle(214, 26, 10, BLACK); // Monture
  fillCircle(205, 17, 2); fillCircle(214, 13, 2); fillCircle(223, 17, 2); // 3 boutons
  // On allume la lampe
  fill(160, 30, YELLOW);
}


// Quand le temps est écoulé, on efface le chronomètre et on éteint la lampe
void finMinuterie()
{
  fillRect(203, 11, 225, 36, GREY); // On efface le chronomètre
  fill(160, 30, BLACK); // On éteint la lampe
}


void setup()
{
  setGraphMode(PAYSAGE); // Initialisation

  // Consigne tout en bas
  setTextCursor(0, 180);
  text(F("\n Appuyez sur les boutons de\n  chaque côté de la fenêtre"));

  maison(1, 1); // On dessine l'intérieur de la maison
  fillRect(203, 11, 275, 36, GREY); // Boite en plastique contenant le chronomètre

  // Mise en place des comportements des objets
  bouton1.onClicFunction = &debutMinuterie; // Bouton de droite, c'est le début de la minuterie
  bouton2.onClicFunction = &debutMinuterie; // Bouton de gauche, c'est le début de la minuterie
  minuterie.onTimeFunction = &finMinuterie; // En fin de temporisation tout s'arrête

}

void loop()
{
  scanEvent(); // Lance le gestionnaire
  aiguilleDuChronometre(); // Dessine le camembert du chronomètre
}

 

Côté technique

En fait Timer ne fait pas grand chose, car c'est le grstionnaire scanEvent() qui vient demander les propriétés de Timer et qui calcule si le comptage du temps est fini ou non. C'est aussi le gestionnaire qui appelle onTime(), et la fonction pointée par onTimeFunction. Le rôle de Timer se borne à initialiser les valeurs lors de sa déclaration, et a se désactiver une fois la tâche accomplie.