Le principe est d'utiliser l'instruction "switch case" en créant un "case" pour chaque état.
Exemple :
Soit le diagramme d'état ci-dessous :
Le code C correspondant est :
enum Etat { ETAT_A, ETAT_B};
enum Etat etatCourant = ETAT_A;
void loop() {
switch(etatCourant) {
case ETAT_A :
// Insérer ici la/les action(s) à faire dans l’état A
break;
case ETAT_B :
// Insérer ici la/les action(s) à faire dans l’état B
break;
}
}
Une transition indique le passage d’un état (état source) dans un autre (état cible). Elle est représentée par une flèche orientée de l’état source vers l’état cible.
Syntaxe générale d’une transition :
{ <événement> } { [ <condition de garde> ]} { / <effet> }
Soit le diagramme d'état ci-dessous :
Le code C correspondant est :
enum Etat { ARRET, MARCHE};
enum Etat etatCourant = ARRET;
const float seuil = 20;
const float hyst = 0.5;
void loop() {
float temperature = getTemperature();
switch(etatCourant) {
case ARRET :
// Action état ARRET
if(temperature < seuil) { // Condition de garde : [temperature < seuil]
etatCourant = MARCHE;
}
break;
case MARCHE :
// Action état MARCHE
if(temperature > seuil + hyst) { // Condition de garde : [temperature > seuil + hyst]
etatCourant = ARRET;
}
break;
}
}
Soit le diagramme d'état ci-dessous :
Le code C correspondant est :
enum Etat { ARRET, MARCHE};
enum Etat etatCourant = ARRET;
const float seuil = 20;
const float hyst = 0.5;
void loop() {
float temperature = getTemperature();
switch(etatCourant) {
case ARRET :
// Action état ARRET
if(temperature < seuil) { // Condition de garde : [temperature < seuil]
etatCourant = MARCHE;
activerRelais(); // Effet : Action faite au moment de la transition
}
break;
case MARCHE :
// Action état MARCHE
if(temperature > seuil + hyst) { // Condition de garde : [temperature > seuil + hyst]
etatCourant = ARRET;
desactiverRelais(); // Effet : Action faite au moment de la transition
}
break;
}
}
Généralement pour les transitions sur événement, on utilise les interruptions de manière à ce que le système soit réactif.
Le principe est le même que pour les conditions de garde sauf que c'est la routine d'interruption qui va modifier la valeur de la variable "etatCourant".
Le code C correspondant est :
enum Etat { ARRET, MARCHE, MARCHE_FORCEE};
enum Etat etatCourant = ARRET;
const float seuil = 20;
const float hyst = 0.5;
unsigned int etatPrecedent = etatCourant;
unsigned long tempsTotalEcoule; // Temps (en ms) écoulé depuis le lancement du programme (! cette variable va revenir à 0 au bout d'eviron 50 jours)
unsigned long tempsAriveeDansEtatCourant = 0; // temps (en ms) du dernier changement d'état
const unsigned long _30_MINUTES = 1800000; // 30 min = 1 800 000 ms
void loop() {
float temperature = getTemperature();
bool etatBouton = getEtatBouton();
tempsTotalEcoule = millis(); // La fonction millis() renvoie le nombre de millisecondes depuis que le programme a démarré
if(etatPrecedent != etatCourant) { // On vient d'entrer dans un nouvel état
etatPrecedent = etatCourant;
tempsAriveeDansEtatCourant = tempsTotalEcoule; // Le temps d'arrivée dans le nouvel état est réinitialisé
}
switch(etatCourant) {
case ARRET : // Action état ARRET
if(temperature < seuil) { // Condition de garde : [temperature < seuil]
etatCourant = MARCHE;
activerRelais(); // Effet : Action faite au moment de la transition
}
if(etatBouton) { // Bouton appuyé
etatCourant = MARCHE_FORCEE;
activerRelais(); // Effet : Action faite au moment de la transition
}
break;
case MARCHE : // Action état MARCHE
if(temperature > seuil + hyst) { // Condition de garde : [temperature > seuil + hyst]
etatCourant = ARRET;
desactiverRelais(); // Effet : Action faite au moment de la transition
}
if(etatBouton) { // Bouton appuyé
etatCourant = MARCHE_FORCEE;
}
break;
case MARCHE_FORCEE : // Action état MARCHE_FORCEE
// Transition : After 30 min
if((tempsTotalEcoule - tempsAriveeDansEtatCourant) > _30_MINUTES) {
if(temperature >= seuil) {
etatCourant = ARRET;
desactiverRelais(); // Effet : Action faite au moment de la transition
}
else
etatCourant = MARCHE;
}
break;
}
}
Article connexe : Les structures algorithmiques de base