Trappe automatique de poulailler avec arduino pro mini

Pour mon premier montage Arduino, j'ai choisi utile pour protéger mes poules des prédateurs founine, renard ou autre opportuniste genre rat qui viendrait les traumatiser. Le montage fonctionne sans problème depuis mai 2015, avec quelques améliorations depuis, il est, je pense, maintenant au point. n'hésitez pas à apporter vos critiques ou réalisations.

schéma ( version à détection par photorésistance )
schéma

Petite vidéo lors des tests avec arrêt sur blocage moteur et Arduino Nano
Vidéo test

Après cela, l'Arduino Nano a été remplacé par un Pro mini pour consommation en veille 0.4 mA.

La batterie de 6 V 2 Ah nécessitait d'être rechargée chaque semaine et maintenant tiens 5 semaines.

Je ne la recharge désormais plus, le panneau solaire s'en charge.

Version de Totopoyo

Fonctionnement :

La tension aux bornes du panneau solaire donne le niveau de luminosité au microprocesseur(µp). Au seuil "nuit", la trappe se ferme environ 1/2 heure après l'heure normale ou les poules rentrent. Quand la trappe est fermée, le moteur se bloque. Son courant est limité par une résistance de 10 ohm, qui en même temps indique au µp le blocage. Au bout du délai programmé, le moteur s'arrête. Le µp entre en mode veille, se réveille toutes les 8 secondes et attends le seuil jour. A l'aube, l'ouverture se fait au bout de 15 périodes de veille, environ 2 minutes, qu'on peut augmenter avec la variable "nbCycle" si des éclairages artificiels intempestifs risquaient de déclencher l'ouverture prématurément. Une butée bloque la trappe une fois ouverte. Si la tension de batterie descends en dessous de 5,5 V, la LED du module pro mini flashe toutes les 8 secondes.

Le système fonctionne avec une batterie de 6 V NIMH. Il consomme 10 mAh par jour. Tous les paramètres sont modifiables par programmation.

Un panneau solaire 6 V 2 W a été ajouté pour recharger la batterie. Avec le peu de consommaton du montage,un éclairage led pourra aussi être alimenté.

Une diode schottky évite que la batterie ne se décharge quand sa tension est supérieure à celle du panneau. Une résistance de 100 ohm limite le courant, surtout en fin de charge

Liste des pièces :

Circuit monté avec Pro Mini et panneau solaire :
La carte montée

La photorésistance sort à l'extérieur dirigée vers l'ouest au soleil couchant.
La ldr à l'extérieur

Fabrication de la partie mécanique :

J'ai des Marans, ce sont des petites poules. Le trou dans la paroi fait L = 20 cm; h = 25 cm, la trappe 22 X 30 en plastique de 3 mm d'épaisseur taillé dans ce qui devait être un panneau publicitaire. Du contreplaqué de 5 mm ou même une tôle galva doit convenir. Un surpoids peut être résolu par un contrepoids sur une poulie ou au bout d'un bras levier.

Nouvelle trappe en tôle galva, plus solide avec butée en bas et arrondie pour ne pas blesser. poids = 300gr, pas en besoin de contrepoids

Trappe à l'intérieur Trappe à l'extérieur
Elle n'a pas voulu prendre la pose :(

Pour verrouiller la porte, il fallait un entrainement rigide en fermeture.

Un tube métallique de 8 mm de diamètrer adapte la vitesse de rotation du moteur, environ 150 tr/mn à la force nécessaire pour déplacer la trappe. Le côté moteur est pincé à l'étau pour s'adapter à l'embout de l'axe du moteur. L'autre extrémité s'adapte à un roulement à bille incrustré dans un flasque récupéré sur un moteur Hs. Le tube est percé de deux trous pour fixer la ficelle par des noeuds à l'interrieur du tube.

La ficelle tourne autour d'une poulie 35 cm plus bas et le ressort (2 ensembles pour plus de force) la maintien tendue. Le domino sert à relier la ficelle à une tige d'acier rigide qui entraine la trappe.

detail du mécanisme

En descente, le moteur est bloqué par une butée plus basse que le bas du trou, empêchant les éventuels prédateurs d'avoir prise pour la soulever.
J'ai ajouté une vis pour la butée haute stoppant l'ouverture.

detail du  haut de la trappe

Pour le protéger et voir un éventuel défaut, le système est entouré d'un cadre en bois de palette et recouvert d'un plexiglass.

Programmation :

Pour cela, il faut :

Diagramme du programme :

Détail de mon programme :

Rien de secret, vous pouvez le modifier à votre guise.(télécharger pour avoir le programme complet)

/* Trappe automatique poulallier avec Arduino Pro Mini

Arret sur blocage moteur sans contacts de fin de course. Panneau solaire pour la
recharge de la batterie.
Si la batterie est faible, la led du circuit s'allume 300 ms toutes les 8 secondes.
*/
#include 
#include 
#include 
volatile int f_wdt = 1;

/* declaration des constantes pour les noms des broches */
const int led = 13; // led du module nano
const int pinmoteur = A2; // mesure courant moteur
const int fermer = 2; // commande de fermeture
const int ouvrir = 3; // commande d'ouverture
const int bat = A1; // surveillance tension batterie
const int pinpanneau = A0; // surveillance tension panneau

/* declaration des variables */
int niveau_bat;//
int nuit = 20; // seuil nuit
int jour = 185;  // seuil jour
int panneau; // luminosité panneau
int courant_moteur;
int retard = 0; // évite de déclencher sur variation de luminosité brève
int nbCycle = 15; // retard à l'ouverture X 8 secondes(2 mn pour 15)
boolean trappe; // état trappe
boolean rotation = 0; //  moteur arrêté
unsigned long debut_blocage; // début du blocage
int mem_courant; // courant moteur au début du blocage
int delai_blocage = 100;

void setup() {
  // initialisation des broches entree/sortie
  pinMode(pinpanneau, INPUT);
  pinMode(bat, INPUT);
  pinMode(fermer, OUTPUT);
  pinMode(ouvrir, OUTPUT);
  pinMode(pinmoteur, INPUT);
  pinMode(led, OUTPUT);

  panneau = analogRead(pinpanneau);
  // Pour forcer la trappe à se fermer la nuit ou à s'ouvrir le jour.
  if (panneau > nuit) {//jour
    trappe = 1; // fermée
  }
  if (panneau < nuit) {
    trappe = 0; // ouverte
  }
  // active le compteur watchdog pour interruption toutes les 8 secondes
  setup_watchdog(9);
}

void loop() {
 // LDR = analogRead(pinldr);
  panneau = analogRead(pinpanneau);
  niveau_bat = analogRead(bat);

  switch (rotation) {

    case 0 : // moteur arrêté
      if (panneau > jour) { // jour
        switch (trappe) {
          case 0 : sommeil(); break;
          case 1 : retard++; ouverture(); break; // pas ouverte
        }
      }//jour
      if (panneau < jour) {
        retard = 0; // éclairage momentané
      }
      if (panneau < nuit) {
        switch (trappe) {
          case 1 : sommeil(); break; // fermée
          case 0 : fermeture(); break;
        }
      }; break;

    case 1 : // moteur tourne
      courant_moteur = analogRead(pinmoteur);
      if (courant_moteur != mem_courant) { // normal
        // sauve le courant moteur et debute le comptage
        mem_courant = courant_moteur;
        debut_blocage = millis();
      }
      // arret moteur si courant moteur invariable depuis delai_blocage
      if (courant_moteur == mem_courant) { // bloqué
        if ((millis() - debut_blocage) > delai_blocage) {
          // bloqué et délai dépassé
          stop();
        }
      }; break;

  }// fin switch rotation
}// fin de loop()


// Watchdog Interrupt Service est excite lors d'un timeout du WDT
ISR(WDT_vect)
{
  if (f_wdt == 0)
  {
    f_wdt = 1; // flag global }
  }
}

void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii = 9;   // pour 8 secondes
  bb = ii & 7;
  if (ii > 7) bb |= (1 << 5);
  bb |= (1 << WDCE);
  ww = bb;
  // Clear the reset flag
  MCUSR &= ~(1 << WDRF);
  // start timed sequence
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}

// active la mise en veille pour 8 secondes
void sommeil(void) {
  // témoin led si la tension de batterie < 6 V
  if (niveau_bat < 565) { // 5.6 V
    digitalWrite(led, 1); delay(300); digitalWrite(led, 0);
  }
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode(); //Entre dans le mode veille choisi
  //le micro passe en sommeil pour 8 secondes
  sleep_disable();
  // Le programme va reprendre ici après le timeout du WDT
}

void ouverture() {
  if (retard > nbCycle) { // environ 2 minutes
    digitalWrite(ouvrir, 1); digitalWrite(fermer, 0); rotation = 1; retard = 0;
  }
  else {
    sommeil();
  }
};

void fermeture() {
  digitalWrite(ouvrir, 0); digitalWrite(fermer, 1); rotation = 1;
};

void stop() {
  digitalWrite(ouvrir, 0); digitalWrite(fermer, 0);
  trappe = !trappe; rotation = 0; sommeil();
};