/* 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. Moteur de faible puissance bloqué par une faible résistance mécanique. La trappe s'ouvre au seuil "jour". Elle se ferme au seuil "nuit", environ 1/2 heure après que les poules soient rentrées. - Pour économiser la batterie, le circuit est mis en veille le reste du temps sauf pendant la rotation du moteur. Consommation 0.5 mA en veille et 200 mA environ pendant les 2 fois 15 secondes de fonctionnement moteur journalier. La led power est coupée (coupure de la piste du circuit imprimé) - l'ouverture ou la fermeture n'est tentée qu'une fois. si blocage anormal du moteur, la trappe restera bloquée en position intermédiaire jusqu'à réparation sans surconsommation(vérifier à chaque visite). Plage de fonctionnement correct 5.5 V à 7.1 V (6.8 V avec panneau solaire) 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 pinldr = A3; // photorésistance 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 /* declaration des variables */ int niveau_bat;// int nuit = 980; // seuil nuit int jour = 250; // seuil jour int LDR; // mesure inverse de luminosité int courant_moteur; int retard = 0; // évite de déclencher sur variation de luminosité brève boolean trappe; // état trappe boolean rotation = 0; // moteur arrêté unsigned long debut_blocage; // début du blocage unsigned long retard_dec; // déclenchement jour int delai_dec; int mem_courant; // courant moteur au début du blocage int delai_blocage = 100; void setup() { // initialisation des broches entree/sortie pinMode(pinldr, INPUT); pinMode(bat, INPUT); pinMode(fermer, OUTPUT); pinMode(ouvrir, OUTPUT); pinMode(pinmoteur, INPUT); pinMode(led, OUTPUT); LDR = analogRead(pinldr); // Pour forcer la trappe à se fermer la nuit ou à s'ouvrir le jour. if (LDR < nuit) { trappe = 1; // fermée } if (LDR > nuit) { trappe = 0; // ouverte } // active le compteur watchdog pour interruption toutes les 8 secondes setup_watchdog(9); } void loop() { LDR = analogRead(pinldr); niveau_bat = analogRead(bat); switch (rotation) { case 0 : // moteur arrêté if (LDR < jour) { // jour switch (trappe) { case 0 : sommeil(); break; case 1 : retard++; ouverture(); break; // pas ouverte } }//jour if (LDR > jour) { retard = 0; // lampe de poche ou pas complètement jour } if (LDR > 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 > 15) { // 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(); };