Encodage machine à etat

Bonjour
l'année dernière avec l'aide de JML, j'ai pu encoder une machine à état avec un seul moteur électrique
Maintenant je suis une machine avec 3 moteurs
Le principe : un moteur central avec deux moteurs pour verrouiller un toit de serre. Chaque moteur possède deux capteurs de fin de course (ouverture & fermeture)
Je souhaite faire fonctionner les deux moteurs de verrouillage/déverrouillage en même temps pour ne pas déséquilibrer le moteur central, tout en ayant des capteurs indépendant et une durée de fonctionnement maxi différente
C'est cette durée que je n'arrive pas à paramétrer correctement car si je simule un défaut sur un des capteurs, le moteur ne s'arrête pas après un certain temps de fonctionnement
Votre aide me serait bien utile
Merci par avance
Voici l'ensemble du code

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Broche de données du bus oneWire connécté sur la broche 2
OneWire oneWire_DS18B20(ONE_WIRE_BUS);// Créer une instance d'objet oneWire pour communiquer avec tous les périphériques OneWire
DallasTemperature sensors(&oneWire_DS18B20);    //Transmettre notre référence oneWire au capteur de température Dallas
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); //set the lcd adress to 0x27 for 16 chars and 2 line display


unsigned long tempsDebutAction01;
unsigned long tempsDebutAction02;
unsigned long tempsDernierAffichageEtat01;
unsigned long tempsDernierAffichageEtat02;
unsigned long tempsDerniereMesureTemperature;

float derniereTemperatureConnue;

const byte pinFinCourseDeverrouSud = 22; // bouton pin 22 -Bornier "Lib S"
const byte pinFinCourseVerrouSud = 24; // bouton pin 24 -Bornier "Ver S"
const byte pinFinCourseHaut = 26; // bouton pin 26 -Bornier "Haut"
const byte pinFinCourseBas = 28; // bouton pin 28 -Bornier "Bas"
const byte pinFinCourseDeverrouNord = 30; // bouton pin 30 -Bornier "Lib N"
const byte pinFinCourseVerrouNord = 32; // bouton pin 32 -Bornier "Ver N"
const byte pinLedDeverrouSud = 23; //Led Rouge Fil Gris
const byte pinLedVerrouSud = 25;  //Led Verte Fil Violet
const byte pinLedHaut = 27; //Led Rouge Fil Bleu
const byte pinLedBas = 29;  //Led Verte Fil Vert
const byte pinLedDeverrouNord = 31; //Led Rouge Fil Jaune
const byte pinLedVerrouNord = 33;  //Led Verte Fil Orange
const byte pinMotDeverrouNord = 52; // moteur deverrou Nord -Bornier "Nord O"
const byte pinMotVerrouNord = 50; // moteur verrou Nord -Bornier "Nord F"
const byte pinMotOuvre = 48; // moteur ouverture -Bornier "Centre O"
const byte pinMotFerme = 46; // moteur fermeture -Bornier "Centre F"
const byte pinMotDeverrouSud = 44; // moteur deverrou Nord -Bornier "Sud O"
const byte pinMotVerrouSud = 42; // moteur verrou Nord -Bornier "Sud F"



int EtatCapteurVerrouNord = LOW; // etat du capteur verrou nord
int EtatCapteurDeverrouNord = LOW; // etat du capteur déverrou nord
int EtatCapteurVerrouSud = LOW; // etat du capteur verrou sud
int EtatCapteurDeverrouSud = LOW; // etat du capteur déverrou sud
int EtatCapteurBas = LOW; // etat du capteur bas
int EtatCapteurHaut = LOW; // etat du capteur haut

enum : byte {Fermer, EnDeverrou, Deverrou, EnOuverture, Ouvert, EnFermeture, EnVerrou, Verrou} etatToit;

// Afficher la température mesurée par DS18B20, stockée dans la variable globale derniereTemperatureConnue
// si elle a changée. appeler avec true en paramètre si on veut forcer l'affichage quand même
void afficherTemperature(bool forceAffichage = false)
{
  static float ancienneTemperature = -100;
  if (forceAffichage || derniereTemperatureConnue != ancienneTemperature) {
    Serial.print("temperature DS18b20: ");
    Serial.print(derniereTemperatureConnue);
    Serial.println(" °C\n");

    lcd.setCursor(0, 0);
    lcd.print(derniereTemperatureConnue);
    lcd.write((char)223);// initialiser le caractère ° dans le LCD
    lcd.setCursor(6, 0);
    lcd.print("C");

    ancienneTemperature = derniereTemperatureConnue;
  }
}

void fermerToit()
{
  digitalWrite(pinMotFerme, HIGH);
  digitalWrite(pinMotOuvre, HIGH);
  digitalWrite(pinMotVerrouNord, HIGH);
  digitalWrite(pinMotDeverrouNord, HIGH);
  digitalWrite(pinMotVerrouSud, HIGH);
  digitalWrite(pinMotDeverrouSud, HIGH);
  etatToit = Fermer;
}

void lireTemperature()
{
  sensors.requestTemperatures();
  derniereTemperatureConnue = sensors.getTempCByIndex(0);
  tempsDerniereMesureTemperature = millis();
}

void setup() {
  pinMode(pinMotOuvre, OUTPUT);
  pinMode(pinMotFerme, OUTPUT);
  pinMode(pinFinCourseBas, INPUT);
  pinMode(pinFinCourseHaut, INPUT);
  pinMode(pinLedBas, OUTPUT);
  pinMode(pinLedHaut, OUTPUT);
  pinMode(pinMotVerrouNord, OUTPUT);
  pinMode(pinMotDeverrouNord, OUTPUT);
  pinMode(pinFinCourseVerrouNord, INPUT);
  pinMode(pinFinCourseDeverrouNord, INPUT);
  pinMode(pinLedVerrouNord, OUTPUT);
  pinMode(pinLedDeverrouNord, OUTPUT);
  pinMode(pinMotVerrouSud, OUTPUT);
  pinMode(pinMotDeverrouSud, OUTPUT);
  pinMode(pinFinCourseVerrouSud, INPUT);
  pinMode(pinFinCourseDeverrouSud, INPUT);
  pinMode(pinLedVerrouSud, OUTPUT);
  pinMode(pinLedDeverrouSud, OUTPUT);

  Serial.begin(115200);
  lcd.init();// print a message to the lcd
  lcd.backlight();

  sensors.begin();            //Initialiser le capteur DS18B20
  lireTemperature();          // obtention de la première température
  fermerToit();               // mise en conditions initiales
  afficherTemperature(true);  // affichage initial
}

//boucle principale
void loop() {

  if (millis() - tempsDerniereMesureTemperature >= 1500ul) lireTemperature();     // ne mettre à jour la T° que toutes les 15 secondes
  if (millis() - tempsDernierAffichageEtat01 >= 3000ul)  {
    afficherTemperature(true);  // afficher la température sur le LCD (et port série)
  } else afficherTemperature();
  EtatCapteurBas = digitalRead(pinFinCourseBas);
  EtatCapteurHaut = digitalRead(pinFinCourseHaut);
  EtatCapteurVerrouNord = digitalRead(pinFinCourseVerrouNord);
  EtatCapteurDeverrouNord = digitalRead(pinFinCourseDeverrouNord);
  EtatCapteurVerrouSud = digitalRead(pinFinCourseVerrouSud);
  EtatCapteurDeverrouSud = digitalRead(pinFinCourseDeverrouSud);
  if (EtatCapteurBas == HIGH)
    digitalWrite(pinLedBas, HIGH);
  else
    digitalWrite(pinLedBas, LOW);
  if ( EtatCapteurHaut == HIGH)
    digitalWrite(pinLedHaut, HIGH);
  else
    digitalWrite(pinLedHaut, LOW);
  if (EtatCapteurVerrouNord == HIGH)
    digitalWrite(pinLedVerrouNord, HIGH);
  else
    digitalWrite(pinLedVerrouNord, LOW);
  if ( EtatCapteurDeverrouNord == HIGH)
    digitalWrite(pinLedDeverrouNord, HIGH);
  else
    digitalWrite(pinLedDeverrouNord, LOW);
  if (EtatCapteurVerrouSud == HIGH)
    digitalWrite(pinLedVerrouSud, HIGH);
  else
    digitalWrite(pinLedVerrouSud, LOW);
  if ( EtatCapteurDeverrouSud == HIGH)
    digitalWrite(pinLedDeverrouSud, HIGH);
  else
    digitalWrite(pinLedDeverrouSud, LOW);

  switch (etatToit) {
    case Fermer:
      if ((derniereTemperatureConnue > 28)  &&  (EtatCapteurVerrouNord == HIGH &&  EtatCapteurDeverrouNord == LOW)) {
        digitalWrite(pinMotDeverrouNord, LOW); // le moteur du déverrouillage Nord est actionné
        tempsDernierAffichageEtat01 = millis() ;
        tempsDebutAction01 = tempsDernierAffichageEtat01;
      if (  (derniereTemperatureConnue > 28)  &&  (EtatCapteurVerrouSud == HIGH &&  EtatCapteurDeverrouSud == LOW)){
        digitalWrite(pinMotDeverrouSud, LOW); // le moteur du déverrouillage Sud est actionné
        tempsDernierAffichageEtat02 = millis() ;
        tempsDebutAction02 = tempsDernierAffichageEtat02;}
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("En Deverrouillage N");
        lcd.setCursor(0, 2);
        lcd.print("En Deverrouillage S");
        etatToit = EnDeverrou; //c'est le nouvel état du toit qui devient En Déverrouillage
      }
      
      break;
    case EnDeverrou:
      if (( EtatCapteurDeverrouNord == HIGH &&  EtatCapteurVerrouNord == LOW) || (( millis() - tempsDebutAction01) >= 20000ul)) {
        tempsDernierAffichageEtat01 = millis() ;
        digitalWrite(pinMotDeverrouNord, HIGH); // le moteur du déverrouillage Nord est arreté
      if (( EtatCapteurDeverrouSud == HIGH &&  EtatCapteurVerrouSud == LOW) || (( millis() - tempsDebutAction02) >= 20000ul)) {
        tempsDernierAffichageEtat02 = millis() ;
        digitalWrite(pinMotDeverrouSud, HIGH); }// le moteur du déverrouillage Sud est arreté 
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Deverrou Nord OK");
        lcd.setCursor(0, 2);
        lcd.print("Deverrou Sud OK");
        etatToit = Deverrou;//c'est le nouvel état du toit qui est Déverrouillé 
      }
      break;

    case Deverrou:
      if ( (EtatCapteurBas == HIGH &&  EtatCapteurHaut == LOW &&  EtatCapteurDeverrouSud == HIGH)) {
        digitalWrite(pinMotOuvre, LOW); // le moteur central est actionné en ouverture
        tempsDernierAffichageEtat01 = millis() ;
        tempsDebutAction01 = tempsDernierAffichageEtat01;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Ouverture");
        etatToit = EnOuverture; //c'est le nouvel état du toit qui devient EnOuverture
      }
      break;

    case EnOuverture:
      if (( EtatCapteurHaut == HIGH &&  EtatCapteurBas == LOW) || (( millis() - tempsDebutAction01) >= 20000ul)) {
        tempsDernierAffichageEtat01 = millis() ;

        digitalWrite(pinMotOuvre, HIGH); // le moteur est arreté en ouverture
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Ouvert");
        etatToit = Ouvert;
      }
      break;

    case Ouvert:
      if ((derniereTemperatureConnue < 25) &&  (EtatCapteurBas == LOW &&  EtatCapteurHaut == HIGH)) {
        digitalWrite(pinMotFerme, LOW); // le moteur central est actionné en fermeture
        tempsDernierAffichageEtat01 = millis() ;
        tempsDebutAction01 = tempsDernierAffichageEtat01;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Fermeture");
        etatToit = EnFermeture;
      }
      break;

    case EnFermeture:
      if (( EtatCapteurBas == HIGH &&  EtatCapteurHaut == LOW) || ((millis() - tempsDebutAction01) >= 20000ul)) {
        digitalWrite(pinMotFerme, HIGH); // le moteur central est arreté en fermeture
        tempsDernierAffichageEtat01 = millis() ;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Clos");
        etatToit = EnVerrou;
      }
      break;

    case EnVerrou:
      if (  (EtatCapteurDeverrouNord == HIGH &&  EtatCapteurVerrouNord == LOW &&  EtatCapteurBas == HIGH)) {
        digitalWrite(pinMotVerrouNord, LOW); // le moteur du verrouillage Nord est actionné
        tempsDernierAffichageEtat01 = millis() ;
        tempsDebutAction01 = tempsDernierAffichageEtat01;
      if ( (EtatCapteurDeverrouSud == HIGH &&  EtatCapteurVerrouSud == LOW)) {
        digitalWrite(pinMotVerrouSud, LOW); // le moteur du verrouillage Sud est actionné
        tempsDernierAffichageEtat02 = millis() ;
        tempsDebutAction02 = tempsDernierAffichageEtat02;}  
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("En Verrouillage Nord");
        lcd.setCursor(0, 2);
        lcd.print("En Verrouillage Sud");
        etatToit = Verrou; //c'est le nouvel état du toit qui devient en Verrouillage
      }
      break;
    case Verrou:
      if (( EtatCapteurVerrouNord == HIGH &&  EtatCapteurDeverrouNord == LOW) || (( millis() - tempsDebutAction01) >= 20000ul)) {
        tempsDernierAffichageEtat01 = millis() ;
        digitalWrite(pinMotVerrouNord, HIGH); // le moteur du Verrouillage Nord est arreté
      if (( EtatCapteurVerrouSud == HIGH &&  EtatCapteurDeverrouSud == LOW) || (( millis() - tempsDebutAction02) >= 20000ul)) {
        tempsDernierAffichageEtat02 = millis() ;
        digitalWrite(pinMotVerrouSud, HIGH);} // le moteur du Verrouillage Sud est arreté  
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Verrouillage Nord OK");
        lcd.setCursor(0, 2);
        lcd.print("Verrouillage Sud OK");
        etatToit = Fermer;
      }
      break;

  }
}

Peut-être une lacune dans la machine à états.
Par exemple, quelque chose me semble bizarre

J'ai survolé le code rapidement, et je peux me tromper, mais je trouve étonnant, dans le morceau de code ci-dessus, de ne conditionner le changement d'état de la machine que sur une seule condition
Si le verrouillage sud déclenche avant le nord, le moteur nord n'est jamais arrêté.

Si la machine à état devient complexe, il est des fois plus facile de gérer plusieurs machine.
Par exemple une machine à état pour gérer le haut niveau et une qui va gérer les moteurs.

Bonsoir
Merci de ta réponse rapide
En l'occurrence, chaque moteur a deux capteurs (début et fin de course), et c'est en fonction de ces capteurs que l'on fait arrêter ou mettre en marche ces moteurs avec une sécurité sur la durée de fonctionnement au cas où un des capteurs soit défaillant, et ainsi bloquer la suite logique du fonctionnement des autres moteurs
Est-ce que peut t'aider dans la compréhension du codage ?
il se peut que la fonction "if " ne soit pas la mieux adaptée à mon besoin. J'avais pensé à la fonction " While " mais je ne suis pas assez compétent pour en effectuer le paramétrage
J'ai déjà fait un codage où tous les moteurs sont détaillés dans des étapes en cascade mais cela représente un danger physique sur le terrain quand par exemple un moteur de déverrouillage ne fonctionne pas alors que l'autre a déjà effectuer son cycle complet ( risque de chute )

Citation
Bonsoir
Je ne connais pas cette possibilité, comment dois-je coder pour faire un essai ?
Merci

Pour des machines d'état un peu compliquées, il existe une bibliothèque qui simplifiera la programmation :

Par contre, il faut apprendre à s'en servir...

Merci Lesept pour ta réponse
j'ai jeté un oeil mais comme je ne suis pas un bilingue, j'ai du mal à comprendre
Comment devrais-je coder pour faire démarrer le fonctionnement de deux moteurs en même temps tout en gardant une indépendance dans les capteurs de fin de course ou de durée de fonctionnement de chaque moteur ?
Merci par avance de ton aide

Il faut d'abord bien décrire ce qu'on attend de la machine d'états. Si je comprends bien tu veux en faire deux semblables, chacune commandant un moteur.

  1. Chaque moteur peut tourner dans un sens ou dans l'autre.
  2. Lorsque le moteur tourne, il doit s'arrêter si le capteur fin de course se déclenche ou si une durée maximale de fonctionnement est atteinte
  3. Lorsque le moteur s'arrête, il change de sens. Le capteur qui le contrôle est alors celui de 'début de course'.
    Est-ce correct ?

Je pense que tu dois commencer par faire un FSM pour le premier moteur. Tu peux t'inspirer de cet exemple :

Il décrit un changement d'état qui se passe soit au bout d'un certain temps, soit par l'appui sur un bouton (capteur dans ton cas).
Etudie-le, comprends-le et adapte-le à ton cas.

Tu dois d'abord définir les états du moteur :

  1. Avance
  2. Arrêt
  3. Recule

Puis tu définis les transitions :

  • 1 vers 2 : FDC ou durée
  • 2 vers 3 : immédiat (?), après changement de sens du moteur
  • 3 vers 2 : DDC ou durée
    etc.

Merci,
Je vais décrypter et essayer de l'adapter

Pour préciser le fonctionnement, c'est à partir d'une T° que les deux moteurs de déverrouillage sont actionnés, puis un autre moteur est actionné pour ouvrir le toit puis "Stop"... puis après une diminution de T°, le moteur du toit change de sens (fermeture), puis les deux moteurs de verrouillage
Tous les moteurs ont des capteurs fin de course (ouverture, fermeture) avec un contrôle de durée de fonctionnement
Je prévoie " bretelle et filet " mais en qualité d'électricien, j'ai trop vu de moteur qui grillait car "pas protégé" en cas de dysfonctionnement des fins de course
Merci de ta proposition

OK, alors je verrai bien les états suivants pour la fenêtre :

  1. Fermée
  2. Ouverture
  3. Ouverte
  4. Fermeture

Les transitions sont à définir :

  • 1 vers 2 : actionner les moteurs de déverrouillage une certaine durée, puis moteur de fenêtre "avance"
  • 2 vers 3 : arrêter le moteur si FDC ou durée max atteinte
  • 3 vers 4 : moteur de fenêtre "recule"
  • 4 vers 1 : arrêter le moteur si DDC ou durée max atteinte, actionner les moteurs de verrouillage

Reste à transcrire ça au format de la bibliothèque... :wink:

Bonsoir
Ok merci, à moi de tout mettre en œuvre

Bonjour
J'ai bien essayé différentes modifications du code mais je n'arrive pas à obtenir ce que je souhaite pour le fonctionnement des moteurs (des led actuellement)
J'ai besoin de votre aide pour avoir des explications sur les différentes lignes et ainsi comprendre le fonctionnement de cette bibliothèque
Voici le code que j'ai modifié pour piloter deux leds (j'ai ajouté la lettre "A" pour avoir deux fonctionnements identique)
Merci par avance

#include "Fsm.h"

/*
 * FSM Library sample with user and timed //Exemple de bibliothèque FSM avec utilisateur et temporisé
 * transitions.
 * Uses a button and Arduino builtin led, //Utilise un bouton et une LED intégrée Arduino,
 * button can be replaced just grounding //bouton peut être remplacé par la mise à la masse de la broche
 * pin.
 */

// Used pins // Broches utilisées
#define LED_PIN     13
#define LED_PINA     12
#define BUTTON_PIN  8
#define BUTTON_PINA  7

//Events // Épreuves
#define BUTTON_EVENT  0
#define BUTTON_EVENTA  0

int buttonState = 0;
int buttonStateA = 0;

/* state 1:  led off //* état 1 : led off
 * state 2:  led on // * état 2 : led on
 * transition from s1 to s2 on button press //transition de s1 à s2 en appuyant sur le bouton
 * transition back from s2 to s1 after 3 seconds or button press //retour de s2 à s1 après 3 secondes ou une pression sur un bouton
 */
State state_led_off(&led_off, &check_button, NULL); //Etat de la led OFF 
State state_led_onA(&led_onA, &check_buttonA, NULL);
State state_led_offA(&led_offA, &check_buttonA, NULL); //Etat de la led OFFA 
State state_led_on(&led_on, &check_buttonA, NULL);
Fsm fsm(&state_led_off);

// Transition functions
void led_off()
{
  Serial.println("led_off");
  digitalWrite(LED_PIN, LOW);
}
void led_offA()
{
  Serial.println("led_offA");
  digitalWrite(LED_PINA, LOW);
}

void led_on()
{
  Serial.println("led_on");
  digitalWrite(LED_PIN, HIGH);
}
void led_onA()
{
  Serial.println("led_onA");
  digitalWrite(LED_PINA, HIGH);
}

void check_button()
{
  int buttonState = digitalRead(BUTTON_PIN);
  if (buttonState == LOW) {
    Serial.println("button_pressed");
    fsm.trigger(BUTTON_EVENT);
  }
}
void check_buttonA()
{
  int buttonStateA = digitalRead(BUTTON_PINA);
  if (buttonStateA == LOW) {
    Serial.println("button_press");
    fsm.trigger(BUTTON_EVENTA);
  }
}

// standard arduino functions
void setup()
{
  Serial.begin(9600);
  
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PINA, OUTPUT);
  pinMode(BUTTON_PINA, INPUT_PULLUP);

  fsm.add_transition(&state_led_off, &state_led_on, BUTTON_EVENT, NULL);
  fsm.add_timed_transition(&state_led_on, &state_led_off, 3000, NULL);
  fsm.add_transition(&state_led_on, &state_led_off, BUTTON_EVENT, NULL);
  fsm.add_transition(&state_led_offA, &state_led_onA, BUTTON_EVENTA, NULL);
  fsm.add_timed_transition(&state_led_onA, &state_led_offA, 3000, NULL);
  fsm.add_transition(&state_led_onA, &state_led_offA, BUTTON_EVENTA, NULL);
  Serial.println("Setup ENDA");
  Serial.println("Setup END");
}

void loop()
{
  // Call fsm run // Exécuter l’appel fsm
  fsm.run_machine();
  delay(200);
}

Je pense que tu dois créer deux machines à états : fsm et fsmA

il y aussi la bibliothèque easyRun de @bricoleau (qu'on ne voit plus trop) ➜ GitHub - bricoleau/easyRun: Doing sereval things at the same time becomes so easy

Bonjour
Merci pour vos réponses, mais je ne suis pas assez expert pour savoir si je vais dans la bonne direction
Ci joint mon programme qui fonctionne bien, à un point près, c'est que les deux moteurs de verrouillage/déverrouillage fonctionnent en cascade l'un après l'autre, alors que je souhaiterai les faire actionner en parallèle tout en gardant leurs FDC, DDC et durée maxi de fonctionnement respectifs
Merci de votre avis et de vos propositions

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Broche de données du bus oneWire connécté sur la broche 2
OneWire oneWire_DS18B20(ONE_WIRE_BUS);// Créer une instance d'objet oneWire pour communiquer avec tous les périphériques OneWire
DallasTemperature sensors(&oneWire_DS18B20);    //Transmettre notre référence oneWire au capteur de température Dallas
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); //set the lcd adress to 0x27 for 16 chars and 2 line display


unsigned long tempsDebutAction;
unsigned long tempsDernierAffichageEtat;
unsigned long tempsDerniereMesureTemperature;

float derniereTemperatureConnue;

const byte pinFinCourseDeverrouSud = 22; // bouton pin 22 -Bornier "Lib S"
const byte pinFinCourseVerrouSud = 24; // bouton pin 24 -Bornier "Ver S"
const byte pinFinCourseHaut = 26; // bouton pin 26 -Bornier "Haut"
const byte pinFinCourseBas = 28; // bouton pin 28 -Bornier "Bas"
const byte pinFinCourseDeverrouNord = 30; // bouton pin 30 -Bornier "Lib N"
const byte pinFinCourseVerrouNord = 32; // bouton pin 32 -Bornier "Ver N"
const byte pinLedDeverrouSud = 23; //Led Rouge Fil Gris
const byte pinLedVerrouSud = 25;  //Led Verte Fil Violet
const byte pinLedHaut = 27; //Led Rouge Fil Bleu
const byte pinLedBas = 29;  //Led Verte Fil Vert
const byte pinLedDeverrouNord = 31; //Led Rouge Fil Jaune
const byte pinLedVerrouNord = 33;  //Led Verte Fil Orange
const byte pinMotDeverrouNord = 52; // moteur deverrou Nord -Bornier "Nord O"
const byte pinMotVerrouNord = 50; // moteur verrou Nord -Bornier "Nord F"
const byte pinMotOuvre = 48; // moteur ouverture -Bornier "Centre O"
const byte pinMotFerme = 46; // moteur fermeture -Bornier "Centre F"
const byte pinMotDeverrouSud = 44; // moteur deverrou Nord -Bornier "Sud O"
const byte pinMotVerrouSud = 42; // moteur verrou Nord -Bornier "Sud F"



int EtatCapteurVerrouNord = LOW; // etat du capteur verrou nord
int EtatCapteurDeverrouNord = LOW; // etat du capteur déverrou nord
int EtatCapteurVerrouSud = LOW; // etat du capteur verrou sud
int EtatCapteurDeverrouSud = LOW; // etat du capteur déverrou sud
int EtatCapteurBas = LOW; // etat du capteur bas
int EtatCapteurHaut = LOW; // etat du capteur haut

enum : byte {Fermer, EnDeverrouNord, DeverrouNord, EnDeverrouSud, DeverrouSud, EnOuverture, Ouvert, EnFermeture, EnVerrouNord, VerrouNord, EnVerrouSud, VerrouSud} etatToit;

// Afficher la température mesurée par DS18B20, stockée dans la variable globale derniereTemperatureConnue
// si elle a changée. appeler avec true en paramètre si on veut forcer l'affichage quand même
void afficherTemperature(bool forceAffichage = false)
{
  static float ancienneTemperature = -100;
  if (forceAffichage || derniereTemperatureConnue != ancienneTemperature) {
    Serial.print("temperature DS18b20: ");
    Serial.print(derniereTemperatureConnue);
    Serial.println(" °C\n");

    lcd.setCursor(0, 0);
    lcd.print(derniereTemperatureConnue);
    lcd.write((char)223);// initialiser le caractère ° dans le LCD
    lcd.setCursor(6, 0);
    lcd.print("C");

    ancienneTemperature = derniereTemperatureConnue;
  }
}

void fermerToit()
{
  digitalWrite(pinMotFerme, HIGH);
  digitalWrite(pinMotOuvre, HIGH);
  digitalWrite(pinMotVerrouNord, HIGH);
  digitalWrite(pinMotDeverrouNord, HIGH);
  digitalWrite(pinMotVerrouSud, HIGH);
  digitalWrite(pinMotDeverrouSud, HIGH);
  etatToit = Fermer;
}

void lireTemperature()
{
  sensors.requestTemperatures();
  derniereTemperatureConnue = sensors.getTempCByIndex(0);
  tempsDerniereMesureTemperature = millis();
}

void setup() {
  pinMode(pinMotOuvre, OUTPUT);
  pinMode(pinMotFerme, OUTPUT);
  pinMode(pinFinCourseBas, INPUT);
  pinMode(pinFinCourseHaut, INPUT);
  pinMode(pinLedBas, OUTPUT);
  pinMode(pinLedHaut, OUTPUT);
  pinMode(pinMotVerrouNord, OUTPUT);
  pinMode(pinMotDeverrouNord, OUTPUT);
  pinMode(pinFinCourseVerrouNord, INPUT);
  pinMode(pinFinCourseDeverrouNord, INPUT);
  pinMode(pinLedVerrouNord, OUTPUT);
  pinMode(pinLedDeverrouNord, OUTPUT);
  pinMode(pinMotVerrouSud, OUTPUT);
  pinMode(pinMotDeverrouSud, OUTPUT);
  pinMode(pinFinCourseVerrouSud, INPUT);
  pinMode(pinFinCourseDeverrouSud, INPUT);
  pinMode(pinLedVerrouSud, OUTPUT);
  pinMode(pinLedDeverrouSud, OUTPUT);

  Serial.begin(115200);
  lcd.init();// print a message to the lcd
  lcd.backlight();

  sensors.begin();            //Initialiser le capteur DS18B20
  lireTemperature();          // obtention de la première température
  fermerToit();               // mise en conditions initiales
  afficherTemperature(true);  // affichage initial
}

//boucle principale
void loop() {

  if (millis() - tempsDerniereMesureTemperature >= 1500ul) lireTemperature();     // ne mettre à jour la T° que toutes les 15 secondes
  if (millis() - tempsDernierAffichageEtat >= 3000ul)  {
    afficherTemperature(true);  // afficher la température sur le LCD (et port série)
  } else afficherTemperature();
  EtatCapteurBas = digitalRead(pinFinCourseBas);
  EtatCapteurHaut = digitalRead(pinFinCourseHaut);
  EtatCapteurVerrouNord = digitalRead(pinFinCourseVerrouNord);
  EtatCapteurDeverrouNord = digitalRead(pinFinCourseDeverrouNord);
  EtatCapteurVerrouSud = digitalRead(pinFinCourseVerrouSud);
  EtatCapteurDeverrouSud = digitalRead(pinFinCourseDeverrouSud);
  if (EtatCapteurBas == HIGH)
    digitalWrite(pinLedBas, HIGH);
  else
    digitalWrite(pinLedBas, LOW);
  if ( EtatCapteurHaut == HIGH)
    digitalWrite(pinLedHaut, HIGH);
  else
    digitalWrite(pinLedHaut, LOW);
  if (EtatCapteurVerrouNord == HIGH)
    digitalWrite(pinLedVerrouNord, HIGH);
  else
    digitalWrite(pinLedVerrouNord, LOW);
  if ( EtatCapteurDeverrouNord == HIGH)
    digitalWrite(pinLedDeverrouNord, HIGH);
  else
    digitalWrite(pinLedDeverrouNord, LOW);
  if (EtatCapteurVerrouSud == HIGH)
    digitalWrite(pinLedVerrouSud, HIGH);
  else
    digitalWrite(pinLedVerrouSud, LOW);
  if ( EtatCapteurDeverrouSud == HIGH)
    digitalWrite(pinLedDeverrouSud, HIGH);
  else
    digitalWrite(pinLedDeverrouSud, LOW);

  switch (etatToit) {
    case Fermer:
      if ((derniereTemperatureConnue > 28)  &&  (EtatCapteurVerrouNord == HIGH &&  EtatCapteurDeverrouNord == LOW)) {
        digitalWrite(pinMotDeverrouNord, LOW); // le moteur du déverrouillage Nord est actionné
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Deverrouillage N");
        etatToit = EnDeverrouNord; //c'est le nouvel état du toit qui devient En Déverrouillage Nord
      }
      break;
    case EnDeverrouNord:
      if (( EtatCapteurDeverrouNord == HIGH &&  EtatCapteurVerrouNord == LOW) || (( millis() - tempsDebutAction) >= 20000ul)) {
        tempsDernierAffichageEtat = millis() ;

        digitalWrite(pinMotDeverrouNord, HIGH); // le moteur du déverrouillage Nord est arreté
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Deverrou Nord OK");
        etatToit = DeverrouNord;
      }
      break;
    case DeverrouNord:
      if (  (EtatCapteurVerrouSud == HIGH &&  EtatCapteurDeverrouSud == LOW &&  EtatCapteurDeverrouNord == HIGH)) {
        digitalWrite(pinMotDeverrouSud, LOW); // le moteur du déverrouillage Sud est actionné
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Deverrouillage S");
        etatToit = EnDeverrouSud; //c'est le nouvel état du toit qui devient En Déverrouillage Sud
      }
      break;
    case EnDeverrouSud:
      if (( EtatCapteurDeverrouSud == HIGH &&  EtatCapteurVerrouSud == LOW) || (( millis() - tempsDebutAction) >= 20000ul)) {
        tempsDernierAffichageEtat = millis() ;

        digitalWrite(pinMotDeverrouSud, HIGH); // le moteur du déverrouillage Sud est arreté
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Deverrou Sud OK");
        etatToit = DeverrouSud;
      }
      break;
    case DeverrouSud:
      if ( (EtatCapteurBas == HIGH &&  EtatCapteurHaut == LOW &&  EtatCapteurDeverrouSud == HIGH)) {
        digitalWrite(pinMotOuvre, LOW); // le moteur central est actionné en ouverture
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Ouverture");
        etatToit = EnOuverture; //c'est le nouvel état du toit qui devient EnOuverture
      }
      break;

    case EnOuverture:
      if (( EtatCapteurHaut == HIGH &&  EtatCapteurBas == LOW) || (( millis() - tempsDebutAction) >= 20000ul)) {
        tempsDernierAffichageEtat = millis() ;

        digitalWrite(pinMotOuvre, HIGH); // le moteur est arreté en ouverture
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Ouvert");
        etatToit = Ouvert;
      }
      break;

    case Ouvert:
      if ((derniereTemperatureConnue < 25) &&  (EtatCapteurBas == LOW &&  EtatCapteurHaut == HIGH)) {
        digitalWrite(pinMotFerme, LOW); // le moteur central est actionné en fermeture
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Fermeture");
        etatToit = EnFermeture;
      }
      break;

    case EnFermeture:
      if (( EtatCapteurBas == HIGH &&  EtatCapteurHaut == LOW) || ((millis() - tempsDebutAction) >= 20000ul)) {
        digitalWrite(pinMotFerme, HIGH); // le moteur central est arreté en fermeture
        tempsDernierAffichageEtat = millis() ;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Clos");
        etatToit = EnVerrouNord;
      }
      break;

    case EnVerrouNord:
      if (  (EtatCapteurDeverrouNord == HIGH &&  EtatCapteurVerrouNord == LOW &&  EtatCapteurBas == HIGH)) {
        digitalWrite(pinMotVerrouNord, LOW); // le moteur du verrouillage Nord est actionné
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Verrouillage Nord");
        etatToit = VerrouNord; //c'est le nouvel état du toit qui devient en Verrouillage Nord
      }
      break;
    case VerrouNord:
      if (( EtatCapteurVerrouNord == HIGH &&  EtatCapteurDeverrouNord == LOW) || (( millis() - tempsDebutAction) >= 20000ul)) {
        tempsDernierAffichageEtat = millis() ;

        digitalWrite(pinMotVerrouNord, HIGH); // le moteur du Verrouillage Nord est arreté
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Verrouillage Nord OK");
        etatToit = EnVerrouSud;
      }
      break;

    case EnVerrouSud:
      if ( (EtatCapteurDeverrouSud == HIGH &&  EtatCapteurVerrouSud == LOW &&  EtatCapteurBas == HIGH)) {
        digitalWrite(pinMotVerrouSud, LOW); // le moteur du verrouillage Sud est actionné
        tempsDernierAffichageEtat = millis() ;
        tempsDebutAction = tempsDernierAffichageEtat;
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("En Verrouillage Sud");
        etatToit = VerrouSud; //c'est le nouvel état du toit qui devient En Verrouillage Sud
      }
      break;
    case VerrouSud:
      if (( EtatCapteurVerrouSud == HIGH &&  EtatCapteurDeverrouSud == LOW) || (( millis() - tempsDebutAction) >= 20000ul)) {
        tempsDernierAffichageEtat = millis() ;

        digitalWrite(pinMotVerrouSud, HIGH); // le moteur du Verrouillage Sud est arreté
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("Verrouillage Sud OK");
        etatToit = Fermer;
      }
      break;

  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.