Go Down

Topic: Porte automatique pour poulailler (Read 55195 times) previous topic - next topic

philippe6philoux

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

Code: [Select]
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);
}

etibou

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é)
Code: [Select]

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..

philippe6philoux

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.

philippe6philoux

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.

etibou

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.

philippe6philoux

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.

norman46

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

etibou

Bonjour,

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

mattymatt

Bonjour,

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

etibou

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...




philippe6philoux

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.


Code: [Select]
#include <RTClib.h>
#include <Wire.h>

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);
}

  

etibou

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

philippe6philoux

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

philippe6philoux

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:
Code: [Select]
#include <RTClib.h>
#include <Wire.h>

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);
}

philippe6philoux

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

Go Up