Porte automatique pour poulailler

Bonsoir,

Voici le code promis.
Du coup, il peut gérer soit des contacts fin de course soit une entrée analogique.
Il suffit de commenter ou dé-commenter les #define non utiles
Le fonctionnement avec les contacts a été testé (moteur 28BYJ6-48 5v)
Reste à tester le fonctionnement avec l’entrée analogique et bien définir le sens des corrections.
A tester…
Bon courage.
Etibou

pese_ruche_contrepoids.ino (3.09 KB)

Bonjour, j'ai réalisé une porte poulailler à guillotine, avec 2 fin de courses haut et bas, et le moteur est une foreuse sans fils. Au niveau mécanique ça fonctionne très bien. Pour la programmation c'est un Arduino uno. détection nuit/ jour par une cellule photo-résistance. le problème est que j'ai voulus ajouter une temporisation à la fermeture (qui fonctionne bien) mais il y a un problème à l'ouverture: on dirait que il ne tient pas compte de la temporisation.

Pour le moment j'utilise une horloge pour retarder l'ouverture.... et j'ai mis des // dans mon programme, je pense que j'ai un problème de compréhention des if et else, ou des lignes de conditions en général Voici le progamme

const char ledbleu = 2; // variable broche 2 (vraie), Une LED bleu  pour détection crépuscule, s'il fait sombre
const char fermeture = 7;  // variable pour broche 7 (vraie), pour fermer porte
const char capteur = 0; // broche A0 sur laquelle va être connecté le pont diviseur de tension

float tension = 0;             // variable qui va enregistrer la tension lue en sortie du capteur
float seuilObscurite = 4.2;    // valeur en V, seuil qui détermine le niveau auquel l'obscurité est présente
int x=0;
void setup()
        {
           // définition des broches utilisées
           pinMode(ledbleu, OUTPUT);
           pinMode(fermeture, OUTPUT);
           digitalWrite(ledbleu, HIGH);
           digitalWrite(fermeture, HIGH);
           Serial.begin(9600); // la voie série pour monitorer
        }
void loop()
{
    // conversion de cette valeur en tension
    tension = (analogRead(capteur) * 5.0) / 1024;

    if(tension >= seuilObscurite)  //Pour FERMETURE
          {
            x=x+1;
                 if (x==1)digitalWrite(ledbleu, LOW);               // detection seuil obscurité On allume la LED bleu         
                 if (x==1)delay(240000);                              // délai pour ne fermer porte que aprés 4 minutes ( 240 000)
                 x=2;     
             digitalWrite(fermeture, LOW);                           //  On ferme la porte apres x secondes
             digitalWrite(ledbleu, HIGH);                           // On éteint la LED bleu
          }     
    if(tension < seuilObscurite)  //Pour OUVERTURE
              {
                x=3;
                //Serial.print(" x=  ");
               //if (x==3)delay(240000);//délai pour ouvrir la porte que aprés 4 minutes
                if (x==3)digitalWrite(fermeture, HIGH); // on ouvre la porte
         x=0;
     }

    // délai pour ne prendre des mesures que toutes les 60-secondes (60 000)
    delay(60000);
    
                   //Serial.print(" x=  ");
                    Serial.println(x);
}

Hello,

C'est pas mal mais il faut tenir compte de quelques règles. Quand on mesure la tension d'une cellule photo-résistance et qu'on détermine un niveau de luminosité pour déclencher l'ouverture et la fermeture d'une porte, il est préférable d'avoir deux seuils de détection différents pour éviter que la porte fasse le yo-yo au moment du passage du seuil. Une autre possibilité est de travailler avec une valeur moyennée. Je pense que le pb vient de la variable x. Il est préférable d'utiliser un booléen pour mémoriser l'état de la porte et engager une seule fois l’ordre d’ouverture et de fermeture. Voici un exemple de code avec les 2 seuils de détection (valeurs arbitraire) et un booléen pour mémoriser l'état de la porte. (Attention code non testé)

const char ledbleu = 2; // variable broche 2 (vraie), Une LED bleu  pour détection crépuscule, s'il fait sombre
const char fermeture = 7;  // variable pour broche 7 (vraie), pour fermer porte
const char capteur = 0; // broche A0 sur laquelle va être connecté le pont diviseur de tension

float tension = 0;             // variable qui va enregistrer la tension lue en sortie du capteur
float seuilObscurite = 4.2;    // valeur en V, seuil qui détermine le niveau auquel l'obscurité est présente
float seuilLumonisite = 4;    // valeur en V, seuil qui détermine le niveau auquel la luminosité est présente
boolean PorteFermee = false;  // statut de la porte ou démarre toujours le programme porte ouverte
int x = 0;
void setup()
{
  // définition des broches utilisées
  pinMode(ledbleu, OUTPUT);
  pinMode(fermeture, OUTPUT);
  digitalWrite(ledbleu, HIGH);
  digitalWrite(fermeture, HIGH);
  Serial.begin(9600); // la voie série pour monitorer
}
void loop()
{
  // conversion de cette valeur en tension
  tension = (analogRead(capteur) * 5.0) / 1024;

  if ((tension >= seuilObscurite) && !PorteFermee) //Pour FERMETURE
  {

    digitalWrite(ledbleu, LOW);             // detection seuil obscurité On allume la LED bleu
    delay(240000);                            // délai pour ne fermer porte que aprés 4 minutes ( 240 000)

    digitalWrite(fermeture, LOW);                           //  On ferme la porte apres x secondes
    digitalWrite(ledbleu, HIGH);                           // On éteint la LED bleu
    PorteFermee = true;
  }

  if ((tension < seuilLumonisite) && PorteFermee) //Pour OUVERTURE
  {

    //Serial.print(" x=  ");
    delay(240000);//délai pour ouvrir la porte que aprés 4 minutes
    digitalWrite(fermeture, HIGH); // on ouvre la porte
    PorteFermee = false;
  }

  // délai pour ne prendre des mesures que toutes les 60-secondes (60 000)
  delay(60000);

  //Serial.print(" x=  ");
  Serial.println(x);
}

Bon courage..

Bonjour, merci pour cette réponse, en effet les problèmes viennent surement de là, je vais tester et je vous tient au courant. Bonne journée.

Voilà, j'ai testé, et tout fonctionne bien , je peux régler la temporisation, comme je le voulais, merci Etibou ton code était bon dés le départ. Je pense que je vais essayer de mesurer aussi la tension du moteur pour mettre une sécurité supplémentaire en cas de blocage du moteur.

Bonjour et Bonne Année à tous,

Je poste la dernière version du code pour mon projet de porte automatique de poulailler.
Ce code est allégé et simplifié car on utilise un moteur pas à pas (28BYJ-48 5V) pour piloter la porte guillotine au lieu d’un moto-réducteur
Plus de fin de course mais un mode étalonnage pour déterminer la longueur de course de la porte.
Les heures de fermetures et d’ouverture sont toujours calculées par rapport au levé et couché du soleil.(plus de cellule photo-résistance)
Les inconvénients de ce nouveau code sont qu’il n’y a plus de détection d’anomalie de fermeture (plus de fin de course) et que l’ensemble consomme plus de courant avec le maintient sous tension du module ULN2003.

Composants nécessaires

  • Arduino uno
  • Tiny RTC
  • Moteur Pas à Pas 28BYJ-48 5V
  • Module pilotage Moteur ULN2003
  • Convertisseur DC-DC 12V-5V

A bientôt.

Poulailler_4.ino (33.3 KB)

Bonsoir, et bonne année à tous, on peu dire a mon niveau, waou ça c'est un travail approfondis, je vais maintenant essayer d'en comprendre un petit peu , bon travail superbe.

Bonjour je suis en dernière année secondaire et je compte faire votre projet en travail de fin d'étude j'aurai besoin de quelque information supplémentaire pourrions-nous parler via mail ou autre voici mon mail: norman14@live.fr

Bonjour,

Je vous ai directement répondu par mail. Aucun problème pour répondre à vos questions.

Bonjour,

c'est un super projet que tu nous présente là ! j'aimerais savoir comment l'adapter à un arduino pro mini ?

Bonjour,

Pour le code, je ne vois pas ce qui bloquerai son bon déroulement sur Arduino pro mini car le fonctionnement d'une Arduino pro mini est quasiment identique à un arduino uno sauf qu'il n'y a pas l'interface de communication USB pour la programmation et le mode débug en liaison série. Si après programmation on supprime la carte de communication pour conserver que "Arduino pro mini", il sera difficile de la mettre à l'heure ou de passer en mode debug.. Pour les projets qui n'utilisent pas d'horloge mais juste un détection de seuil lumineux l'Arduino pro mini est intéressante car une fois le programme au point, il n'y a plus besoin d'accéder à la carte. Elle est autonome. A voir...

Bonjour, je pense ajouter une gestion des heures,pour cela j'ai opté pour un rtc ic2 1307, tout se passe bien pour la lecture , sauf au niveau de ma variable "mois", il semble que cette variable ne marche pas, je voudrai le chiffre du mois en décimal. En fait comment placer et écrire les données de date et d'heures dans des variables...

exemple : si avril alors retirer 180 secondes à l'ouverture si mai alors retirer 360 secondes à l'ouverture....etc comme cela la porte s'ouvre de plus en plus tôt.

j'ai mis des //****************** (pour ce qui concerne la variable "mois" )

Bonne soirée.

#include 
#include 

RTC_DS1307 RTC; //Classe RTC_DS1307

const char ledbleu = 2; // variable broche 2 (vraie), Une LED bleu  pour détection crépuscule, s'il fait sombre
const char fermeture = 7;  // variable pour broche 7 (vraie), pour fermer porte
const char capteur = 0; // broche A0 sur laquelle va être connecté le pont diviseur de tension

float tension = 0;             // variable qui va enregistrer la tension lue en sortie du capteur
float seuilObscurite = 4.2;    // valeur en V, seuil qui détermine le niveau auquel l'obscurité est présente
float seuilLumonisite = 4;    // valeur en V, seuil qui détermine le niveau auquel la luminosité est présente
boolean PorteFermee = false;  // statut de la porte ou démarre toujours le programme porte ouverte
int mois = 4;  //********************************

void setup()
{
  // définition des broches utilisées
  pinMode(ledbleu, OUTPUT);
  pinMode(fermeture, OUTPUT);
  digitalWrite(ledbleu, HIGH);
  digitalWrite(fermeture, HIGH);
  Serial.begin(57600); // la voie série pour monitorer
  Wire.begin(); //Démarrage de la librairie wire.h
  RTC.begin(); //Démarrage de la librairie RTClib.h


  
  //Si RTC ne fonctionne pas
  if (! RTC.isrunning()) {
    Serial.println("RTC ne fonctionne pas !");
   
    //Met à l'heure à date à laquelle le sketch est compilé
    RTC.adjust(DateTime(__DATE__, __TIME__));
    //Cela fonctionne également :
    //RTC.adjust(DateTime("Dec  5 2012","12:00:00"));
    //RTC.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }
  }
void loop()
{
  //Affichage de l'heure
  DateTime now = RTC.now();
  //Serial.print(now.day(), DEC);
  //Serial.print('/');
  Serial.println(now.month(), DEC);
  
   mois == now.month();   //*******************
   Serial.println(mois);   //**********************
  Serial.print('/');
  Serial.print(now.year(), DEC); 
  Serial.println(' ');
  //Serial.print(now.hour(), DEC);
  //Serial.print(':');
  //Serial.print(now.minute(), DEC);
  //Serial.print(':');
//  Serial.print(now.second(), DEC);
 // Serial.println();
  //delay(3000);
  // conversion de cette valeur en tension
  tension = (analogRead(capteur) * 5.0) / 1024;

  if ((tension >= seuilObscurite) && !PorteFermee) //Pour FERMETURE
  {
   
    digitalWrite(ledbleu, LOW);             // detection seuil obscurité On allume la LED bleu
    delay(4000);                            // délai pour ne fermer porte que aprés 4 minutes ( 240 000) pour essais 4sec =4000

    digitalWrite(fermeture, LOW);                           //  On ferme la porte apres x secondes
    digitalWrite(ledbleu, HIGH);                           // On éteint la LED bleu
    PorteFermee = true;
    Serial.print(" PorteFermee=  ");
    Serial.println(PorteFermee);
  }

  if ((tension < seuilLumonisite) && PorteFermee) //Pour OUVERTURE   //*********************
  {
       if (mois == 4)                                                //**********************
  {
  Serial.println('avril');                                           //**********************
  delay(3);
  }
   
    delay(4000);//délai pour ouvrir la porte que aprés 4 minutes pour essais 4sec =4000
    digitalWrite(fermeture, HIGH); // on ouvre la porte
    PorteFermee = false;
    Serial.print(" PorteFermee=  ");
    Serial.println(PorteFermee);
  }

  // délai pour ne prendre des mesures que toutes les 60-secondes (60 000) cela évite les ouvertures en cas d'orage
  delay(500);// pour essais 1/2seconde=500


  //Serial.println(PorteFermee);
}

Bonjour,

Une petite erreur de syntaxe mois == now.month(); Le double "=" est un test d'égalité et non pas d'affectation. Un seul "=" est nécessaire.. Bonne journée

Bonjour, oui bien vu, j'ai changé et ça marche, j'avais aussi mis serial.print ('avril') entre simple guiements ce qui me donnais comme résultat : 26988 je ne sais pas pourquoi, peu être en hexa... merci beaucoup . Maintenant je vais ajouter des if pour une ouverture différé différente chaque mois en fonction du lever du jour.

Pourquoi je veux ça, c'est pour ouvrir le poulailler a des heures ou il y a déjà une activité dans les rues , ce qui je l’espère empêche le renard de venir....

Bonne journnée

bonjour, voilà que je bloque à nouveau, je ne comprend pas la structure des if, j'en ai placé deux pour le mois 4 et le mois 5, et apparemment contre toute attente il passe au if 5.....pourtant je suis au mois 4.

ci-dessous le code:

#include 
#include 

RTC_DS1307 RTC; //Classe RTC_DS1307

const char ledbleu = 2; // variable broche 2 (vraie), Une LED bleu  pour détection crépuscule, s'il fait sombre
const char fermeture = 7;  // variable pour broche 7 (vraie), pour fermer porte
const char capteur = 0; // broche A0 sur laquelle va être connecté le pont diviseur de tension

float tension = 0;             // variable qui va enregistrer la tension lue en sortie du capteur
float seuilObscurite = 4.2;    // valeur en V, seuil qui détermine le niveau auquel l'obscurité est présente
float seuilLumonisite = 4;    // valeur en V, seuil qui détermine le niveau auquel la luminosité est présente
boolean PorteFermee = false;  // statut de la porte ou démarre toujours le programme porte ouverte
int mois = 0;  //********************************
float xtemp = 0;

void setup()
{
  // définition des broches utilisées
  pinMode(ledbleu, OUTPUT);
  pinMode(fermeture, OUTPUT);
  digitalWrite(ledbleu, HIGH);
  digitalWrite(fermeture, HIGH);
  Serial.begin(57600); // la voie série pour monitorer
  Wire.begin(); //Démarrage de la librairie wire.h
  RTC.begin(); //Démarrage de la librairie RTClib.h


  
  //Si RTC ne fonctionne pas
  if (! RTC.isrunning()) {
    Serial.println("RTC ne fonctionne pas !");
   
    //Met à l'heure à date à laquelle le sketch est compilé
    RTC.adjust(DateTime(__DATE__, __TIME__));
    //Cela fonctionne également :
    //RTC.adjust(DateTime("Dec  5 2012","12:00:00"));
    //RTC.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }
  }
void loop()
{
  //Affichage de l'heure
  DateTime now = RTC.now();
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  
   mois = now.month(), DEC;   //*******************
   //Serial.println(mois);   //**********************
  Serial.print('/');
  Serial.print(now.year(), DEC); 
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  //delay(3000);
  // conversion de cette valeur en tension
  tension = (analogRead(capteur) * 5.0) / 1024;

  if ((tension >= seuilObscurite) && !PorteFermee) //Pour FERMETURE
  {
   
    digitalWrite(ledbleu, LOW);             // detection seuil obscurité On allume la LED bleu
    delay(4000);                            // délai pour ne fermer porte que aprés 4 minutes ( 240 000) pour essais 4sec =4000

    digitalWrite(fermeture, LOW);                           //  On ferme la porte apres x secondes
    digitalWrite(ledbleu, HIGH);                           // On éteint la LED bleu
    PorteFermee = true;
    Serial.print(" PorteFermee=  ");
    Serial.println(PorteFermee);
  }

  if ((tension < seuilLumonisite) && PorteFermee) //Pour OUVERTURE   //*********************
  {
       if (mois = 4)                                                
  {                            
    xtemp = 40000;
  Serial.print(" avril = ");                                         
  Serial.println(mois);
Serial.print("xtemp = ");
Serial.println(xtemp);
                         
  }
         if (mois = 5)                                                
  {                       
    xtemp = 8000;
  Serial.print(" mai = ");                                         
  Serial.println(mois);
Serial.print("xtemp = ");
Serial.println(xtemp);
  }                   
   
    delay(xtemp);//délai pour ouvrir la porte que aprés xtemp secondes, pour essais 4sec =4000
    digitalWrite(fermeture, HIGH); // on ouvre la porte
    PorteFermee = false;
    Serial.print(" PorteFermee=  ");
    Serial.println(PorteFermee);
  }

  // délai pour ne prendre des mesures que toutes les 60-secondes (60 000) cela évite les ouvertures en cas d'orage
  delay(500);// pour essais 1/2seconde=500


  //Serial.println(PorteFermee);
}

bonsoir, autant pour moi ,j'ai fait la même erreur dans l'autre sens, pas mis == ,maintenant mes if fonctionnent tous correctement..

Bonsoir, Félicitations pour ce super et gros travail, bravo.

une suggestion, pour le problème de courant au repos du moteur pas à pas, j'ai fait des essais en mettant à 0 les 4 broches : digitalWrite(8,0); digitalWrite(9,0); digitalWrite(10,0); digitalWrite(11,0) , après une toute petite tempo pour être sûr que le moteur est arrêté, et ça fonctionne ! Je ne sais pas si ça pourrait être applicable à ton code.

autre question, serait-il possible d'utiliser le RTC DS1302 à la place du 1307 ? Merci

Bonjour, je suppose que pour le 1302 à la place du 1307, c'est oui, le 1302 est plus précis dérive -+ 2min par ans ,contre -+ 2 minutes par mois pour 1307..

La précision d'un DS1302 ou d'un DS1307 dépend totalement de son quartz. Si le module possède un quartz de piètre qualité, il dérivera plus. Et comme le montage n'est pas dans un local à température constante ...

Un DS3231 par contre a un oscillateur interne compensé en température.

Accuracy ±2ppm from 0°C to +40°C

Bonjour,

Effectivement les DS1302 / DS1307 dérivent dans le temps mais comme les poules n’ont pas de montre, une mise à l’heure tous les 6 mois est suffisant.
Pour couper l’alimentation sur un moteur pas à pas lors de la phase de repos, il faut être certain qu’il n’y a pas de glissement sinon, on perd le référentiel.
Si besoin, je pourrai poster une nouvelle version qui corrige quelques petits soucis…
A+