Modifications

Aller à : navigation, rechercher

AeroTempo

10 602 octets ajoutés, 26 décembre 2021 à 18:19
aucun résumé de modification
A l'issue de cette seconde temporisation, si la lumière ne se rallume pas, l'aérateur s'éteint.
Techniquement, l'AéroTempo est basé sur un automate d'états finis à 4 états et 4 transistionstransitions.Les 4 états :- Off- T1- On- T2
Les 4 états : Off, T1, On, T2 Les 4 transitions :- LightOn- , LightOff- , FinT1- , FinT2
Le schéma de l'automate est le suivant :
<gallery>
[[Fichier:Automate.jpg|vignette]]Le schéma de l'automate d'états finis de l'AéroTempo.
</gallery>
 
Le code source commenté à héberger sur une carte Arduino Uno ou Duomilanove :
<code>
/******************************************************
AeroTempo : Temporisateur pour aérateur de toilettes
Principe : 1) A la détection de l'apparition de la lumière dans les toilettes :
2) - mise en route d'une première temporisation t1,
3) - mise en route du ventilagteur/extracteur via un relai 220v
4) A la disparition de la lumière :
5) - mise en route d'une seconde temporisation t2,
6) - extinction du ventilateur.
Version V0 : Montage initial pour test(POC), t1 = 1 min., t2 = 2 min. fixées en dur dans le code
Utilisation d'un écran LCD inspiré de l'exemple Hello Word de la librairie LyquidCryqtal de l'ID Arduino
The circuit:
* LCD VSS pin (1) to ground
* LCD Vdd pin (2) to 5V
* 10K resistor (j'ai mis un potentiomètre pour régler le contraste :
* ends to +5V and ground
* wiper to LCD VO pin (3)
* LCD RS pin (4) to digital pin 12 Arduino
* LCD R/W pin (5) to ground
* LCD Enable pin (6) to digital pin 11
* LCD DB4 pin (11) to digital pin 5
* LCD DB5 pin (12) to digital pin 4
* LCD DB6 pin (13) to digital pin 3
* LCD DB7 pin (14) to digital pin 2
Version V0a : Reprise du code de l'exemple Hello Word de la librairie LyquidCryqtal de l'IDE Arduino
Version V0b : Intégraion de la LDR (selon mon cours au MDC) et intégration du relai
Le Circuit :
* LDR en série avec R1k entre +5v et Gnd
* Point milieu avec A0
* Relay +5v et Gnd et In1 avec broche 7
Version V0c : Mise en place des deux temporisations (en dur dans le code)
* t1 => délai d'attente après l'établissement de la lumière avant déclenchement de l'aérateur
* (pour éviter le déclenchement sur une simple ouverture de porte de courte durée)
* t2 => temps de fonctionnement de l'aérateur après l'extinction de la lumière
* Recours à un automate d'états finis cf.
* https://forum.arduino.cc/t/programmation-automate-fini-machine-a-etat/452532/5
Version V0d :
- Mise en place d'un reset matériel
* Le circuit :
* R2k entre la broche 8 et le Reset
* /!\ Attention à ne pas utiliser la broche 13 qui est en PullUp et repasse à 0 à chaque Reset,
* donc le premier Soft Reset déclenche une infinité de Reset => la carte reste bloquée et ne redémarre pas !
- Passage de l'affichage en pourcentage de luminosité :
0% Nuit noire (1023 lu sur la LDR)
100% Pleine lumière (0 lu sur la LDR)
- Mise en place d'un mode Run et d'un mode Test :
qui permet une modification des valeurs des tempos
Changement de mode par un PushButton à bascule sur la broche 9
Version V0e :
- Le mode initial et après chaque reset est Run
- Renommage du mode Test en mode Test (t)
- Affichage de la tempo à rebours (décompte) pendant les états etT1 et etT2
*******************************************************************************/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
const int LdrAnalogIn = A0;
const int RelayPin = 7; // Broche IN1 du relay qui pilote l'aérateur
const int ModePin = 9; // Broche du PushButton de changement de Mode
const String FirmWareVersion = "v0e"; // Version du FirmWare pour l'affichage
 
int LdrValue = 0; // Valeur lue sur la LDR (Valeur faible = forte luminosité)
int Col = 0; // Numéro de la colonne pour l'écriture sur l'écran LCD (entre 0 et 15)
unsigned long TimeStamp = 0; // Top Chrono pour suivre l'écoulement des délais t1 et t2
unsigned long timer = 0; // Permet l'affichage du temps qui s'écoule
 
int t1; // Tempo (en secondes) entre détection de la lumière et mise en route de l'aérateur
int t2; // Tempo (en secondes) entre extinction de la lumière et arrêt de l'aérateur
unsigned long T; // Tempo (en secondes) entre deux Reset de la carte
 
// Création de l'afficheur LCD1604
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
 
// Définition des deux modes de fonctionnement
enum :boolean {Test, Run} mode;
 
// Définition des 4 états de l'automate
enum :byte {etOff,etT1,etOn,etT2} etat;
 
// Définition des 4 événements
boolean evLightOn() { // Apparition de la lumière
// Lecture de la luminosité
LdrValue = analogRead(LdrAnalogIn);
lcd.setCursor(0,1); // On place le curseur en début de ligne 1
lcd.print(100-int(LdrValue/10.23)); // On affiche le pourcentage de luminosité à partir de la valeur lue sur la LDR : (0<LDR<1023)
lcd.print("% "); // Pour effacer l'unité au cas où la valeur diminue d'un ordre de grandeur.
if (LdrValue < 500) {
return true;
} else {
return false;
}
}
 
boolean evLightOff() { // Disparition de la lumière
return !evLightOn();
}
 
boolean evT1Out() { // Fin de la tempo T1
if (millis()/1000 - TimeStamp > t1) {
return true;
} else {
return false;
}
}
 
boolean evT2Out() { // Fin de la tempo T2
if (millis()/1000 - TimeStamp > t2) {
return true;
} else {
return false;
}
}
 
// Cette fonction effectue un effaçage du Timer
// quelque soit sa longueur ( entre 1 et 5 caractères)
void effaceTimer() {
lcd.setCursor(11,1);
lcd.print(" ");
}
 
// Cette fonction effectue un Reset matériel
void pushReset() {
int resetPin = 8; //!\\ ne pas utiliser la broche 13 cf. commentaires en intro
pinMode(resetPin, OUTPUT); // active la broche en sortie (OUTPUT) ce qui déclenche le reset
}
 
void setup() {
// Détermination des modes pour les broches
pinMode(LdrAnalogIn,INPUT);
pinMode(RelayPin,OUTPUT);
pinMode(ModePin,INPUT);
 
// Initialisation de la liaison série
Serial.begin(115200);
// Paramétrage du LCD : Nb de colonnes, Nb de lignes
lcd.begin(16, 2);
// Affichage de la version du FirmWare.
lcd.print("AeroTempo");
lcd.setCursor(7,1);
lcd.print(FirmWareVersion);
 
// Initialisation de l'automate
etat = etOff;
TimeStamp = 0;
mode = Run;
Serial.println("AeroTempo");
}
 
void loop() {
// Reglage du Bug d'affichage : Cetrainment un parasite sur la broche 11 (Enable) qui reset l'afficheur
digitalWrite(11,LOW);
// Détection du changement de mode entre Run et Test
if (digitalRead(ModePin) == HIGH) {
Serial.print(mode + " Bip ");
 
if (mode == Test) {
mode = Run;
} else {
mode = Test;
}
Serial.println(mode);
}
 
// Détermination des paramètres de tempo selon le mode (Run ou Test)
switch (mode) {
case Test :
t1 = 5;
t2 = 10;
T = 50;
break;
case Run :
t1 = 60;
t2 = 300;
T = 86400;
break;
}
// Coeur de l'automate d'états finis
switch (etat) {
case etOff :
lcd.setCursor(13,0); // On place le curseur en bout de ligne 0
lcd.print("Off"); // On affiche l'état
digitalWrite(RelayPin,HIGH); // On arrète l'aérateur
if (evLightOn()) { // la lumière est-elle allumée ?
TimeStamp = millis()/1000; // On note le top départ de t1
etat = etT1; // l'automate change d'état
}
timer = (millis()/1000 - TimeStamp);
break;
case etT1 :
lcd.setCursor(13,0); // On place le curseur en bout de ligne 0
lcd.print(" T1"); // On affiche l'état
if (evLightOff()) { // la lumière est-elle éteinte ?
TimeStamp = 0;
etat = etOff; // l'automate change d'état
} else if (evT1Out()){ // le délai de t1 est-il expiré ?
// (i.e. la lumière est-elle établie depuis suffisamment longtemps (t1 secondes)
TimeStamp = 0;
etat = etOn; // l'automate change d'état
}
timer = t1-(millis()/1000 - TimeStamp);
break;
case etOn :
lcd.setCursor(13,0); // On place le curseur en bout de ligne 0
lcd.print(" On"); // On affiche l'état
digitalWrite(RelayPin,LOW); // On met en route l'aérateur
if (evLightOff()) { // la lumière est-elle éteinte ?
TimeStamp = millis()/1000; // On note le top départ de t2
etat = etT2; // l'automate change d'état
}
timer = (millis()/1000 - TimeStamp);
break;
case etT2 :
lcd.setCursor(13,0); // On place le curseur en bout de ligne 0
lcd.print(" T2"); // On affiche l'état
if (evT2Out()) { // le délai T2 est-il expiré ?
// (i.e. la lumière est-elle éteinte depuis suffisamment longtemps (t2 secondes)
TimeStamp = 0;
etat = etOff; // l'automate change d'état
} else if (evLightOn()) {
TimeStamp = 0; // On reset le TimeStamp
etat = etOn;
}
timer = t2 - (millis()/1000 - TimeStamp);
break;
} // fin du switch case sur l'état de l'automate
// Détermination de la colone où débute l'affichage du Timer
//timer = (millis()/1000 - TimeStamp);
if (timer < 10) {
Col = 15;
} else if (timer < 100) {
Col = 14;
} else if (timer < 1000) {
Col = 13;
} else if (timer < 10000) {
Col = 12;
} else if (timer < 100000) {
Col = 11;
}
// Affichage du mode
lcd.setCursor(12,0);
if (mode == Test) {
lcd.print("t");
} else {
lcd.print("r");
}
// Affichage du timer
effaceTimer();
lcd.setCursor(Col,1);
lcd.print(timer);
 
// Reset régulier bout T secondes
if (millis()/1000 > T) {
pushReset();
}
 
Serial.println(digitalRead(ModePin));
}
</code>
12
modifications

Menu de navigation