Poulailler avec servo Moteur

Bonjour,
il y a deux mois j’ai fabriqué une porte coulissante façon « guillotine » pour mon poulailler. Le but c’était d’utiliser le plus possible le matériel déjà en ma possession. Je me suis inspiré de plusieurs projets vus sur le net et j’ai créé le mien, bien entendu sans prétention aucune (car plutôt bricoleur du dimanche, pour le code aussi). J’ai utilisé un servo moteur 360 degrés connecté à deux poulies. Un capteur de lumière donne la commande pour la fermeture et l’ouverture. Afin d’arrêter le servo moteur au bon moment, j’ai rajouté deux fins de course. Le système marche, mais parfois, lors de la fermeture, la porte ne touche pas le fin de course en bas. Cela à cause soit d’une poule (conne) qui traine devant la porte, soit de la paille qui se déplace, un grand :poop: bien pile à l’entrée … Donc le moteur continue à tourner, mais se s’arrêtant pas, il embobine le câble dans le sens inverse, donc la porte remonte (mais l’Arduino pense qu’il est en train toujours de la baisser). Ne trouvant pas le fin de course, la porte reste coincée et le moteur se bloque à cause de la force contraire (et heureusement ne grille pas). Le moteur est alimenté par une alimentation 5V externe et l’Arduino Nano par 12V. Pour résoudre ce problème j’ai essayé d’imaginer de coupler une temporalité au fin de course, c’est à dire que si après un certain temps le fin de course n’est pas trouvé, le moteur s’arrête quand même.
Voici déjà mon code à ce jour:


#include <Servo.h>
int Val_Photo ;  //Lecture valeurs capteur lumière
int photo = A0; // PIN capteur lumière
int Val_luce = 30; // Valeur  luminosité


const int Fin_Course_Bas = 4;     // Numéro de la broche à laquelle est connecté le fin de course
const int Fin_Course_Haut = 5;  // Numéro de la broche à laquelle est connecté le fin de coursE

Servo myservo;  

void setup() {
  
  pinMode(Fin_Course_Bas, INPUT);
  pinMode(Fin_Course_Haut, INPUT);

  myservo.attach(9);  
  
  Serial.begin (9600); // initaialisation port série

}

void Montee (){
  while ( digitalRead (Fin_Course_Haut) == HIGH) {
  myservo.write(180);  
    delay(15); 
  }
}

void Descente (){
 
  
  while ( digitalRead (Fin_Course_Bas) == HIGH ) {
  myservo.write(0); 
    delay(15);  
  }
}
void OFF (){
   myservo.write (90); 
     delay(15);  
     
}
      


void loop() {
  
  
  Val_Photo = analogRead (photo); // valeur capteur lumière
  Serial.print("Val_Photo");
  Serial.println(Val_Photo);
  

  if (Val_Photo > Val_luce) {
    {
      Montee();
    }
    if( digitalRead (Fin_Course_Haut) == LOW)
    {
      OFF();
   }
}

  if (Val_Photo < Val_luce) {
  {
     Descente();
   
     if( digitalRead (Fin_Course_Bas) == LOW)
    {
      OFF();
    }
     
  }     
   }
  
  
delay (60000);

}




Est-ce que je dois travailler plutôt dans le while du Void Descente en rajoutant un « or » ?

Merci d’avance de vos retours.

Claudio

Moi je mettrais un or dans ce if.
Lorsque tu lances la descente tu initialises un chrono (en variable globale c'est le plus simple)

chrono = millis();
Juste avant l'appel de la fonction descente

Et dans ton test tu ajoutes

|| (millis()-chrono>dureemax)

Et tu définis dureemax pour la durée de descente maximale en millisecondes.

Bonsoir Lesept,
et merci beaucoup pour la réponse !
Comme je disais je suis un "codeur" du dimanche ...
J'imagine que je dois me tromper quelque part:


#include <Servo.h>
int Val_Photo ;  //Lecture valeurs capteur lumière
int photo = A0; // PIN capteur lumière
int Val_luce = 950; // Valeur  luminosité
int dureemax = 2000; // temps de descente


const int Fin_Course_Bas = 4;     // Numéro de la broche à laquelle est connecté le fin de course
const int Fin_Course_Haut = 5;  // Numéro de la broche à laquelle est connecté le fin de coursE

Servo myservo;  

void setup() {
  
  pinMode(Fin_Course_Bas, INPUT);
  pinMode(Fin_Course_Haut, INPUT);

  myservo.attach(9);  
  
  Serial.begin (9600); // initaialisation port série

}

void Montee (){
  while ( digitalRead (Fin_Course_Haut) == HIGH) {
  myservo.write(180);  
    delay(15); 
  }
}

void Descente (){
 
  
  while ( digitalRead (Fin_Course_Bas) == HIGH ) {
  myservo.write(0); 
    delay(15);  
  }
}
void OFF (){
   myservo.write (90); 
     delay(15);  
     
}
      


void loop() {
  
  
  Val_Photo = analogRead (photo); // valeur capteur lumière
  Serial.print("Val_Photo");
  Serial.println(Val_Photo);
  

  if (Val_Photo > Val_luce) {
    {
      Montee();
    }
    if( digitalRead (Fin_Course_Haut) == LOW)
    {
      OFF();
   }
}

  if (Val_Photo < Val_luce) {
     int chrono = millis();
  {
     Descente();
   
     if( digitalRead (Fin_Course_Bas) == LOW || (millis()-chrono>dureemax))
    {
      OFF();
    }
     
  }     
   }
  
  
delay (60000);

}

Merci pour ta patience :expressionless: 



Un servo 180° avec un bras de levier aurai été plus adapté, et les FDC seraient inutiles.

... surement, mais le but c'était, comme j'ai expliqué, d'utiliser du matériel déjà à disposition.
Par contre ça ne résolue pas mon problème ... :expressionless:
Après conseil de lesept j'ai modifié mon code, mais ça ne marche toujours pas. Je poste mon dernier code ici:


#include <Servo.h>
int Val_Photo ;  //Lecture valeurs capteur lumière
int photo = A0; // PIN capteur lumière
int Val_luce = 950; // Valeur  luminosité
int dureemax = 2000; // temps de descente


const int Fin_Course_Bas = 4;     // Numéro de la broche à laquelle est connecté le fin de course
const int Fin_Course_Haut = 5;  // Numéro de la broche à laquelle est connecté le fin de coursE

Servo myservo;  

void setup() {
  
  pinMode(Fin_Course_Bas, INPUT);
  pinMode(Fin_Course_Haut, INPUT);

  myservo.attach(9);  
  
  Serial.begin (9600); // initaialisation port série

}

void Montee (){
  while ( digitalRead (Fin_Course_Haut) == HIGH) {
  myservo.write(180);  
    delay(15); 
  }
}

void Descente (){
 
  
  while ( digitalRead (Fin_Course_Bas) == HIGH ) {
  myservo.write(0); 
    delay(15);  
  }
}
void OFF (){
   myservo.write (90); 
     delay(15);  
     
}
      


void loop() {
  
  
  Val_Photo = analogRead (photo); // valeur capteur lumière
  Serial.print("Val_Photo");
  Serial.println(Val_Photo);
  

  if (Val_Photo > Val_luce) {
    {
      Montee();
    }
    if( digitalRead (Fin_Course_Haut) == LOW)
    {
      OFF();
   }
}

  if (Val_Photo < Val_luce) {
     int chrono = millis();
  {
     Descente();
   
     if( digitalRead (Fin_Course_Bas) == LOW || (millis()-chrono>dureemax))
    {
      OFF();
    }
     
  }     
   }
  
  
delay (60000);

}




Où je me trompe ... ?
Merci pour votre patience.

Claudio

Bonjour Vinchiappetto

Je tournerai Montee () Descente() ainsi:


void Montee (){
	myservo.write(180);     // Servo dans le sens montée
	while ( digitalRead (Fin_Course_Haut) == HIGH) {
	}
	OFF ();
}

void Descente (){
	
	myservo.write(0);     // Servo dans le sens descente	
	while ( digitalRead (Fin_Course_Bas) == HIGH ) {
	}
	OFF ();
}

Je n'ai pas essayé "en vrai" mais s'il faut, j'ai le nécessaire.

Cordialement
jpbbricole

Bonjour Jpbbricole,
merci pour ta réponse.
Mais le problème c'est plutôt de rajouter une temporalité au cas où le fin de course n'est pas enclenché à la descente. J'ai bien eu une piste par lesept, mais ça ne marche pas.
:face_with_raised_eyebrow:

Parfois il faut savoir investir quelques euros plutôt que de s'engager dans une voie logicielle sans issue.
Il y a de multiples problèmes :

  • servo 360° : équivalent à un moteur continu. Pas de contrôle de position.
  • ficelle : la porte n'est pas plaquée au sol. Un prédateur rusé pourra la soulever.

Bonjour Vinchiappetto

Peut-être mettre le fin de course sur la tension du fil de levage, quand détendu, arrivé en bas ou sur une poule ou sur un grand :poop: bien pile à l’entrée.

Cordialement
jpbbricole

Bien entendu tu as raison hbachetti, mais c'était le principe de récupération qui a été mis en avant. Le poulailler a été construit aussi avec de la récupération. Il est installé dans un enclos et j'ai un chien dans le terrain, donc pas trop de chance que les poules soient attaquées. Mais c'est le code qui me perturbe: normalement ça devrait être facile de rajouter une temporalité couplée au fin de course, mais je n'y arrive pas. Des idées ... ?

Bonjour Vinchiappetto

Doubler un fin de course d'une temporisation, cela veut dire que l'on sait au bout de combien de temps on estime que le fin de course (FDC) "n'a pas fait son travail".
A ce moment, pourquoi ne pas supprimer le FDC et envoyer l'ordre de descente le temps nécessaire à la fermeture, le fil risque, au pire, d'être détendu?
Ou se baser uniquement sur la tension du fil.
Avec la surveillance du fil, si un obstacle temporaire, comme une poule, disparaît, le tension reviendrait et on pourrait continuer le processus de fermeture.

Cordialement
jpbbricole

Quand on utilise millis() ou micros(), il faut déclarer des variables unsigned long :
unsigned long chrono = millis();

Ca donnerait ça :

  if (Val_Photo < Val_luce) {
    unsigned long chrono = millis();
    Descente();

    if ((digitalRead (Fin_Course_Bas) == LOW) || (millis() - chrono > dureemax)) OFF();
  }

Il faut expliquer ce qui ne marche pas, j'ai un peu de mal à voir d'ici... Que se passe t-il ou t-il pas ?

Effectivement je trouve plus censé d'agir de telle façon. Mais vu que le FDC est déjà installé, pourquoi m'en priver ? C'est juste une question de sécurité (ça plante environs 1 fois sur 10) Merci beaucoup !

Merci beaucoup lesept. Demain je vais changer cela dans mon code et je vais tester. J'ai appris des nouvelles choses ...

Le plantage est donc fréquent. Les FDC sont probablement mal placés.
D'autre part, en extérieur les FDC classiques et bon marché, non étanches, peuvent poser des problèmes à plus ou moins long terme.
Pour ma part j'utilise des ampoules REED :

Bonjour Vinchiappetto

C'est quel type de FDC, si c'est un mécanique du genre
image
Pourquoi ne pas le déplacer sur le chemin du fil de façon que, le fil tendu, donc porte pendue, il soit "fermé"?

Cordialement
jpbbricole