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

bonjour, bon je suis paumé , je voudrais refaire tout le programme mais je ne sais pas quoi utiliser comme boucle, test... ce que je voudrais c est ouvrir et fermer manuellement la trappe en appuyant brievement sur un bouton, fermer automatiquement sui il fait nuit au cas ou j aurais oublier de fermer et surtout ajouter une securité qui permet d arreter le moteur au dela d un certain temps. J ai bien essaye de faire ce code mais c est pas terrible. Pouvez vous juste me dire dans quelle direction aller?

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 sensib=110;
unsigned long Periode=1000;//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 PorteOuverte;
boolean PorteFermee;
boolean nuit=0;//etat cellule photoelectrique
boolean secu;//etat securité pour arreter moteur si probleme
int delaicellule=3000;//delai detection seuil crepuscule
int ledStateV=LOW;//etat led verte
int ledStateR=LOW;//etat led rouge
int compteurNuit=0;
unsigned long previousTimeN=0;//cellule photo electrique
unsigned long previousTimeM=0; //montée moteur
unsigned long previousTimeD=0;//descente moteur
unsigned long previousMillisV=0;//clignotement vert
unsigned long previousMillisR=0;//clignotement rouge


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() 
{
unsigned long currentTime=millis();
 
//LECTURE BUTEES

 boolean PorteOuverte = digitalRead(buteeHaute);//lecture butée haute
 boolean PorteFermee = digitalRead(buteeBasse);//lecture butée basse

  
  
  
 //LECTURE BOUTONS etatO et etatF
  
 if (digitalRead(pinOuverture)==1)//lecture appui bouton ouverture
  	
   			{etatO=1;compteurNuit=0;
        	}// etat bouton ouverture appuyé	
  	
  else {etatO=0;
       }
  
 if (digitalRead(pinFermeture)==1)//lecture appui bouton ouverture
  	
   			{etatF=1;compteurNuit=0;
        	}//etat bouton ouverture appuyé	
  	
  else {etatF=0;
       } 
  
/* 
 Serial.print ("etatO=");
Serial.print (etatO);
  Serial.print ("etatF=");
Serial.print(etatF);
 
 */ 
  
  
  //CELLULE PHOTOELECTRIQUE nuit
  
  if (analogRead (A0)<sensib)//lecture cellule
  {
    
   	if ((millis()-previousTimeN)>delaicellule)// temporisation permettant de prendre une seconde mesure de luminosité
    	{previousTimeN=millis();
      		if (analogRead (A0)<sensib)
        		{nuit=1;
                 compteurNuit++;
                 previousTimeM=millis();
                 
               	}//il fait nuit
        }
  }
  else {nuit=0;}
  
  
  
  
  
  
  Serial.print ("cellule photo electrique=");
  Serial.print(analogRead(A0));
  Serial.print ("nuit=");
  Serial.print(nuit);
  Serial.print ("compteur nuit=");
  Serial.println (compteurNuit);
   
 
  
  
  //OUVERTURE (etatMoteur1)
  
 /* Serial.print ("etat moteur=");
  Serial.print (etatMoteur);
  Serial.print ("securité=");
  Serial.println (secu);
*/
  if ((etatO == 1)&&(PorteOuverte==0))// ouverture trappe
  {actionMoteur(1, 100);
   etatMoteur=1;
   previousTimeM=millis();
  }
  
  


	

  
  //FERMETURE (etatMoteur2)
  
  
  if (((etatF == 1)&&(PorteFermee==0))||((compteurNuit>= 1)&&(compteurNuit<= 2)&&(PorteFermee==0)))//fermeture trappe
  { actionMoteur(-1, 100);
   etatMoteur=2;//moteur en descente 
   previousTimeM=millis();
  }
  

  
 
  
 //SECURITE
  
  if ((etatMoteur==1)||(etatMoteur==2))
  {
    if(((millis())-previousTimeM) > Periode)
  	// je regarde si le temps ecoulé est superieur a la periode
			{
          	arretMoteur();
   			alarme();
              previousTimeM=millis();
      
    	}
  }
   
  
  //ARRET MOTEUR BUTEES
  

	if ((etatMoteur==1)&&(PorteOuverte==1))// arret moteur en butée haute
 {arretMoteur();}
  
	if ((etatMoteur==2)&&(PorteFermee==1))//arret moteur en butée basse
 {arretMoteur();compteurNuit=3;}  
  
  
	 
  
  //ARRET URGENCE
  	if ((etatF==1)&&(etatO==1))//arret d urgence en appuyant sur les 2 boutons
      {arretMoteur();}
      

  //LEDS VERTE ET ROUGE
  
 		
  
	if ((PorteOuverte == 1)&&(PorteFermee == 0))// allumer led verte quand trappe ouverte
  	{ digitalWrite (ledVerte, HIGH);
    digitalWrite (ledRouge, LOW);
  
  	}

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

  	
   	if (etatMoteur==1)//ouverture
  {clignotementVert();}
  
	if (etatMoteur==2)//fermeture
  {clignotementRouge();}
  

}


void actionMoteur(int sens, int pourcentage) //fonction moteur
{
  int etat1, etat2, puissance;
  if (sens == 1) //ouverture
  	{etat1 = 1;
   	etat2 = 0;
 	}
  else if (sens == -1) //fermeture
  	{
    etat1 = 0;
    etat2 = 1;
  	}
  else 
  	{
    etat1 = 0;
    etat2 = 0;
  	}
  puissance = map(pourcentage, 0, 100, 0, 255);//mappage puissance en pourcentage
  digitalWrite (pin1Moteur, etat1);
  digitalWrite (pin2Moteur, etat2);
  analogWrite (pinPMoteur, puissance);
  

  
}


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



void clignotementVert()
{digitalWrite (ledRouge, LOW);
 unsigned long previousMillisV=0;
 
     if((millis()- previousMillisV )>= 500) 
 			{previousMillisV = millis();
    		ledStateV= !ledStateV;
   			digitalWrite(ledVerte, ledStateV);
  			}
}
  

void clignotementRouge()
{digitalWrite (ledVerte, LOW);
 unsigned long previousMillisR=0;
 
     if((millis()- previousMillisR )>= 500) 
 			{previousMillisR = millis();
    		ledStateR= !ledStateR;
   			digitalWrite(ledRouge, ledStateR);
  			}
}
  





void alarme()
{digitalWrite(ledVerte,LOW);
 compteurNuit=3;
 unsigned long erreur=0;
 
     if((millis()- erreur )>= 200) 
 			{erreur = millis();
    		ledStateR= !ledStateR;
   			digitalWrite(ledRouge, ledStateR);
  			}
}
  

vous avez regardé tous les exemples de code pour les portes de poulailler (il y en a plusieurs sur le forum) ?

Ce que vous décrivez est sans doute déjà existant

Si vous voulez recommencer de 0, décrivez sur un bout de papier la machine à état correspondant à votre besoin et implémentez là. (ie prenez le temps de la réflexion avant de coder)

➜ (cf mon tuto éventuellement)

Merci pour le conseil. J avais déjà lu une première fois le tuto mais j avais rien compris :grimacing:. Là ça commence à aller mieux et surtout maintenant je sais que c est la direction que je dois prendre. Vais travailler dans ce sens et je reviendrai vers vous après si ça va pas. Mais avec la machine à état je vais pouvoir introduire le temps pour la sécurité et faire clignoter les leds. Merci encore

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