Millis me rend fou

Bonjour à vous tous.
Je me suis lancer pour la première fois dans la programmation pour l'ouverture de mon poulailler avec une photorésistance " qui changera plus tard avec un calcul de valeur sur panneau solaire".

Le principe,
2 BP Ouverture et Fermeture manuel qui sont prioritaire sans sécurité logiciel.
suivit si en automatique, une gestion par photorésistance.

2 switch logiciel sont présent pour les fins de courses et 2 switch mécanique au cas ou.
J'utilise un L298N shield avec inversion séparer

La ou je sèche, c'est pour initialisé millis() sans qu'il se reset dans ma programmation .

Pouvez-vous m'aider et m'expliquer svp. je n'y arrive vraiment pas.

si je lance une fois manuellement, millis se s'initialise et quand le mode automatique démarre, il se met directement en erreur
il faudrait que chrono=millis() se fassent juste avant de démarrer les if dans le mode auto je pense

// Test L293D
// brancher le capteur sur a0 et 5v puis une résistance de 10K de A0 a Ground
const int sensorPin = A0; // Capteur connecter a A0
int sensorVal; // Lecture valeur
int ValMin = 100;
int ValMax = 300;
int TempCourse = 4000;
bool erreurb; bool erreurh; int erreurswb; int erreurswh;
unsigned long etatmode;
unsigned long chrono = 0;

// Motor connections
int en1 = 9; // Pin ENA  du L298N
int en2 = 8; // Pin ENB  du L298N
int in1 = 11; // Pin 2  du L298N
int in2 = 10; // Pin 3 du L298N
int in3 = 7; // Pin 4 du L298N
int in4 = 6; // Pin 5 du L298N
// Bouton poussoir
int boutonOuvre = 3; // Bp Ouverture manuel
int boutonFerme = 2; // BP Fermer manuel
// Fin de course
int switchOuvre = 5; // Switch Haut NO
int switchFerme = 4; // Switch Bas NO


void setup()
{
  Serial.begin(9600);
  Serial.println("Programme Poulailler MotorShield");
  pinMode(en1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(en2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  // Moteur off au démarrage
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  // Bp en interne
  pinMode(boutonOuvre, INPUT_PULLUP);
  pinMode(boutonFerme, INPUT_PULLUP);
  pinMode(switchOuvre, INPUT_PULLUP);
  pinMode(switchFerme, INPUT_PULLUP);
  erreurh = false ; erreurb = false ; // Variable erreur haut et bas
}

void MoteurOuvre()
{
  // Ouverture
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 255);
  analogWrite(en2, 0);
  delay(300);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  Serial.println("Ouverture de la porte");
}

void MoteurFerme()
{
  // Fermeture
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 0);
  analogWrite(en2, 255);
  delay(300);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  Serial.println("Fermeture de la porte");
}

// Fonctions
void MoteurStop()
{
  // Stop
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  delay(300);
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  Serial.println("Stop");
  chrono=millis();
}
void ResetAlarme() {
  if (erreurswb != (digitalRead(switchFerme))) {
    erreurswb = (digitalRead(switchFerme));
    erreurb = false;
    chrono = millis();
  }

  if (erreurswh != (digitalRead(switchOuvre))) {
    erreurswh = (digitalRead(switchOuvre));
    erreurh = false;
    chrono = millis();
  }
}

// Attention on commence ici a faire le show
void loop()
{
  
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  Serial.print(sensorVal); Serial.print(" Lux     "); Serial.print(digitalRead(switchOuvre)); Serial.print(" switchOuvre     "); Serial.print(digitalRead(switchFerme));
  Serial.print(" switchFerme     "); Serial.print(digitalRead(boutonOuvre)); Serial.print(" boutonOuvre     "); Serial.print(digitalRead(boutonFerme)); Serial.print(" boutonFerme     ");
  Serial.print(" erreurH     "); Serial.print(erreurh); Serial.print(" erreurB     "); Serial.println(erreurb);

  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == true)) etatmode = "rien";
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == false)) etatmode = "tout";
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == true)) etatmode = "ouvre";
  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == false)) etatmode = "ferme";
  ResetAlarme();


  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  if ( etatmode == "ouvre" ) {MoteurOuvre();chrono=millis();}

  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  if ( etatmode == "ferme" )  {MoteurFerme();chrono=millis();}

// Si aucun bouton enfoncer et que les conditions sont bonnes
if (etatmode =="rien"){
  
  if (digitalRead(switchFerme) == true && (erreurb) == false ) {
    if (sensorVal < ValMin) {
      if ((millis() - chrono) < TempCourse)MoteurFerme();
      else {
        chrono = millis();
        erreurb = true;
      }
    }
  }

  if (digitalRead(switchOuvre) == true && (erreurh) == false ) {
    if (sensorVal > ValMax) {
      if ((millis() - chrono) < TempCourse)MoteurOuvre();
      else {
        chrono = millis();
        erreurh = true;
      }
    }
  }
  else MoteurStop();
}


}

Boujour,

Le dernier 'else' du programme n'est la contrepartie que du dernier 'if' et ne s'applique pas au 'if' précédant.
Êtes vous sur que c'est ce que vous voulez ?

Les variables erreurswb et erreurswh sont déclarées en int mais comparées à des états de broches..

Quel en est l'intérêt?

Dans l'état actuel, la fonction ResetAlarme détecte le moment où les switchs de fin de course sont relâchés ou activités.
La variable chrono et calée sur ce temps et les variables booléennes utilisées pour indiquer un temps d'ouverture ou de fermeture trop long sont réinitialisées.

J'ai un doute sur la fonction des variables erreurswb et erreurswb pas forcément en adéquation avec leurs noms, mais ça n'engage que moi.

Les fonctions moteurferme et moteurouvre sont exécutées dans les 'if' mais logiquement cela ne sert à rien puisque, si j'ai bien compris, le moteur tourne déjà ?!

La valeur de chrono est quelque fois réinitialisée de nouveau avec millis() (comme dans les 'if')
Pourquoi ?

Ben déjà je me posait pleins de questions mais alors la j'ai raser le burnout :slight_smile:

a vrai dire j'ai pas tout compris pardon

J'ai viré du superflu mais je trouve pas comment remettre chrono = millis() avant que le if automatique ne redémarre

// Test L293D
// brancher le capteur sur a0 et 5v puis une résistance de 10K de A0 a Ground
const int sensorPin = A0; // Capteur connecter a A0
int sensorVal; // Lecture valeur
int ValMin = 100;
int ValMax = 300;
int TempCourse = 4000;
bool erreurb; bool erreurh; int erreurswb; int erreurswh;
int etatmode;
unsigned long chrono = 0;

// Motor connections
int en1 = 9; // Pin ENA  du L298N
int en2 = 8; // Pin ENB  du L298N
int in1 = 11; // Pin 2  du L298N
int in2 = 10; // Pin 3 du L298N
int in3 = 7; // Pin 4 du L298N
int in4 = 6; // Pin 5 du L298N
// Bouton poussoir
int boutonOuvre = 3; // Bp Ouverture manuel
int boutonFerme = 2; // BP Fermer manuel
// Fin de course
int switchOuvre = 5; // Switch Haut NO
int switchFerme = 4; // Switch Bas NO


void setup()
{
  Serial.begin(9600);
  Serial.println("Programme Poulailler MotorShield");
  pinMode(en1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(en2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  // Moteur off au démarrage
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  // Bp en interne
  pinMode(boutonOuvre, INPUT_PULLUP);
  pinMode(boutonFerme, INPUT_PULLUP);
  pinMode(switchOuvre, INPUT_PULLUP);
  pinMode(switchFerme, INPUT_PULLUP);
  erreurh = false ; erreurb = false ; // Variable erreur haut et bas
}

void MoteurOuvre()
{
  // Ouverture
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 255);
  analogWrite(en2, 0);
  delay(300);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  Serial.println("Ouverture de la porte");
}

void MoteurFerme()
{
  // Fermeture
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 0);
  analogWrite(en2, 255);
  delay(300);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  Serial.println("Fermeture de la porte");
}

// Fonctions
void MoteurStop()
{
  // Stop
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  delay(300);
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  Serial.println("Stop");
  chrono=millis();
}
void ResetAlarme() {
  if (erreurswb != (digitalRead(switchFerme))) {
    erreurswb = (digitalRead(switchFerme));
    erreurb = false;
    
  }

  if (erreurswh != (digitalRead(switchOuvre))) {
    erreurswh = (digitalRead(switchOuvre));
    erreurh = false;
    
  }
}

// Attention on commence ici a faire le show
void loop()
{
  
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  Serial.print(sensorVal); Serial.print(" Lux     "); Serial.print(digitalRead(switchOuvre)); Serial.print(" switchOuvre     "); Serial.print(digitalRead(switchFerme));
  Serial.print(" switchFerme     "); Serial.print(digitalRead(boutonOuvre)); Serial.print(" boutonOuvre     "); Serial.print(digitalRead(boutonFerme)); Serial.print(" boutonFerme     ");
  Serial.print(" erreurH     "); Serial.print(erreurh); Serial.print(" erreurB     "); Serial.println(erreurb);

  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == true)) {etatmode = "rien";}
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == false)) {etatmode = "tout";}
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == true)) {etatmode = "ouvre";}
  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == false)) {etatmode = "ferme";}
  ResetAlarme();


  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  if ( etatmode == "ouvre" ) {MoteurOuvre();}

  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  else if ( etatmode == "ferme" )  {MoteurFerme();}



// Si aucun bouton enfoncer et que les conditions sont bonnes
if (etatmode =="rien"){
  
  if (digitalRead(switchFerme) == true && (erreurb) == false && (sensorVal < ValMin)) {
    
      if ((millis() - chrono) < TempCourse) MoteurFerme();
      else {        
        erreurb = true;
      }
    
  }

  if (digitalRead(switchOuvre) == true && (erreurh) == false && (sensorVal > ValMax)) {
    
      if ((millis() - chrono) < TempCourse)MoteurOuvre();
      else {
        erreurh = true;
      }
    
  }
  else MoteurStop();
}


}

De quel if parlez vous?

// Si aucun bouton enfoncer et que les conditions sont bonnes
if (etatmode =="rien"){
 
  if (digitalRead(switchFerme) == true && (erreurb) == false && (sensorVal < ValMin)) {
   
      if ((millis() - chrono) < TempCourse) MoteurFerme();
      else {       
        erreurb = true;
      }
   
  }

  if (digitalRead(switchOuvre) == true && (erreurh) == false && (sensorVal > ValMax)) {
   
      if ((millis() - chrono) < TempCourse)MoteurOuvre();
      else {
        erreurh = true;
      }
   
  }
  else MoteurStop();
}


}

Sur cette partie, votre structure, si on ne tient pas compte du premier 'if' englobant, est de forme:

If {}
If {} else {}

Le else ne sera exécuté qui si le if de la même ligne n'est pas validé.
Il n'y a pas de condition liée au 'if' de la ligne du dessus

Utiliser ctrl-t pour indenter correctement votre code dans l'éditeur arduino

Oui merci beaucoup
j'ai formater mon texte ctrl T
j'ai rajouter un if pour réinitialiser millis lors d'un contact avec un switch ( réinitialiser le temps du déplacement).
j'ai aussi rajouter une variable "tourne" pour limiter le stop moteur.

Par contre, si il y a une coupure de courant lors du déplacement, et que me retrouve entre la valeur Min et Max, rien ne se passera jusqu’à ce que le capteur rentre dans les valeurs demander.

J'aimerai faire une fermeture avec sécurité a l'initialisation puis laisser le mode automatique gérer après.

// brancher le capteur sur a0 et 5v puis une résistance de 10K de A0 a Ground
const int sensorPin = A0; // Capteur connecter a A0
int sensorVal; // Lecture valeur
int ValMin = 100;
int ValMax = 300;
int TempCourse = 4000;
bool erreurb; bool erreurh; int erreurswb; int erreurswh;
bool tourne = false;
int etatmode;
unsigned long chrono = 0;

// Motor connections
int en1 = 9; // Pin ENA  du L298N
int en2 = 8; // Pin ENB  du L298N
int in1 = 11; // Pin 2  du L298N
int in2 = 10; // Pin 3 du L298N
int in3 = 7; // Pin 4 du L298N
int in4 = 6; // Pin 5 du L298N
// Bouton poussoir
int boutonOuvre = 3; // Bp Ouverture manuel
int boutonFerme = 2; // BP Fermer manuel
// Fin de course
int switchOuvre = 5; // Switch Haut NO
int switchFerme = 4; // Switch Bas NO


void setup()
{
  Serial.begin(9600);
  Serial.println("Programme Poulailler MotorShield");
  pinMode(en1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(en2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  // Moteur off au démarrage
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  // Bp en interne
  pinMode(boutonOuvre, INPUT_PULLUP);
  pinMode(boutonFerme, INPUT_PULLUP);
  pinMode(switchOuvre, INPUT_PULLUP);
  pinMode(switchFerme, INPUT_PULLUP);
  erreurh = false ; erreurb = false ; // Variable erreur haut et bas
}

void MoteurOuvre()
{
  // Ouverture
  tourne = true;
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 255);
  analogWrite(en2, 0);
  delay(300);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  Serial.println("Ouverture de la porte");
}

void MoteurFerme()
{
  // Fermeture
  tourne = true;
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  analogWrite(en1, 0);
  analogWrite(en2, 255);
  delay(300);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  Serial.println("Fermeture de la porte");
}

// Fonctions
void MoteurStop()
{
  // Stop
  if (tourne == false)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    delay(300);
    analogWrite(en1, 0);
    analogWrite(en2, 0);
    Serial.println("Stop");
  }
}
void ResetAlarme()
{
  if (erreurswb != (digitalRead(switchFerme)))
  {
    erreurswb = (digitalRead(switchFerme));
    erreurb = false;
  }

  if (erreurswh != (digitalRead(switchOuvre)))
  {
    erreurswh = (digitalRead(switchOuvre));
    erreurh = false;
  }
}

// Attention on commence ici a faire le show
void loop()
{

  sensorVal = analogRead(sensorPin); // Capteur lumiere
  Serial.print(sensorVal); Serial.print(" Lux     "); Serial.print(digitalRead(switchOuvre)); Serial.print(" switchOuvre     "); Serial.print(digitalRead(switchFerme));
  Serial.print(" switchFerme     "); Serial.print(digitalRead(boutonOuvre)); Serial.print(" boutonOuvre     "); Serial.print(digitalRead(boutonFerme)); Serial.print(" boutonFerme     ");
  Serial.print(" erreurH     "); Serial.print(erreurh); Serial.print(" erreurB     "); Serial.println(erreurb);

  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == true)) etatmode = "rien";
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == false)) etatmode = "tout";
  if ((digitalRead(boutonOuvre) == false) && (digitalRead(boutonFerme) == true)) etatmode = "ouvre";
  if ((digitalRead(boutonOuvre) == true) && (digitalRead(boutonFerme) == false)) etatmode = "ferme";
  if ((digitalRead(switchOuvre) == false) or (digitalRead(switchFerme) == false)) 
  {
    chrono = millis();
    tourne = false;
  }
  
  ResetAlarme();


  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  if ( etatmode == "ouvre" ) {
    tourne = true;
    MoteurOuvre();
  }

  //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
  else if ( etatmode == "ferme" ) {
    tourne = true;
    MoteurFerme();
  }

  // Si aucun bouton enfoncer et que les conditions sont bonnes
  if (etatmode == "rien")
  {

    if (digitalRead(switchFerme) == true && (erreurb) == false && (sensorVal <= ValMin))
    {

      if ((millis() - chrono) < TempCourse) {
        tourne = true;
        MoteurFerme();
      }
      else
      {
        erreurb = true; tourne = false;
      }
    }

    if (digitalRead(switchOuvre) == true && (erreurh) == false && (sensorVal >= ValMax))
    {

      if ((millis() - chrono) < TempCourse) {
        tourne = true;
        MoteurOuvre();
      }
      else
      {
        erreurh = true; tourne = false;
      }
    }
  } MoteurStop();
}

Votre logique de programmation n'est toujours pas bonne...

Vous devez définir les différentes étapes nécessaires au bon déroulement de votre programme.

Chaque étape représente un état ou vous devez attendre un événements (modification de la position d'un switch, le dépassement d'un temps, le déclenchement d'une interruption, la réception d'une donnée sur le port série,...).

Durant cet état, il est donc nécessaire de définir et scruter les variables qui vous indiqueront le moment de basculer dans un autre état.

Vous devrez, le cas échéant, modifier certaines variables nécessaires au traitement de l'étape suivante, puis basculer sur l'état suivant en modifiant la variable de votre machine à état.

Logiquement, il y a donc des états ou seules certaines variables doivent être modifier.

La modification de ces variables en dehors de ces blocs seront sources d'erreurs ou simplement inutiles.

Si l'on prend comme exemple les conditions 'if' citées précédemment de votre loop, elles modifient la variable 'tourne' et appellent la fonction MoteurFerme() ou MoteurOuvre().

Or, la première instruction de ces 2 fonctions est la modification de la variable 'tourne'.

Le bonne emplacement pour la modification de cette variable est évidemment dans la fonction qui change l'état du moteur car cela permet de s'assurer que sa valeur représentera toujours l'état réel du moteur.

les trois fonctions qui change l'état du moteur sont MoteurOuvre(), MoteurFerme() et MoteurStop(). En dehors de ces fonctions, cette variable ne doit être utilisée que pour un test de condition.

Si vous devez modifier cette variable, c'est que vous devez forcement appeler la fonction correspondante.

Dans ce même 'if', vous appelez soit MoteurOuvre(), soit MoteurFerme(). Cependant, cette portion de programme est utilisée pour détectée soit l'activation du switch de fin de course, soit le dépassement du temps d'ouverture et de fermeture.

Il est donc évident que le moteur tourne déjà, rendant inutile un nouvel appel à la fonction. Seul l'appel de la fonction MoteurStop() serait la conséquence de la validation de ces deux condition et provoquera alors le basculement dans un autre état (porté fermée, porte ouverte, erreur lors de l'ouverture, erreur lors de la fermeture)

Vous devez donc vérifier chaque ligne d'instruction pour savoir si elle est nécessaire, car dans le cas contraire, elle est inutile.

Il en va de même pour la variable 'chrono'. Son initialisation doit avoir lieu uniquement à des moments précis (début de l'activation du moteur? au moment ou le switch de butée s'ouvre?).

c'est à vous de définir ce ou ces moments et de vous y tenir. inutile d'initialiser cette variable si vous ne comptez pas faire de mesure de temps ensuite.

Cela ne fera que alourdir votre programme avec des instructions inutiles en compliquant sa compréhension.

Reprenez votre programme pour redéfinir qui fait quoi, et à quel moment.

Une fois modifié, vous verrez que le code sera plus simple à comprendre, et surtout à faire évoluer.

Pour ce qui est de la coupure de courant, le seul moyen de mémoriser une information après redémarrage du programme est de le stocker dans la zone EEPROM.

Malheureusement, cette zone est limitée en nombre d'écriture dans le temps, et sauvegarder en boucle la durée de déplacement de la porte risque d'abîmer votre composant rapidement.

Vous pouvez cependant enregistrer que vous avez amorcé la montée ou la descente de la porte.

Lors de la réinitialisation de la carte, la porte reprendra son mouvement avec une durée d'ouverture et de fermeture réinitialisée. Les switchs de butée seront alors utilisées pour détecter la fin du mouvement, en espérant qu'ils soient fonctionnels.

Il est donc essentiel que la partie mécanique ainsi que le moteur supportent pendant une courte période de forcer le mécanisme car dans le cas contraire, c'est la casse assurée.

Une fonction de détection de la hausse du courant dans le moteur peut s'ajouter à celle des switchs de fin de course pour identifier un obstacle comme une poule sous la porte :o.

Merci beaucoup pour toutes ces explications.

Au départ, lorsque j'ai créer le code, j'étais partis sur une base de while.
En effectuant des test, la seul possibilité de court-circuiter la boucle que j'ai trouver, était de placer des conditions et changement d'état partout.

depuis je me suis diriger vers des if esle mais j'ai pas penser a supprimer le superflu.

Pour ce qui est de la logique de programmation, je n'y suis pas encore, je pratique malheureusement sur base de logique humaine, ce qui rend certainement le programme plus lourd et complexe.

Je suis persuader de m'améliorer avec le temps et expérience.

il faut encore que je me documente sur les terme a employer comme int, bol, const, long etc...

je viens de virer tout les tourne inutile et laisser dans les changements d'état.

Je vais déja utiliser ce code pour ma porte vu qu'elle n'attend que celui-ci car elle est déja monter physiquement

et puis je me dirigerait vers une amélioration du code en y ajoutant quelques fonctions supplémentaire.

En tou cas, merci de tes explications je vais essayer de tout comprendre ;D puis corriger

Ps pour la fonction de réarmement, je me suis diriger vers une variable reset mis a 1 en setup et changer lors de la fermeture et executer une seul fois

if reset == 1 ........ reset = 0;

Bonne journée et super forum d'entraide 8)

Salut ,

jetez un coup d' oeil ici , ca vous sera peut etre utile pour simplifier votre gestion des etats :slight_smile:
https://forum.arduino.cc/index.php?topic=470879.0

En fait, je n'arrive pas a me synchroniser sur le mode de réflexion standard.
On va dire que j'ai tout les éléments mais que je n'arrive pas a les placers dans l'ordre .

au final, mon code actuel fonctionne a merveille mais sans en être heureux car il y a surement plus correct a faire.

J'ai l'impression qu'il est long pour faire aussi peu

Dans l'ensemble,
en mode manuel, les leds rouge et bleu clignotes et j'ai les boutons a dispositions avec switch actifs.

en mode auto, gérer par la photorésistance en fermeture, led rouge clignote, led bleu en ouverture.

Pour éviter un arrêt de fermeture ou ouverture,le capteur a un écart séparer de 5lux ' on va dire'.

Donc ouverture = clignote bleu et fixe quand switch est actionner
idem fermeture en rouge.

erreur = clignotement alterner

// brancher le capteur sur a0 et 5v puis une résistance de 10K de A0 a Ground
const int sensorPin = A0; // Capteur connecter a A0
const int ModePin = A1;
int sensorVal; // Lecture valeur
int TempCourse = 40000;
bool erreur; int erreurswb; int erreurswh;
bool tourne = false;
int etatmode;
unsigned long chrono = 0;
bool reset = 1;
int luxcapteur;
bool mode;
int luxMin = 10;
int luxMax = 500;

// LED
const int ledPinBleu =  12;      // crée un identifiant pour la broche utilisée avec la LED
const int ledPinRouge =  13;      // crée un identifiant pour la broche utilisée avec la LED
int ledManu = LOW; //  est utilisée pour fixer l'état de la LED (HIGH/LOW)
int ledAuto = LOW; //  est utilisée pour fixer l'état de la LED (HIGH/LOW)
long previousMillis = 0;        // variable pour mémoriser le temps écoulé depuis le dernier changement de la LED
long interval = 500;

// Motor connections
int en1 = 9; // Pin ENA  du L298N
int en2 = 8; // Pin ENB  du L298N
int in1 = 11; // Pin 2  du L298N
int in2 = 10; // Pin 3 du L298N
int in3 = 7; // Pin 4 du L298N
int in4 = 6; // Pin 5 du L298N

// Bouton poussoir
int boutonOuvre = 3; // Bp Ouverture manuel
int boutonFerme = 2; // BP Fermer manuel

// Fin de course
// Attention switch appuyer = 1 sinon 0 !!!!!!!!
int switchOuvre = 5; // Switch Haut NF
int switchFerme = 4; // Switch Bas NF


void setup()
{
  Serial.begin(9600);
  Serial.println("Programme Poulailler MotorShield");
  pinMode(en1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(en2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Moteur off au démarrage
  analogWrite(en1, 0);
  analogWrite(en2, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  // Bp en interne
  pinMode(boutonOuvre, INPUT_PULLUP);
  pinMode(boutonFerme, INPUT_PULLUP);
  pinMode(switchOuvre, INPUT_PULLUP);
  pinMode(switchFerme, INPUT_PULLUP);
  erreur = false ;  // Variable erreur haut et bas

  pinMode(ledPinBleu, OUTPUT);
  pinMode(ledPinRouge, OUTPUT);
  pinMode(ModePin, INPUT);


}

void MoteurOuvre()
{
  unsigned long currentMillis = millis(); // stocke la valeur courante de la fonction millis()

  // Ouverture
  tourne = true;
  analogWrite(en1, 255);
  analogWrite(en2, 0);
  delay(300);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  //  Serial.println("Ouverture de la porte");

  if ((currentMillis - previousMillis > interval) && (digitalRead(switchOuvre) == 0) && (erreur == false) && (mode == 1)) {
    previousMillis = currentMillis;
    if (ledManu == LOW) {
      ledManu = HIGH; ledAuto = LOW;
    }
    else
    {
      ledManu = LOW;

    }
    digitalWrite(ledPinBleu, ledManu); digitalWrite(ledPinRouge, ledAuto);
  }

}

void MoteurFerme()
{
  unsigned long currentMillis = millis(); // stocke la valeur courante de la fonction millis()

  // Fermeture
  tourne = true;
  analogWrite(en1, 0);
  analogWrite(en2, 255);
  delay(300);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  //  Serial.println("Fermeture de la porte");
  if ((currentMillis - previousMillis > interval) && (digitalRead(switchFerme) == 0) && (erreur == false) && (mode == 1)) {
    previousMillis = currentMillis;
    if (ledAuto == LOW) {
      ledAuto = HIGH; ledManu = LOW;
    }
    else
    {
      ledAuto = LOW;

    }
    digitalWrite(ledPinBleu, ledManu); digitalWrite(ledPinRouge, ledAuto);
  }
}

// Fonctions
void MoteurStop()
{
  // Stop
  if (tourne == false)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    delay(300);
    analogWrite(en1, 0);
    analogWrite(en2, 0);
    //   Serial.println("Stop");
  }
}
void ResetAlarme()
{
  if ((erreurswb != (digitalRead(switchFerme))))
  {
    erreurswb = (digitalRead(switchFerme));
    erreur = false;
  }

  if (erreurswh != (digitalRead(switchOuvre)))
  {
    erreurswh = (digitalRead(switchOuvre));
    erreur = false;
  }
};



// Attention on commence ici a faire le show
void loop()
{
  ResetAlarme();
  sensorVal = analogRead(sensorPin); // Capteur lumiere
  mode = analogRead(ModePin);
  unsigned long currentMillis = millis(); // stocke la valeur courante de la fonction millis()
  /*
    Serial.print(sensorVal); Serial.print(" Lux     "); Serial.print(digitalRead(switchOuvre)); Serial.print(" switchOuvre     "); Serial.print(digitalRead(switchFerme));
    Serial.print(" switchFerme     "); Serial.print(digitalRead(boutonOuvre)); Serial.print(" boutonOuvre     "); Serial.print(digitalRead(boutonFerme)); Serial.print(" boutonFerme     ");
    Serial.print(" erreur     "); Serial.println(erreur);
    Serial.println(reset); Serial.println(mode);Serial.println(luxcapteur);
  */

  if ((digitalRead(switchOuvre) == 1) && (erreur == false) && (mode == 1)) {
    digitalWrite(ledPinBleu, HIGH);
    digitalWrite(ledPinRouge, LOW);
  } else if ((digitalRead(switchFerme) == 1) && (erreur == false) && (mode == 1)) {
    digitalWrite(ledPinBleu, LOW);
    digitalWrite(ledPinRouge, HIGH);
  }

  if ((digitalRead(boutonOuvre) == 1) && (digitalRead(boutonFerme) == 1)) {
    etatmode = 0;  //Rien
    if (mode == 0) {
      tourne = false;
    }
  }
  if ((digitalRead(boutonOuvre) == 0) && (digitalRead(boutonFerme) == 0)) {
    etatmode = 1;  //Tout
    // erreur = true;
  }
  if ((digitalRead(boutonOuvre) == 0) && (digitalRead(boutonFerme) == 1)) etatmode = 2; //Ouvre
  if ((digitalRead(boutonOuvre) == 1) && (digitalRead(boutonFerme) == 0)) etatmode = 3; //Ferme
  if ((digitalRead(switchOuvre) == 1) or (digitalRead(switchFerme) == 1)) {
    chrono = millis();
    tourne = false;
  }
  if (sensorVal <= luxMin) luxcapteur = 0;
  if (sensorVal >= luxMax) luxcapteur = 1;
  if ((sensorVal > luxMin + 5) && (sensorVal < luxMax - 5)) {
    luxcapteur = 2;
    chrono = millis();
  }


  // Active la LED si erreur
  if ((erreur == true) && (mode == 1)) {
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      if (ledManu == LOW) {
        ledManu = HIGH; ledAuto = LOW;
      }
      else
      {
        ledManu = LOW;
        ledAuto = HIGH;
      }
      digitalWrite(ledPinBleu, ledManu); digitalWrite(ledPinRouge, ledAuto);
    }
  }//

  if (reset == 1) {
    while ((digitalRead(switchFerme) == 0))
    {
      //    if ((digitalRead(switchFerme) == 0) && (mode == 1))
      MoteurFerme();

    } reset = 0; MoteurStop();
  }

  else {
    if (mode == 0) { //MANUEL
      chrono = millis();
      if (erreur == false) {
        if (currentMillis - previousMillis > interval)  {
          previousMillis = currentMillis;
          if (ledAuto == LOW) {
            ledAuto = HIGH; ledManu = HIGH;
          }
          else
          {
            ledAuto = LOW; ledManu = LOW;

          }
          digitalWrite(ledPinBleu, ledManu); digitalWrite(ledPinRouge, ledAuto);
        }
      }
      //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
      if (( etatmode == 2 ) && (digitalRead(switchOuvre) == 0)) {
        MoteurOuvre();
      }

      //Commande Bouton poussoir Ouvert et Fermer, si uniquement un des deux est presser
      else if (( etatmode == 3 ) && (digitalRead(switchFerme) == 0)) {
        MoteurFerme();
      }
    }

    else if ((mode == 1) && (erreur == false)) { //AUTO


      if (digitalRead(switchFerme) == 0 && (erreur) == false && (luxcapteur) == 0)
      {
        if ((millis() - chrono) < TempCourse) {
          MoteurFerme();
        }
        else
        {
          erreur = true; tourne = false;
        }
      }
      if (digitalRead(switchOuvre) == 0 && (erreur) == false && (luxcapteur) == 1)
      {
        if ((millis() - chrono) < TempCourse) {
          MoteurOuvre();
        }
        else
        {
          erreur = true; tourne = false;
        }
      }
    }
    MoteurStop();
  }
}

lalens007:
Pour ce qui est de la logique de programmation, je n'y suis pas encore, je pratique malheureusement sur base de logique humaine, ce qui rend certainement le programme plus lourd et complexe.

Pas du tout. C'est la même logique que l'on utilise au quotidien et pour programmer.
Simplement, avant de programmer il faut formaliser cette logique. Et c'est cette étape que les débutants en programmation court-circuitent souvent.
Il faut précisément décrire les étapes élémentaires (les fonctions en C) et les conditions qui font passer d'une étape à la suivante.
Le problème c'est que dans la vie de tous les jours on fait les choses assez machinalement et lorsqu'on décrit les actions nécessaires à la réalisation d'une tâche on oublie assez souvent des étapes et lorsqu'on programme ça plante.
Il faut commencer par poser sur le papier les actions et leur enchainement avec (toutes) les conditions qui vont faire passer d'une actions à une autre. Ensuite, on essaye de réaliser la tâche en suivant les actions décrites dans l'algorithme pour vérifier que l'on arrive bien au résultat.
Et seulement après on code.

Tu dois être plus rigoureux dans l'utilisation de tes variables en fonction du type.

Une variable booléenne est égale à 'true' ou 'false'.
DigitalRead utilise uniquement 'HIGH' ou 'LOW' pour représenter l'état de la pin.
Le résultat de millis() doit être assigné uniquement à une variable de type unsigned long.

La variable 'tourne' est encore modifié en dehors des fonctions de commande du moteur.

Tu dois choisir si cette variable représente l'état de fonctionnement du moteur ou commande l'activation du moteur.

Dans le premier cas, on modifie sa valeur dans les fonctions de commande du moteur et on lit sa valeur en dehors pour savoir si le moteur tourne.

Dans le deuxième cas, on teste sa valeur dans les fonctions d'ouverture ou de fermeture.... pour activer l'ouverture ou la fermeture..., et on active les fonctions en modifiant sa valeur en dehors des fonctions.

Ne mélange pas pas les deux sinon ton programme deviendra difficile à lire.

Tu utilises la variable 'reset' pour initialiser la position de la porte une seule fois dans la loop.
Cette fonction doit être déplacée dans le setup, c'est son rôle d'initialiser les variables, outils, et états de ton système.

Fdufnews à raison. La structure du programme doit être constituée de fonctions simples qui s'enchaînent les une derrières les autres de façon logique.

Il faut partir d'une structure simple et fonctionnelle, et ensuite ajouter les éléments un par un.

Si tu ne maîtrise pas une fonction, tu testés celle ci à part jusqu'à obtenir le résultat voulut, et ensuite tu l'ajoutes à ton programme principale.

Mais tu dois toujours garder en tête lors de l'écriture des fonctions qu'elles ne doivent pas interférer avec le reste du programme.

Un exemple classique est l'instruction delay() qui simplifie les 'pauses' dans une fonction de clignotement de led, mais interfère avec une autre fonction qui scrute un clavier ou commande un moteur pas à pas.
C'est pourquoi on le banni sur des programmes complexes, mais peut convenir sur un programme simple.