Déclaration d'un objet statique, utilisation de onSelectFunction Voir Clock: Exemple-801-Clock-Statique-onTimeFunction.ino
Déclaration d'un objet dynamique globale, utilisation de onSelectFunction Voir Clock: Exemple-802-Clock-Dynamique-onTimeFunction.ino
Déclaration d'un objet dynamique dans le setup(), utilisation de onSelectFunction Voir Clock: Exemple-803-Clock-Dynamique-setup-onTimeFunction.ino
Déclaration d'un objet statique, nouvelle classe Voir Clock: Exemple-804-Clock-Statique-Classe.ino
Déclaration d'un objet dynamique globale, nouvelle classe Voir Clock: Exemple-805-Clock-Dynamique-Classe.ino
Déclaration d'un objet dynamique dans le setup(), nouvelle classe Voir Clock: Exemple-806-Clock-Dynamique-setup-Classe.ino
Déclaration d'un objet dynamique dans le setup() sans pointeur, nouvelle classe Voir Clock: Exemple-807-Clock-SansPointeur-Classe.ino
Pour se détendre, utilisation de Timer et PushZone Voir Clock: Exemple-808-Clock-Sapin_de_Noel.ino
Dans les exemples qui suivent un métronome change la couleur de l'écran toutes les deux scondes.
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 métronomes 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.
Les 7 premiers exemples montrent 7 façons (parfois assez semblables) de déclarer un métronome.
De la même façon on peut déclarer tous les objets (horloges, mais aussi boutons...). Ces 7 exemples
ne seront pas repris systématiquement, sauf pour le premier bouton.
Le huitième exemple est une application sympathique.
Premier exemple: déclaration statique
C'est la façon la plus simple d'utiliser un métronome. L'instance est statique.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-801-Clock-Statique-onTimeFunction\Exemple-801-Clock-Statique-onTimeFunction.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 1:
// - L'horloge a une définition statique
// - Utilise onTimeFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration statique de l'instance, doit se faire en dehors du setup
// Si on la définissait dans le setup elle serait détruite au sortir du setup et
// en pariculier lorsque l'on en a besoin (dans le loop).
Clock metronome(2000); // Déclaration d'un métronome, action toutes les 2 secondes
// Déclaration d'une fonction qui fera ce qu'il faut faire toutes les fin de comptage
// Peut se mettre avant ou après la déclaration de la variable
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
void onTimeAction(void)
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
// Association de la fonction qui va faire le travail avec le métronome
// Attention, il y a un caractère "&" avant le nom de la fonction.
// Cette ligne veut dire: metronome a une propriété onTimeFunction et on va
// affecter cette propriété avec l'adresse (présence du "&") de onTimeAction
metronome.onTimeFunction=&onTimeAction; // Fonction à appeler toutes les secondes
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Deuxième exemple: déclaration dynamique avant le setup.
Quand on déclare l'instance, on obtient un pointeur sur metronome. les pointeurs sont utiles pour
parcourir différents objets. En pricipe, cela a peu d'intérêt. Si on voulait accéder à une liste
d'hologe, on peut passer par la liste du gestionnaire.
La déclaration est faite ici avant le setup
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-802-Clock-Dynamique-onTimeFunction\Exemple-802-Clock-Dynamique-onTimeFunction.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 2:
// - L'horloge a une définition dynamique avant le setup
// - Utilise onTimeFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration dynamique de l'instance, peut se faire en dehors du setup
// Dans ce cas horloge est accessible partout
Clock *horloge = new Clock(2000); // Déclaration d'un métronome, action toutes les 2 secondes
// Déclaration d'une fonction qui fera ce qu'il faut faire toutes les fin de comptage
// Peut se mettre avant ou après la déclaration de l'instance horloge
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
void onTimeAction(void)
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
// Association de la fonction qui va faire le travail avec le métronome
// Attention, il y a un caractère "&" avant le nom de la fonction.
// Cette ligne veut dire: metronome a une propriété onTimeFunction et on va
// affecter cette propriété avec l'adresse (présence du "&") de onTimeAction
horloge->onTimeFunction=&onTimeAction; // Fonction à appeler toutes les secondes
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Troisième exemple: déclaration dynamique dans le setup.
C'est pratiquement la même chose que dans l'exemple précédent, mais l'instance est déclarée dans
le setup. Dans ce cas, l'instance est dans la pile et est accessible tout le temps, mais seul le
pointeur est détruit au sortir du setup. Ou pourrait aussi sur le même principe déclarer l'instance
dans une fonction.
Même si le pointeur est détruit au sortir de la fonction, pendant qu'il exixte, on peut accéder
à l'objet. Cela permet en particuler d'utiliser une boucle pour définir plusieurs objets semblables
dans le style: Clock *horloge;
for (byte numero=0; numero<10; numero++)
{
horloge = new Clock(random(100)*100+1000*numero); // Déclaration d'un métronome, action n'importe quand
horloge->onTimeFunction=&onTimeAction; // Fonction à appeler
}
Dans cet exemple, il va y avoir 10 métronomes qui battent avec des périodes différentses. Au bout du compte,
la fonction onTimeAction() va être appellé pseudoaléatoirement.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-803-Clock-Dynamique-setup-onTimeFunction\Exemple-803-Clock-Dynamique-setup-onTimeFunction.ino (dans votre fichier téléchargé):
// Version 3:
// - L'horloge a une définition dynamique dans le setup()
// - Utilise onTimeFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration d'une fonction qui fera ce qu'il faut faire toutes les fin de comptage
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
void onTimeAction(void)
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
// Déclaration dynamique de l'instance, faite dans une fonction
// Dans ce cas l'instance est accessible partout, mais le pointeur
// horloge sera détruit en sortant de la fonction (ici du setup())
Clock *horloge = new Clock(2000); // Déclaration d'un métronome, action toutes les 2 secondes
// Association de la fonction qui va faire le travail avec le métronome
// Attention, il y a un caractère "&" avant le nom de la fonction.
// Cette ligne veut dire: metronome a une propriété onTimeFunction et on va
// affecter cette propriété avec l'adresse (présence du "&") de onTimeAction
horloge->onTimeFunction = &onTimeAction; // Fonction à appeler toutes les secondes
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Quatrième exemple: Surcharge de onTime, déclaration statique.
Si on a besoin de plusieurs horloges ayant des comportements identiques, on a vu qu'on peut écrire
une fonction externe pour gérer la fin du comptage. Pour chaque horloge, il faudra alors lui associer
cette fonction externe. En définissant une classe fille de Clock et en surchargeant onTime(), on
aura plus qu'a déclarer l'instance, la fonction étant dedans. C'est un peu plus lourd, mais le code
peut être plus clair.
Notez que l'on n'a pas besoin d'accéder au métronome un fois défini, le nom de la variable ne nous
sert à rien
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-804-Clock-Statique-Classe\Exemple-804-Clock-Statique-Classe.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 4:
// - On définir une classe Metronome, dérivée de Clock, avec le bon comportement
// - Metronome a une définition statique
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Metronome: public Clock // Nouvelle classe pour redéfinir onTime
{
public:
Metronome(unsigned long duree):Clock(duree){} // Constructeur qui copie la classe mère
virtual void onTime(void) // Nouveau comportement
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
// Déclaration statique de l'instance, doit se faire en dehors du setup
// Si on la définissait dans le setup elle serait détruite au sortir du setup et
// en pariculier lorsque l'on en a besoin (dans le loop).
Metronome metronome(2000); // Déclaration d'un métronome, action toutes les 2 secondes
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}
Cinquième exemple: Surcharge de onTime, déclaration dynamique.
Si l'on crée une nouvelle classe, il est aussi possible de définir des insances sur les pointeurs.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-805-Clock-Dynamique-Classe\Exemple-805-Clock-Dynamique-Classe.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 5:
// - On définir une classe Metronome, dérivée de Clock, avec le bon comportement
// - Metronome a une définition dynamique
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Metronome: public Clock // Nouvelle classe pour redéfinir onTime
{
public:
Metronome(unsigned long duree): Clock(duree) {} // Constructeur qui copie la classe mère
virtual void onTime(void) // Nouveau comportement
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
// Déclaration dynamique de l'instance, peut se faire en dehors du setup
// Dans ce cas metronome est accessible partout
Metronome *metronome = new Metronome(2000); // Déclaration d'un métronome, action toutes les 2 secondes
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}
Sixième exemple: Surcharge de onTime, déclaration dynamique dans une fonction.
Comme cela a été fait plus haut, que l'on dérive une nouvelle classe ou pas, on peut créer
l'instance metronome dans une fonction. Comme tout à l'heure, l'instance existe partout, mais le
pointeur metronome n'est accessible que dans la fonction qui l'a définie.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-806-Clock-Dynamique-setup-Classe\Exemple-806-Clock-Dynamique-setup-Classe.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 6:
// - On définir une classe Metronome, dérivée de Clock, avec le bon comportement
// - Metronome a une définition dynamique dans une fonction
#include ;lt&PecheuxGraph.h> // Appel de la bibliothèque
class Metronome: public Clock // Nouvelle classe pour redéfinir onTime
{
public:
Metronome(unsigned long duree): Clock(duree) {} // Constructeur qui copie la classe mère
virtual void onTime(void) // Nouveau comportement
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
// Déclaration dynamique de l'instance, peut se faire dans une fonction
// Dans ce cas l'instance est accessible partout, mais le pointeur
// horloge sera détruit en sortant de la fonction (ici du setup())
Metronome *metronome = new Metronome(2000); // Déclaration d'un métronome, action toutes les 2 secondes
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}
Septième exemple: Surcharge de onTime, déclaration dynamique dans une fonction, sans pointeur.
Dans la dernière version, on voit que l'on n'a pas besoin du pointeur. Dans ce cas, ce n'est pas la
peine d'en avoir un.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-807-Clock-SansPointeur-Classe\Exemple-807-Clock-SansPointeur-Classe.ino (dans votre fichier téléchargé):
// Mise en place d'un métronome. Toutes les 2s, il change la couleur du fond
// de l'écran
// Version 7:
// - On définir une classe Metronome, dérivée de Clock, avec le bon comportement
// - Metronome a une définition dynamique sans pointeur
#include ;lt&PecheuxGraph.h> // Appel de la bibliothèque
class Metronome: public Clock // Nouvelle classe pour redéfinir onTime
{
public:
Metronome(unsigned long duree): Clock(duree) {} // Constructeur qui copie la classe mère
virtual void onTime(void) // Nouveau comportement
{
clrscr(RANDOM_COLOR); // Action à faire chaque seconde
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
void setup()
{
setGraphMode(PAYSAGE); // Pour pouvoir utiliser clrscr()
// Déclaration dynamique de l'instance, mais on n'a pas besoin du pointeur
// On peut donc créer une instance sans avoir une référence.
new Metronome(2000); // Déclaration d'un métronome, action toutes les 2 secondes
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}
Huitième exemple: Le sapin de Noël.
35 métronomes avec un Uno, et une boucle quasi obligatoire our tout initialiser, en dérivant
une nouvelle classe. C'est plus une démonstration. On peut mettre 250 métronomes avec un Mega
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-808-Clock-Sapin_de_Noel\Exemple-808-Clock-Sapin_de_Noel.ino (dans votre fichier téléchargé):
// Ce programme dessine un sapin de Noël puis 35 métronomes vont faire
// changer de couleur les 35 boules de Noël à des instants légèrement
// différents (entre 2 et 2,1 seconde). Au début, les boules changent de
// couleur presque en même temps, puis à la longue, elles vont devenir
// indépendantes
// Avec un Mega, on peut mettre 250 métronomes
#include <PecheuxGraph.h>
// Comme le comportement de chaque métronome est légèrement différent, a
// savoir que la boule associée est positionnée différemment pour chacun
// d'eux, il faut que chaque métronome mémorise ces coordonnes. Dériver
// une nouvelle classe est une bonne solution
const word couleurs[]={RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW};
class Boule: public Clock
{
public:
Boule(int x, int y, unsigned long duree): Clock(duree)
{
this->x = x; this->y = y; // Dans ce constructeur, on rajoue l'initialisation des coordonnées
}
int x; int y; // Coordonnée de la boule associée
virtual void onTime(void) // Nouveau comportement
{
fillRect(x, y, x+2, y+2, couleurs[random(6)]); //On change de couleur la boule associée (5 chances sur 6!)
}
};
void setup()
{
long x, y; // Coordonnés d'un point
setGraphMode(PORTRAIT);
// Le sapin
if (bpxDraw("TOOLS/NOEL.BPX", 0, 0)) // Photo d'un sapin
{ // Pas de carte ou pas de fichier, on va tout dessiner à la main
line(0, 240, 134, 223, BISQUE); lineTo(239,258); fill(134,250, BISQUE); // Sol
fill(0,0,LIGHT_YELLOW); // Mur
line(121, 38, 50, 241, DARK_GREEN); lineTo(177, 241); lineTo(121, 38); // Contour du sapin
fill(121, 50, DARK_GREEN); fill(121, 239, DARK_GREEN); //Vert du sapin
fillRect(110,240,132,290,DARK_RED); // Tronc
}
// Déclaration des 40 métronomes. Comme il y en a beaucoup, une boucle
// est bienvenue. On est donc obligé d'avoir une déclaration dynamique. On
// n'a pas besoin du pointeur créé, on n'en utilise pas
for (byte nombre = 0; nombre < 35; nombre++) // Au dela de 40 avec un Uno, la pile déborde et le programme plante
{
do
{
x = random(178); // Coordonnées au hasard, mais pour l'instant cela risque de dépasser du sapin
y = random(242);
}
// Pour la condition pas trop à gauche, le sapin étant vaguement
// triangulaire, il ne faut pas que les points soient à gauche de la
// droite passant par (121,38) et (50,241). Il faut calculer l'équation
// de la droite du type ax+by+c; si c'est nul, on est sur la droite, si
// c'est négatif, on est dans un des deux demi-plan, si c'est positif on
// est dans l'autre demi-plan. Un essai nous dira si on a pris le bon.
// le point (x,y) est sur la droite passant par (x1,y1) et (x2,y2) si
// x - x1 x1 - x2
// ------ = -------
// y - y1 y1 - y2
// L'équation de la droite recherchée est:
// (x - x1)*(y1 - y2) - (y - y1)*(x1 - x2) = 0
// on testera si le membre de droite est nul (on est sur la limite du sapin)
// positif (on est d'un côté)
// négatif (on est de l'autre côté)
while ((203*x+71*y-27261<=0) // Pas trop à gauche
|| (203*x-56*y-22425>=0)); // Pas trop à droite
new Boule(x-1, y-1, 500 + nombre); // (x,y) étant dans le sapin, on créé le métronome
}
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans loop()
}
Voir aussi:
- scanEvent(); Moteur de la gestion des évènements
- Timer; Temporisateur (une action une seule fois)
|