Cellule photoelectrique et programme non bloquant

bonjour,
je cherche a utiliser une cellule photoélectrique pour declancher un moteur qui ferme une trappe quand la nuit arrive en parallèle d un bouton poussoir ( declanche la fermeture de la trappe si j oublie de fermer). J ai cherché a mettre une securite du style si la trappe n est pas arrivée en butée basse au bout d un certain temps, ca veut dire qu il y a un problème et le moteur s arrête. J ai bien réussi a le faire avec le bouton poussoir et la fonction millis(). En revanche avec la cellule photo électrique, je n y arrive pas car cette cellule fonctionne comme si on appuyait en permanence sur un bouton de fermeture et je ne peux plus utiliser de sécurité. Quelqu un aurait une idée? ( je ne sais pas si j ai posté au bon endroit, mais il n y a pas grand chose en francais)
ci joint la simulation que j ai fait avec un bouton ouverture, un bouton fermeture, des butées haute et basse, une led verte pour signaler que la trappe est ouverte et une led rouge.
merci d avance
Circuit design trappe non bloquante | Tinkercad

:warning: pensez vous que le bar soit l'endroit idéal pour poster ? (par contre il y a un fil pour se présenter ce qui est bien vu :slight_smile: )

lire "Les bonnes pratiques du Forum Francophone”


je déplace votre post dans le forum principal

Bonjour

Pour augmenter les chances de réponse il vaudrait mieux poster ici le code (en adoptant la méthode présentées dans le 'Bonnes Pratiques" (partie "Utilisation de quelques outils") . idem pour le montage (plan de câblage mieux véritable schéma)

Tour le monde n'ira pas voir du côté de Tinkercad......

+Quelle est la référence de la 'cellule photoélectrique ' utilisée dans la réalité ?
véritable cellule photoéléctrique ? simple photorésistance ?

il y a aussi de nombreux exemples de porte de poulailler qui peuvent être regardés

int pin1Moteur = 8;
int pin2Moteur = 9;
int pinPMoteur = 5;
int buteeHaute = 2;
int buteeBasse = 3;
int pinOuverture = 4;//bouton ouverture
int pinFermeture = 7;//bouton fermeture
int ledVerte = 10;
int ledRouge = 11;
int Periode = 150000; //periode de temporisation si probleme
int etatMoteur;//etat de marche du moteur
int crepuscule;
boolean etatO;//etat bouton ouverture
boolean etatF;//etat bouton fermeture
boolean etatButeeHaute;
boolean etatButeeBasse;
boolean nuit = 0; //etat cellule photoelectrique
boolean secu;//etat securité pour arreter moteur si probleme
int delaicellule = 200000; //delai detection seuil crepuscule
int ledStateV = LOW; //etat led verte
int ledStateR = LOW; //etat led rouge
unsigned long previousMillisR;//clignotement leds
unsigned long previousMillisV;
unsigned long temporisationO;
unsigned long temporisationF;
unsigned long temporisationN;
//securité


void setup() {
  pinMode(pinPMoteur, OUTPUT);
  pinMode(pin1Moteur, OUTPUT);
  pinMode(pin2Moteur, OUTPUT);
  pinMode(buteeHaute, INPUT);
  pinMode(buteeBasse, INPUT);
  pinMode(pinOuverture, INPUT);
  pinMode(pinFermeture, INPUT);
  pinMode(ledVerte, OUTPUT);
  pinMode(ledRouge, OUTPUT);
  etatO = 0;
  etatF = 0;
  secu = 0;
  Serial.begin(9600);

}

void loop()
{

  //LECTURE BUTEES

  boolean etatButeeHaute = digitalRead(buteeHaute);//lecture butée haute
  boolean etatButeeBasse = digitalRead(buteeBasse);//lecture butée basse

  //LECTURE BOUTONS

  if (digitalRead(pinOuverture) == 1) //lecture appui bouton ouverture
  { unsigned char tempoBoutonO = millis(); //demarrage temporisation pour eviter rebonds
    if ((millis() - tempoBoutonO) > 100)
    { if (digitalRead(pinOuverture) == 1)
      {
        etatO = 1; //etat bouton ouverture appuyé
      }
    }
  }
  else {
    etatO = 0;
  }


  if (digitalRead(pinFermeture) == 1) //lecture appui bouton fermeture
  { unsigned char tempoBoutonF = millis(); //demarrage temporisation pour eviter rebonds
    if ((millis() - tempoBoutonF) > 100)
    { if (digitalRead(pinFermeture) == 1)
      {
        etatF = 1; //etat bouton fermeture appuyé
      }
    }
  }
  else {
    etatF = 0;
  }

  Serial.print("etatbouton ouverture=");
  Serial.print(etatO);
  Serial.print("etatbouton fermeture=");
  Serial.println(etatF);

  //CELLULE PHOTOELECTRIQUE

  if (analogRead (A0) < 150) //lecture cellule
  { unsigned long temporisationcellule = millis();
    if ((millis() - temporisationcellule) > delaicellule) // temporisation permettant de prendre une seconde mesure de luminosité
    { if (analogRead (A0) < 150)
      {
        nuit = 1; //il fait nuit
      }
    }
  }
  else {
    nuit = 0;
  }




  //OUVERTURE (etatMoteur1)


  if ((etatO == 1) && (etatButeeHaute == 0)) // ouverture trappe
  { actionMoteur(1, 100);//moteur en montée
    unsigned long temporisationO = millis();
    etatMoteur = 1; secu = 0;
  }

  if (etatMoteur == 1) //si le moteur est demarré en montée
  { if ((millis() - temporisationO) > Periode) // je regarde si le temps ecoulé est superieur a la periode
    { actionMoteur(0, 0);
      etatMoteur = 0; secu = 1;
    }// dans ce cas, ca depasse la periode alors ca eteint le moteur
    unsigned long currentMillis = millis();//clignotement vert
    digitalWrite(ledRouge, LOW);
    if (currentMillis - previousMillisV >= 500)
    { previousMillisV = currentMillis;
      ledStateV = !ledStateV;
      digitalWrite(ledVerte, ledStateV);
    }

  }



  //FERMETURE (etatMoteur2)


  if ((etatF == 1) && (etatButeeBasse == 0)) //fermeture trappe
  { actionMoteur(-1, 100);//moteur en descente
    unsigned long temporisationF = millis();
    etatMoteur = 2; secu = 0;



  }

  if (etatMoteur == 2) //si le moteur est demarré en descente
  { if ((millis() - temporisationF) > Periode) // je regarde si le temps ecoulé est superieur a la periode
    { actionMoteur(0, 0);

      etatMoteur = 0; secu = 1;
    }// dans ce cas, ca depasse la periode alors ca eteint le moteur

    unsigned long currentMillis = millis();//clignotement rouge
    digitalWrite(ledVerte, LOW);
    if (currentMillis - previousMillisR >= 500)
    { previousMillisR = currentMillis;
      ledStateR = !ledStateR;
      digitalWrite(ledRouge, ledStateR);
    }
  }




  //NUIT (etatMoteur3)

  if ((nuit == 1) && (etatButeeBasse == 0)) //fermeture trappe nuit
  { actionMoteur(-1, 100);//moteur en descente
    unsigned long temporisationN = millis();
    etatMoteur = 3; secu = 0;
  }
  if (etatMoteur == 3) //si le moteur est demarré en descente
  { if ((millis() - temporisationN) > Periode) // je regarde si le temps ecoulé est superieur a la periode
    { actionMoteur(0, 0);
      etatMoteur = 0; secu = 1;
    }
    unsigned long currentMillis = millis();//clignotement rouge
    digitalWrite(ledVerte, LOW);
    if (currentMillis - previousMillisR >= 500)
    { previousMillisR = currentMillis;
      ledStateR = !ledStateR;
      digitalWrite(ledRouge, ledStateR);
    }


  }


  //ARRET MOTEUR BUTEES


  if ((etatMoteur == 1) && (etatButeeHaute == 1)) // arret moteur en butée haute
  { actionMoteur(0, 0);
    etatMoteur = 0;
    etatO = 0;
    secu = 0;
  }

  if ((etatMoteur == 2) && (etatButeeBasse == 1)) //arret moteur en butée basse
  { actionMoteur(0, 0);
    etatMoteur = 0;
    etatF = 0;
    secu = 0;
  }


  if ((etatMoteur == 3) && (etatButeeBasse == 1)) //arret moteur en butée basse
  { actionMoteur(0, 0);
    etatMoteur = 0;
    etatF = 0;
    secu = 0;
  }

  //ARRET URGENCE
  if ((etatF == 1) && (etatO == 1)) //arret d urgence en appuyant sur les 2 boutons
  {
    arretTrappe;
  }


  //LEDS VERTE ET ROUGE

  if (secu == 1) //si delai trop long et butées non atteintes
  { unsigned long currentMillis = millis();//clignotement rouge rapide
    if (currentMillis - previousMillisR >= 200)
    { previousMillisR = currentMillis;
      ledStateR = !ledStateR;
      digitalWrite(ledRouge, ledStateR);
    }

  }

  if ((etatButeeHaute == 1) && (etatButeeBasse == 0) && (etatMoteur == 0)) // allumer led verte quand trappe ouverte
  { digitalWrite (ledVerte, HIGH);
    digitalWrite (ledRouge, LOW);

  }

  if ((etatButeeBasse == 1) && (etatButeeHaute == 0) && (etatMoteur == 0)) //allumer led rouge quand trappe fermée
  { digitalWrite (ledVerte, LOW);
    digitalWrite (ledRouge, HIGH);
  }

  if ((etatButeeBasse == 0) && (etatButeeHaute == 0) && (etatMoteur == 0) && (secu == 0))
  { digitalWrite (ledVerte, LOW);
    digitalWrite (ledRouge, LOW);
  }



}






void actionMoteur(int sens, int pourcentage)
{
  int etat1, etat2, puissance;
  if (sens == 1)
  {
    etat1 = 1;
    etat2 = 0;

  }
  else if (sens == -1)
  {
    etat1 = 0;
    etat2 = 1;

  }
  else
  {
    etat1 = 0;
    etat2 = 0;
  }
  puissance = map(pourcentage, 0, 100, 0, 255);
  digitalWrite (pin1Moteur, etat1);
  digitalWrite (pin2Moteur, etat2);
  analogWrite (pinPMoteur, puissance);
}


void arretTrappe()
{
  actionMoteur(0, 0); etatO = 0; etatF = 0;
}

bonsoir je n ai pas de schema de montage a part celui que j ai fait sur tinkercad. J ai un circuit "commande" avec les boutons poussoirs, les butées et la photoresistance. J ai un circuit "puissance" en 12V pour le moteur et les leds que je commande via un transistor. Le circuit tourne depuis plus d un an sans problemes particulier
J ai deja regardé les autres sujet sur les trappes mais ca ne repondait pas a mes questions. Pour la cellule, je pense que c est une simple photo resistance, ele etait dans un kit arduino.
En fait je souhaite l ameliorer en ajoutant des securités et faire un programme non bloquant, c est a dire qu avant dans mon programme, dès qu une condition etait remplie, l action se deroulait jusqu au bout. Je cherche a faire qqchose de plus fluide, par exemple pouvoir faire remonter la trappe si je viens d appuyer par erreur sur la descente... J ai peut etre mis trop de fonctions millis(). Du coup je viens de televerser le programme sur l arduino et je me rend compte que la trappe se met tout de suite en securité aussi bien en montée qu en descente, meme en augmentant le delai pour se mettre en securite alors que sur le simulateur ca fonctionnait. voila voila. Vous allez certainement rigoler en regardant le code mais c est mon premier projet. j essaie de faire simple mais je me rend compte que ca devient vite compliqué :slightly_smiling_face:

bonjour, je crois que j ai déconné dans les portées de mes variables avec les millis() pour commencer, j essaie de corriger ca

profitez en aussi pour utiliser HIGH et LOW pour tester les résultats de digitalRead(), ça rend le code plus lisible.

le nom des variables pourrait être aussi mieux choisi. Quand je vois que etatButeeHaute est un booléen par exemple (donc vrai ou faux), je ne sais pas ce que ça veut dire s'il est vrai (ça dépend de si vous utilisez un pullup ou pulldown)

Si vous appeliez la variable porteEnButeeHaute alors là ce serait plus clair.

Par exemple:

const byte APPUI = LOW; // avec un PULLUP
...
boolean porteEnButeeHaute = (digitalRead(buteeHaute) == APPUI);  // test d'appui en butée haute

si ensuite on a dans le code
if (porteEnButeeHaute) { ....}
on comprend tout de suite ce que veut dire le test