Je vous suis depuis un bon bout de temps, j'ai un kit mega avec lequel je bricole, et j'ai enfin de quoi passer à l'étape du dessus, à savoir un frigo dont seul le circuit de froid fonctionne encore (plus de lumière ou de thermostat).
L'objectif est de pouvoir réguler 3 paramètres :
Température
Humidité
Homogénéité entre le bas et le haut du frigo
J'ai commencé à faire le contrôle de mesure des deux capteurs DHT22, pour l'instant cela fonctionne, mais j'aurais surement besoin de vos connaissances sur la gestion des états et la portée des variables.
Il est encore un peu tôt pour publier dans le sous forum explicitement dédié aux la présentation détaillée de réalisations terminées et fonctionnelles....chaque chose en son temps....
Je déplace donc le fil de discussion dans la partie principale du forum francophone comme demandé dans les Bonnes Pratiques du Forum Francophone épinglées un tête de forum
Pour ce qui est de la gestion des états il peut être intéressant de concevoir dès le départ le code sous forme de 'machine à états fiinis' comme expliqué dans ce tutoriel
Du coup tu as des questions particulière sur ta réalisation en cours ?
Il n'est pas facile de te conseiller plus que de t'indiquer un tutoriel, si on ne sait pas plus sur tes choix ou les problèmes que tu rencontre.
je gère actuellement le processus d'action lorsque la porte est ouverte,
lorsque je l'ouvre, je coupe un certain nombre de fonction, par contre lorsque je referme la porte, je pense avoir correctement gérer le fait que je détecte la fermeture de la porte et non la porte fermée, mais j'aimerais savoir comment transmettre l'état des effecteurs (ventilateurs et autres) avant arrêt dans la fonction Door_Opened() et les transmettre à la fonction Door_Closed() ?
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <Wire.h>
#include <Adafruit_ADXL343.h>
#define DHTUP 10 // PIN capteur haut
#define DHTBOT 11 // PIN capteur bas
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht_up(DHTUP, DHTTYPE);
DHT dht_bot(DHTBOT, DHTTYPE);
//Déclaration des timer
//unsigned long Ventil_B = millis();
//unsigned long Ventil_Hygro = millis();
// Déclaration des PINs
const int Door_Switch = 2;
const int Internal_Light = 3;
const int Compressor = 4;
const int Main_Ventil = 5;
const int Ventil_HRDown = 6;
const int Ventil_HRup = 7;
const int HRdown_Mod = 8;
const int HRup_Mod = 9;
const int Alarm_Buzzer = 10;
//Decalration des variabels
int Door_Alarm_Time = 120000; // Déclaration valeur de compteur alarme porte
bool HRDOwn=false; // Intilialisation status déshulmidificateur d'air
bool HRup=false; // Initialisation status humidification d'air
int Up_Delta = 2; // définition du seuil haut de déclenchement production de froid
int Down_Delta = 1; // définition du delta bas pour l'arrêt de la production de froid
int consigne = 12; // définition de la température de consigne
int Door_Status;
int Door_Status_Mem;
float Temp_H;
float Temp_B;
float Hygro_H;
float Hygro_B;
void setup() {
//Déclaration des types IO pins
pinMode(Door_Switch, INPUT_PULLUP);
pinMode(Internal_Light, OUTPUT);
pinMode(Compressor, OUTPUT);
pinMode(Main_Ventil, OUTPUT);
pinMode(Ventil_HRDown, OUTPUT);
pinMode(Ventil_HRup, OUTPUT);
pinMode(HRdown_Mod, OUTPUT);
pinMode(HRup_Mod, OUTPUT);
pinMode(DHTUP, INPUT);
pinMode(DHTBOT, INPUT);
pinMode(Alarm_Buzzer, OUTPUT);
Serial.begin(9600);
//démarrage timer anti cycle court
unsigned long SCC_Timer = millis();
//intitialisation capteur de mesure temp & hygro
dht_up.begin();
dht_bot.begin();
Door_Status_Mem = LOW;
//init timer porte ouverte
// init timer hygro
// init timer brassage
}
void loop() {
// Lecture des états des capteurs et siwtchs
Door_Status = digitalRead(Door_Switch);
//lecture des valeurs de températures et hygrométrie
Temp_H = dht_up.readTemperature();
Temp_B = dht_bot.readTemperature();
Hygro_H = dht_up.readHumidity();
Hygro_B = dht_bot.readHumidity();
// si Température basse > consigne + seuil haut ==> démarrer compresseur
//si temp haute - temp basse > delta temp admissible ==>
// démarrer brassage air
// démarrer timer brassage
// si temp aute - temp basse =< 0 ==> arrêt brassage air
// si hygro haute > hygro_basse + x%, démarrage brassage air
//si porte ouverte ==>
if ( Door_Status != Door_Status_Mem) {
Door_Opened();
unsigned long Door_Open_Timer = millis(); // timer porte ouverte
Door_Status_Mem = Door_Status;
if(Door_Open_Timer>Door_Alarm_Time) {
digitalWrite(Alarm_Buzzer, HIGH);
}
}
//Détection de la fermeture de la porte
if (Door_Status != Door_Status_Mem) {
Door_Closed();
}
// si hygro DHT haut > consigne + seuil
// démarrage timer deshygro
// démarrage module peltier
// démarrage ventilo peltier
// démarrage brassage air
// si hygro DHT haut < consigne - seuil
//arrêt module peltier
// arrêt ventilo peltier
// arrêt brassage air
// arrêt et initialisation timer deshygro
// si timer hygro == limite haute
// buzzer + alarme hygro haute
}
void Door_Opened() {
digitalWrite(Internal_Light, HIGH); // - allumage éclairage
if(Ventil_HRDown==HIGH) {// - si brassage air = high ==> arrêt brassage air
digitalWrite(Ventil_HRDown, LOW);
}
if(HRup==true) {// - si brassage air = high ==> arrêt brassage air
digitalWrite(Ventil_HRup, LOW);
digitalWrite(HRup_Mod, LOW);
}
// - si deshumdifiateur ON ==> arrêt ventilo hygrodown + peltier
// - si humdificateur ON ==> arrêt ventilo + module US
// - si porte ouverte plus de 1 min => buzzer + arrêt compresseur (démarrage timer anti cycle court)
}
void Door_Closed (){
digitalWrite(Internal_Light, LOW); // - allumage éclairage
digitalWrite(Main_Ventil, HIGH);
/*
Reste à décider s'il faut conserver les états précédents au moment de l'ouverture pour les réappliquer au moment de la fermeture de la porte
*/
}
J'ai légèrement modifier ton programme pour faire simplement ce que tu cherche.
C'est vite fait et très approximatif, je ne gère pas la répétition et le rebond du bouton.
Il y a des classes qui gère très bien les boutons, tu y gagnerais à les utiliser
Tu devrais indenter ton code correctement, il serait plus facile à lire (même pour toi).
Facile, dans l'IDE il suffit de taper Control-T (ou Pomme-T sur Mac)
@biggil, merci pour le tips en effet c'est plus propre comme ça. @terwal, si je comprends bien, au lieu de lire l'état et de faire moult contrôle les uns séparé des autres, tu penses qu'il vaut mieux faire un if{} multiple pour gérer tout les états en une fonction ?
Je vais regarder pour comprendre comment ça fonctionne.
enum DoorState {opening, opened, closing, closed};
DoorState door = closed;
Dans cet exemple, le enum Door_State, pas de soucis je capte, par contre Door_State door, la partie door correspond a quoi ?
Pour revenir à mon question, en fait j'ai une variable quiva avoir une valeur assigner dans la fonction Door_Opened, et je voudrais pouvoir récupérer ces valeurs dans la fonctions Door_Closed, dans ce cas, comment on fait, on rentre les états en argument de la deuxième fonction ?
Cette ligne crée une variable, qui s'appelle door, de type DoorState et qui est initialisée à closed. door est ainsi le nom de la variable.
Pour accéder à une même variable depuis plusieurs fonctions, le plus simple (j'ai pas dit le plus malin) c'est de déclarer cette variable en variable globale. C-à-d que tu places la ligne qui la déclare en dehors de toute paire de { } (donc, pas dans une fonction).
L'idée c'est de séparer la lecture de tes composants de l'algorithme général.
La lecture d'un matériel fait changer ou pas un état.
Puis en fonction de cet état, tu établi un algorithme.
Je n'ai pas lu en détail le tuto de @J-M-L mais je pense que cela va dans le même sens.
Le mieux serait peut être que tu suivi à la lettre son tutoriel.
De même si tu utilise une classe de gestion de bouton, je pense que cela te simplifiera la vie.
sur un MEGA cette variable ne va pas valoir 120000... utilisez unsigned long (ou uint32_t) pour tout ce qui a trait au temps et à millis
là vous le faites bien
sauf que ce n'est pas utilisé...
vous avez des variables globales et vous ne les mettez pas à jour dans Door_Opened() donc dans Door_Closed() si vous les relisez vous aurez les dernières infos connues (éventuellement celles du moment où la porte a été ouverte si vous ne les mettez pas à jour quand la porte est ouverte)
@J-M-L , merci beaucoup pour ton retour.
Dans l'ordre pour la taille de variable pour mon Door_alarme_Time, en effet, la valeur est trrop grand, je vais corriger.
concernant le SCC_Timer, je ne l'ai pas encore implémenté, il doit me servir à gérer les cycles courts du compresseur.
Enfin pour les variables, si j'ai bien compris, je les déclare en global au début de mon fichier, dans ma fonction Door_Opened(), je fait une lecture d'état pour les sauvegardé dans ces variables avant toutes modification d'états des sorties, et du coup elles devraient être exploitables dans la fonction Door_Closed() c'est bien cela ?
oui. A vous de voir si vous avez besoin d'une copie où si vous suspendez la mise à jour des variables quand la porte est ouverte (auquel cas vous pourriez simplement utiliser les valeurs des variables existantes)
Ma question dans cette boucle, je demande à ce que l'état soit maintenu à HIGH tant que... (boucle While), par contre, est-ce que de cette manière, une fois le While terminé, est ce que l'état va revenir à LOW ou pas ?
vous entrez dans une boucle infinie car le contenu de la boucle while ne met à jour aucune des variables apparaissant dans le test. Donc si vous entrez dans le while, vous y restez jusqu'au prochain reset de l'Arduino...
en plus ça ne sert à rien de répéter les autres digitalWrite.... ce serait plus logique d'activer puis de tester tant que vous n'avez pas atteint la consigne (si vous voulez un code bloquant)
// activer les éléments
digitalWrite(HRdown_Mod, HIGH);
digitalWrite(Ventil_HRDown, HIGH);
// attendre d'avoir atteint la consigne
while(Hygro_H > Hygro_Low + 2 ){
// ➜ ici mettre à jour les variables pertinentes du test utilisé dans le while
}
// désactiver les éléments
digitalWrite(HRdown_Mod, LOW);
digitalWrite(Ventil_HRDown, LOW);
généralement on essaye de ne pas faire de code bloquant. C'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
Donc si je comprends bien, si je fais du "pseudo code", je dois pour ne pas bloquer, travailler ainsi :
si (temp est trop haute) {
démarrage du compresseur et de la ventil
}
si (Compresseur en route && Temp <= consigne basse) {
arrêt compresseur
}
faire un démarrage et je contrôle simplement que la consigne est atteinte, ce qui implique, que je peux effectuer d'autres tâches pendant le même temps.
En gros si tu met une broche de sortie au niveau HIGH, elle le restera tant que tu ne l'a mettra pas au niveau LOW. tu peux donc faire ce que tu veux entre temps, jusqu'à ce que tu estime qu'il faut changer le niveau de sortie de ta broche.