Comment appliquer la mise en veille Arduino nano [Résolution en cours]

Bonjour,
Je débute et j’ai entrepris la fabrication d’une trappe automatique de poulailler.
Elle fonctionne très bien mais sur batterie, je voudrais réduire la consommation mesurée à 24 mA au repos, vu que le fonctionnement se résume à 10 secondes par jour.

Mon premier problème est la compréhension limitée de l’anglais.

Je voudrais implémenté le code le plus simple possible.
J’ai essayé la librairie Adafruit_SleepyDog.h, mais je n’en comprends pas le fonctionnement.

Sinon, sans librairie supplémentaire, j’ai trouvé cette page

En résumé peut-on m’aider à implémenter le bon code au bon endroit ?

/* inclus la librairie economiseur de batterie. */
//#include <Adafruit_SleepyDog.h>

/* Trappe automatique poulallier en fonction des seuils de lumière jour et nuit.
-  ouverture et fermeture sur seuil de lumière.
- arrêt moteur par contact fin de course.
- arrêt moteur au bout de 8 secondes si le temps normal de 5 secondes dépassé, en cas de mécanique ou contact défectueux. 
 */

/* déclaration des constantes pour les noms des broches */
const int led = 13; // led du module nano
const int ldr = A7; // LDR sur broche A7
const int moteur = A6; // mesure courant moteur
const int fermer = 2; // commande relais de fermeture
const int ouvrir = 3; // commande relais d'ouverture
const int  haut = 4; // fin de course 
const int bas = 5; // fin de course

/* déclaration des variables */
int nuit = 900; // seuil nuit
int jour = 80;  // seuil jour
unsigned long debut=0; // temps début de rotation

void setup() {
  // initialisation des broches entrée/sortie
 pinMode(ldr, INPUT);
 pinMode(fermer, OUTPUT);
 pinMode(ouvrir, OUTPUT);
 pinMode(haut, INPUT_PULLUP);
 pinMode(bas, INPUT_PULLUP);
}

void loop() {
//lecture de l'état des entrées
int ouvert = digitalRead(haut); // 1 au repos
int ferme = digitalRead(bas);
int seuil = analogRead(ldr);
// Serial.begin(9600);
// Serial.println(blocage);
// mode économiseur activé
//int sleepMS = Watchdog.sleep();

// action 
 //Il fait jour et la trappe est fermé déclenche l'ouverture et compte le temps.  
 if(seuil < jour && ferme == 0){digitalWrite(ouvrir, 1);debut=millis();};
 // arrêt forcé du moteur si son temps de fonctionnement est supérieur au temps normal.
 if(millis() - debut > 8000){digitalWrite(ouvrir, 0);digitalWrite(fermer, 0);}; 
 // arrêt moteur quand la trappe est ouverte
 if(ouvert == 0){digitalWrite(ouvrir, 0);};
 // Il fait nuit et la trappe est ouverte déclenche la fermeture et le compteur de temps moteur
 if(seuil > nuit && ouvert == 0){digitalWrite(fermer, 1);debut = millis();}
 if(ferme == 0){digitalWrite(fermer, 0);};
 delay(10);
}

une piste

//Optimisation de la consommation

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;
unsigned long tempo_desiree = 32; // mettre un multiple de 8, mais pas obligatoire
unsigned long compteur_reveil = 0;
unsigned long compteur_travail=0;
unsigned long debut_travail=0;
unsigned long fin_travail =0;
unsigned long total_travail=0;
// Watchdog Interrupt Service est exécité lors d'un timeout du WDT
ISR(WDT_vect)
{
  if (f_wdt == 0)
  {
    f_wdt = 1; // flag global }
  }
}
// paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii = 9;
  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);
}

void enterSleep(void) {
  Serial.print(".....zzzzzzzzzzzzzz  ");
  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
  // Le programme va reprendre ici après le timeout du WDT
  sleep_disable(); // La 1ère chose à faire est de désactiver le mode veille
  Serial.println("..............fin sommeil ");
}

//************* SETUP *************
void setup() {
  //Optimisation de la consommation
  //power_adc_disable(); // Convertisseur Analog / Digital pour les entrées analogiques
  //power_spi_disable();
  //power_twi_disable();
  // Si pas besoin de communiquer par l'usb
  //power_usart0_disable();
  //Extinction des timers, attention timer0 utilisé par millis ou delay
  //power_timer0_disable();
  //power_timer1_disable();
  //power_timer2_disable();

  setup_watchdog(9);
  Serial.begin(57600);
}

//************* LOOP *************

void loop()
{ debut_travail =  millis();
  if (f_wdt == 1)
  {
     compteur_reveil++;
    // Effectuer le programme ici si sommeil demandé = 8 secondes
       Serial.print("reveil pour la  ");
       Serial.print(compteur_reveil,DEC);
       if (compteur_reveil==1){Serial.println(" ere fois");}
       else {Serial.println(" eme fois");}
   // fin des mesures ici si sommeil = 8 secondes
    if ((compteur_reveil*8)>= tempo_desiree)
    {
      compteur_travail++;
    // Effectuer le programme ici si sommeil demandé >8 secondes
       Serial.print("travail car il y a eu  ");
       Serial.print((compteur_reveil*8),DEC);
       Serial.println(" secondes de sommeil ");
       Serial.print("il y a ");
       Serial.print((compteur_travail*32),DEC);
       Serial.println(" secondes de fonctionnement ");
    // fin des mesures ici si sommeil >8 secondes
    compteur_reveil = 0;
    }
    
    fin_travail=millis();
    total_travail=total_travail +(fin_travail-debut_travail);
    Serial.print("temps total de travail =  ");
    Serial.print(total_travail);Serial.println("  ms  ");
    delay(2000); //pour laisser le temps aux "serial.print" de se fairent
    f_wdt = 0; // Ne pas oublier d'initialiser le flag, sinon pas de sommeil
    enterSleep(); //Revenir en mode veille
  }
}

Bonjour, Pour la mise en veille, fait une recherche sur le forum, le sujet a fait l'objet de nombreux posts.

j’ai adapté à ton code
réveil toutes les 8 secondes pendant 1ms
le prog regarde si cela fait 15mn de sommeil si non: refermes ses yeux
si oui: exécute ta boucle 1 fois puis retourne dormir pour 15mn

en test chez moi ( au moniteur,… je n’ai pas de poules)

/* inclus la librairie economiseur de batterie. */
//#include <Adafruit_SleepyDog.h>

//****************************************************************************
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;              
unsigned long tempo_desiree =900; // 15mn=900 secondes
unsigned long compteur_reveil = 0;
unsigned long compteur_travail=0;
unsigned long debut_travail=0;
unsigned long fin_travail =0;
unsigned long total_travail=0;
//****************************************************************************

/* Trappe automatique poulallier en fonction des seuils de lumière jour et nuit.
-  ouverture et fermeture sur seuil de lumière.
- arrêt moteur par contact fin de course.
- arrêt moteur au bout de 8 secondes si le temps normal de 5 secondes dépassé, 
en cas de mécanique ou contact défectueux. 
 */

/* déclaration des constantes pour les noms des broches */
const int led = 13; // led du module nano
const int ldr = A7; // LDR sur broche A7
const int moteur = A6; // mesure courant moteur
const int fermer = 2; // commande relais de fermeture
const int ouvrir = 3; // commande relais d'ouverture
const int  haut = 4; // fin de course 
const int bas = 5; // fin de course

/* déclaration des variables */
int nuit = 900; // seuil nuit
int jour = 80;  // seuil jour
unsigned long debut=0; // temps début de rotation

void setup() {
  // initialisation des broches entrée/sortie
 pinMode(ldr, INPUT);
 pinMode(fermer, OUTPUT);
 pinMode(ouvrir, OUTPUT);
 pinMode(haut, INPUT_PULLUP);
 pinMode(bas, INPUT_PULLUP);
 //****************************************************************************
 setup_watchdog(9);
 Serial.begin(57600);
 //****************************************************************************
}

void loop()
{
  //****************************************************************************
  debut_travail =  millis();
  if (f_wdt == 1)
  {
    compteur_reveil++;
       Serial.print("reveil pour la  ");
       Serial.print(compteur_reveil,DEC);
       if (compteur_reveil==1){Serial.println(" ere fois");}
       else {Serial.println(" eme fois");}
       //ici, on peut mettre le prog si le temps de sommeil 
       //est de 8 secondes.et virer le if ((compteur_reveil*8)>= tempo_desiree)
       //mais si le temps désiré est > 8secondes, on entre dans 
       //le if ((compteur_reveil*8)>= tempo_desiree)
    if ((compteur_reveil*8)>= tempo_desiree)
    {
      compteur_travail++;
  delay(2000); //le temps de boire un café et d'etre opérationnel
  //****************************************************************************    
//lecture de l'état des entrées
int ouvert = digitalRead(haut); // 1 au repos
int ferme = digitalRead(bas);
int seuil = analogRead(ldr);
// action 
 //Il fait jour et la trappe est fermé déclenche l'ouverture et compte le temps.  
 if(seuil < jour && ferme == 0){digitalWrite(ouvrir, 1);debut=millis();};
 // arrêt forcé du moteur si son temps de fonctionnement est supérieur au temps normal.
 if(millis() - debut > 8000){digitalWrite(ouvrir, 0);digitalWrite(fermer, 0);}; 
 // arrêt moteur quand la trappe est ouverte
 if(ouvert == 0){digitalWrite(ouvrir, 0);};
 // Il fait nuit et la trappe est ouverte déclenche la fermeture et le compteur de temps moteur
 if(seuil > nuit && ouvert == 0){digitalWrite(fermer, 1);debut = millis();}
 if(ferme == 0){digitalWrite(fermer, 0);};
 delay(10);
 //****************************************************************************    
       Serial.print("travail car il y a eu  ");
       Serial.print((compteur_reveil*8),DEC);
       Serial.println(" secondes de sommeil ");
       Serial.print("il y a ");
       Serial.print((compteur_travail*32),DEC);
       Serial.println(" secondes de fonctionnement ");
    // fin des mesures ici si sommeil >8 secondes
    compteur_reveil = 0;
 }
    fin_travail=millis();
    total_travail=total_travail +(fin_travail-debut_travail);
    Serial.print("temps total de travail =  ");
    Serial.print(total_travail);Serial.println("  ms  ");
    delay(2000); //pour laisser le temps aux "serial.print" de se fairent
    f_wdt = 0; // Ne pas oublier d'initialiser le flag, sinon pas de sommeil
    enterSleep(); //Revenir en mode veille
 //****************************************************************************
 }
}
// Watchdog Interrupt Service est exécité lors d'un timeout du WDT
ISR(WDT_vect)
{
  if (f_wdt == 0)
  {
    f_wdt = 1; // flag global }
  }
}
// paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 
//           : 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
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);
}

void enterSleep(void) {
  Serial.print(".....zzzzzzzzzzzzzz  ");
  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
  // Le programme va reprendre ici après le timeout du WDT
  sleep_disable(); // La 1ère chose à faire est de désactiver le mode veille
  Serial.println("..............fin sommeil ");
}

Bonjour et merci pour vos réponses,

Avant ma question, j'avais fait le tour du sujet sur le forum sans trouver de vrai réponse simple.

Merci djgh pour la proposition, je vais étudier ça, mais ou trouver ces librairies avr/sleep.h, avr/power.h et avr/wdt.h. ?? Je ne les trouve pas depuis le logiciel (manage libraries ...), ni sur le net ... Pour sleep.h http://www.nongnu.org/avr-libc/user-manual/sleep_8h.html, je ne vois pas ou il faut télécharger.

De plus, n'y a t'il pas une solution plus directe pour le ATmega328P que de passer par 3 librairies ?

Je me doute que ça fait prétentieux pour un débutant de poser ce genre de question, je compte sur votre indulgence.

Cordialement

:)

Il n'y a rien à charger. Ces librairies sont installées avec la chaîne de compilation. Ce sont des librairies "standards".

Chaque librairie gère une fonction particulière du processeur:

  • avr/sleep.h: la mise en sommeil
  • avr/power.h: l'alimentation
  • avr/wdt.h: le watchdog La combinaison des trois permet d'assurer la fonction demandée.

le micro dort 8 secondes et le prg compte le nombre de fois 8 secondes que tu veux. temps désiré en unsigned long te permet de mettre ......................beaucoup.

j'ai mis 900 pour 15mn histoire de ne pas louper le changement de luminosité, mais tu es libre de le réveiller toutes les demi heure(1800) ou toutes les heures(3600) ou ..............

Jette un œil là : Lien vers site de Mike Gammon "Power Saving"

Comme l'a dit fdufnews il existe des librairies standards qui n'ont rien à voir avec le projet arduino. Les micro avr d'Atmel existaient bien avant la création des projets Wiring puis Arduino. Dans le monde professionnel la probabilité que les avr soient programmés avec les librairies Arduino n'est pas nulle mais c'est loin d'être la plus répandue.

Pour voir comment on fait sans librairies Arduino (mais ce sera plus compliqué) tu peux jeter un œil ici : lien vers le site avr-freaks

Bonjour et merci à tous, je commence à comprendre. Je mettrais en application quand j'aurai reçu un nouveau circuit, et ferais des mesures pour choisir le meilleur mode. Trop de boulot en ce moment le jour ;)

Bonjour, dfgh, merci encore. J'ai appliqué le code proposé.

La consommation descend à 7 mA au lieu de 24 mA, mais il ne reste pas éveillé pour arrêter le moteur au contact fin de course. Je crois bien que mon moteur a fini par rendre l’âme :(

J'ai cherché la solution, mais elle dépasse mes compétences. Quelle serait la fonction pour désactiver momentanément la veille, pour ne la réactiver qu'après l'arrêt du moteur ?

c’est possible
en fait, le micro s’endort avant que le moteur ait complètement ouvert ou fermé la porte
j’ai modifié le code ( les modifs sont signalées par //ùùùùùùùùùùùùùùùùùùùùùùùùùùùù)
le micro n’est désormais autoriser à dormir que si un fdc est actionné, donc porte en haut ou en bas
tu peux visualiser sur ton moniteur grace aux “serialPrint”

donc : à tester

/* inclus la librairie economiseur de batterie. */
//#include <Adafruit_SleepyDog.h>

//****************************************************************************
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;              
unsigned long tempo_desiree =900; // 15mn=900 secondes
unsigned long compteur_reveil = 0;
unsigned long compteur_travail=0;
unsigned long debut_travail=0;
unsigned long fin_travail =0;
unsigned long total_travail=0;
//****************************************************************************

/* Trappe automatique poulallier en fonction des seuils de lumière jour et nuit.
-  flag_ouverture et flag_fermeture sur seuil de lumière.
- arrêt moteur par contact fin de course.
- arrêt moteur au bout de 8 secondes si le temps normal de 5 secondes dépassé, 
en cas de mécanique ou contact défectueux. 
 */

/* déclaration des constantes pour les noms des broches */
const int led = 13; // led du module nano
const int ldr = A7; // LDR sur broche A7
const int moteur = A6; // mesure courant moteur
const int cde_fermer = 2; // commande relais de flag_fermeture
const int cde_ouvrir = 3; // commande relais d'flag_ouverture
const int  fdc_haut = 4; // fin de course 
const int fdc_bas = 5; // fin de course

/* déclaration des variables */
int nuit = 900; // seuil nuit
int jour = 80;  // seuil jour
unsigned long debut=0; // temps début de rotation

void setup() {
  // initialisation des broches entrée/sortie
 pinMode(ldr, INPUT);
 pinMode(cde_fermer, OUTPUT);
 pinMode(cde_ouvrir, OUTPUT);
 pinMode(fdc_haut, INPUT_PULLUP);
 pinMode(fdc_bas, INPUT_PULLUP);
 //****************************************************************************
 setup_watchdog(9);
 Serial.begin(57600);
 //****************************************************************************
}

void loop()
{
  //****************************************************************************
  debut_travail =  millis();
  if (f_wdt == 1)
  {
    compteur_reveil++;
       Serial.print("reveil pour la  ");
       Serial.print(compteur_reveil,DEC);
       if (compteur_reveil==1){Serial.println(" ere fois");}
       else {Serial.println(" eme fois");}
       //ici, on peut mettre le prog si le temps de sommeil 
       //est de 8 secondes.et virer le if ((compteur_reveil*8)>= tempo_desiree)
       //mais si le temps désiré est > 8secondes, on entre dans 
       //le if ((compteur_reveil*8)>= tempo_desiree)
    if ((compteur_reveil*8)>= tempo_desiree)
    {
      compteur_travail++;
  delay(2000); //le temps de boire un café et d'etre opérationnel
  //****************************************************************************    
//lecture de l'état des entrées
int flag_ouvert = digitalRead(fdc_haut); // 1 au repos
int flag_ferme = digitalRead(fdc_bas);
int seuil = analogRead(ldr);
// action 
 //Il fait jour et la trappe est fermé déclenche l'ouverture et compte le temps.  
 if(seuil < jour && flag_ferme == 0){digitalWrite(cde_ouvrir, 1);debut=millis();};
 // arrêt forcé du moteur si son temps de fonctionnement est supérieur au temps normal.
 if(millis() - debut > 8000){digitalWrite(cde_ouvrir, 0);digitalWrite(cde_fermer, 0);}; 
 
 // arrêt moteur quand la trappe est ouverte
 if(flag_ouvert == 0){digitalWrite(cde_ouvrir, 0);};
 // Il fait nuit et la trappe est flag_ouverte déclenche la flag_fermeture et le compteur de temps moteur
 if(seuil > nuit && flag_ouvert == 0){digitalWrite(cde_fermer, 1);debut = millis();}
 if(flag_ferme == 0){digitalWrite(cde_fermer, 0);};
 delay(10);
 //****************************************************************************    
       Serial.print("travail car il y a eu  ");
       Serial.print((compteur_reveil*8),DEC);
       Serial.println(" secondes de sommeil ");
       Serial.print("il y a ");
       Serial.print((compteur_travail*32),DEC);
       Serial.println(" secondes de fonctionnement ");
    // fin des mesures ici si sommeil >8 secondes
    compteur_reveil = 0;
 }
    fin_travail=millis();
    total_travail=total_travail +(fin_travail-debut_travail);
    Serial.print("temps total de travail =  ");
    Serial.print(total_travail);Serial.println("  ms  ");
    delay(2000); //pour laisser le temps au moteur de libérer son fdc fdc_haut ou fdc_bas
    //ùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùù
    Serial.print("fdc fdc_haut =  ");Serial.println(fdc_haut);
    Serial.print("fdc fdc_bas =  ");Serial.println(fdc_bas);
    //dès que le moteur à commencé à tourner, il lache son fdc. celui ci est donc à 0
    //tant que le moteur n'a pas complètement flag_ouvert ou fermé la porte, les deux fdc sont à 0
    //dès que le moteur actionne un fdc, on entre dans le if ci dessous
    //la tempo de 1 Seconde laisse le temps au micro de passer la cde à 0
    if(((fdc_haut==1)&(fdc_bas==0)) or ((fdc_haut==0)&(fdc_bas==1))) //la porte est soit flag_ouverte, soit fermée
    {
    delay(1000); //pour laisser le temps au moteur de libérer son fdc fdc_haut ou fdc_bas
    f_wdt = 0; // Ne pas oublier d'initialiser le flag, sinon pas de sommeil
    enterSleep(); //Revenir en mode veille
    }
    //ùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùù
 //****************************************************************************
 }
}
// Watchdog Interrupt Service est exécité lors d'un timeout du WDT
ISR(WDT_vect)
{
  if (f_wdt == 0)
  {
    f_wdt = 1; // flag global }
  }
}
// paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 
//           : 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
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);
}

void enterSleep(void) {
  Serial.print(".....zzzzzzzzzzzzzz  ");
  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
  // Le programme va reprendre ici après le timeout du WDT
  sleep_disable(); // La 1ère chose à faire est de désactiver le mode veille
  Serial.println("..............fin sommeil ");
}

Merci dfgh,
C’était bien une mise en veille trop tôt, résolu en ne retournant en veille que 10 secondes après un départ moteur.
J’essaie d’éviter la fonction delay(), car je compte étoffer le programme de fonctions de sauvegarde des horaires d’ouverture et fermeture, surveillance batterie et charge solaire, ext …

/* Trappe automatique poulallier en fonction des seuils de lumière jour et nuit.
-  ouverture et fermeture sur seuil de lumière.
- arrêt moteur par contact fin de course.
- arrêt moteur au bout de 8 secondes si le temps normal de 5 secondes dépassé, en cas de mécanique ou contact défectueux. 
- optimisation conso normal = 23.5 mA /  veille = 7.1 mA
- consommation moteur 250 mA /  330 mA bloqué
- mise en veille relancée 10 secondes après le début d'ouverture ou fermeture
 Merci à fdufnews, 68tjs et particulièrement à dfgh du forum arduino francais pour l'aide apportée
*/

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;             

/* déclaration des constantes pour les noms des broches */
//const int led = 13; // led du module nano
const int ldr = A7; // LDR sur broche A7
//const int moteur = A6; // mesure courant moteur
const int fermer = 2; // commande relais de fermeture
const int ouvrir = 3; // commande relais d'ouverture
const int  haut = 4; // fin de course 
const int bas = 5; // fin de course

/* déclaration des variables */
int nuit = 900; // seuil nuit
int jour = 80;  // seuil jour
int ouvert = 0; // valeur contact haut fermé
int ferme = 1;// contact bas fermé 
int seuil;// seuil de la LDR
unsigned long debut=0;

void setup() {
  // initialisation des broches entrée/sortie
 pinMode(ldr, INPUT);
 pinMode(fermer, OUTPUT);
 pinMode(ouvrir, OUTPUT);
 pinMode(haut, INPUT_PULLUP);
 pinMode(bas, INPUT_PULLUP);

 setup_watchdog(9);
}

void loop() {
// lecture de l'état des entrées
ouvert = digitalRead(haut); 
ferme = digitalRead(bas);
seuil = analogRead(ldr);

// départ moteur
 //Il fait jour et la trappe est fermé déclenche l'ouverture et compte le temps.  
if(seuil < jour && ferme ==0 ){digitalWrite(ouvrir, 1);debut=millis();};
 // Il fait nuit et la trappe est ouverte déclenche la fermeture et le compteur de temps moteur
if(seuil > nuit && ouvert == 0){digitalWrite(fermer, 1);debut = millis();}


// arrêt moteur sur contact fin de course
 // arrêt trappe ouverte
 if(ouvert == 0){digitalWrite(ouvrir, 0);};
 //arrêt trappe fermee
 if(ferme == 0){digitalWrite(fermer, 0);};
 
 /* arrêt forcé du moteur si son temps de fonctionnement est supérieur au temps normal.
 Reste en position intermédiaire si défaut.*/
 if(millis() - debut > 8000){digitalWrite(ouvrir, 0);digitalWrite(fermer, 0);};  

// relance la veille.
if(millis()-debut > 10000){enterSleep();}

}// fin de loop()


// Watchdog Interrupt Service est exécité lors d'un timeout du WDT
ISR(WDT_vect)
{
  if (f_wdt == 0)
  {
    f_wdt = 1; // flag global }
  }
}
// paramétre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms,
//           : 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
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 enterSleep(void) {
  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
  
}

J’ai fait mes tests avec un ampèremètre branché, mais sans le moniteur série, car dans ce cas, le mode veille ne s’active pas et la consommation est > 36 mA.

je viens de lire ta reponse
je t’avais préparé ce code, alors je te le poste quand meme

//****************************************************************************
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;              
unsigned long tempo_desiree =900; // 15mn=900 secondes
unsigned long compteur_reveil = 0;
unsigned long compteur_travail=0;
unsigned long debut_travail=0;
unsigned long fin_travail =0;
unsigned long total_travail=0;
//****************************************************************************

/* Trappe automatique poulallier en fonction des seuils de lumière jour et nuit.
-  flag_ouverture et flag_fermeture sur seuil de lumière.
- arrêt moteur par contact fin de course.
- arrêt moteur au bout de 8 secondes si le temps normal de 5 secondes dépassé, 
en cas de mécanique ou contact défectueux. 
 */

/* déclaration des constantes pour les noms des broches */
const int led = 13; // led du module nano
const int ldr = A7; // LDR sur broche A7
const int moteur = A6; // mesure courant moteur
const int cde_fermer = 2; // commande relais de flag_fermeture
const int cde_ouvrir = 3; // commande relais d'flag_ouverture
const int  fdc_haut = 4; // fin de course 
const int fdc_bas = 5; // fin de course
int flag_ouvert = 0;
int flag_ferme  = 0;
/* déclaration des variables */
int nuit = 900; // seuil nuit
int jour = 80;  // seuil jour
unsigned long debut=0; // temps début de rotation
//******************************************************************************
//******************************************************************************
void setup() {
 //______________________ initialisation des broches entrée/sortie
 pinMode(ldr, INPUT);
 pinMode(cde_fermer, OUTPUT);
 pinMode(cde_ouvrir, OUTPUT);
 pinMode(fdc_haut, INPUT_PULLUP);
 pinMode(fdc_bas, INPUT_PULLUP);
 setup_watchdog(9);
 //Serial.begin(57600);
}
//******************************************************************************
//******************************************************************************
void alarme_porte_restee_fermee()
{
//mettre l'action à faire en cas de disfonctionnement
}
//******************************************************************************
//******************************************************************************
void alarme_porte_restee_ouverte()
{
//mettre l'action à faire en cas de disfonctionnement
}
//******************************************************************************
//******************************************************************************
void ouverture_porte(){
digitalWrite(cde_ouvrir, 1);
debut=millis();
// arrêt moteur quand la trappe est ouverte
while(flag_ouvert != 0)//tant que porte pas ouverte
{
  if(millis() - debut > 8000){break;}// arret forcé moteur si ouverture trop longue
}                                    //ouverture porte terminée dans les temps
digitalWrite(cde_ouvrir, 0);         // reset cde ouverture porte
debut=0;                             //reset chrono temps alloué pour mouvement
if (flag_ouvert!=0){alarme_porte_restee_fermee();}
}
//******************************************************************************
//******************************************************************************
void fermeture_porte(){
digitalWrite(cde_fermer, 1);
debut=millis();
// arrêt moteur quand la trappe est fermée
while(flag_ferme != 0)//tant que porte pas fermée
{
  if(millis() - debut > 8000){break;}// arret forcé moteur si fermeture trop longue
}                                    //fermeture porte terminée dans les temps
digitalWrite(cde_fermer, 0);         // reset cde fermeture porte
debut=0;                             //reset chrono temps alloué pour mouvement
if (flag_ferme!=0){alarme_porte_restee_ouverte();}
}
//******************************************************************************
//******************************************************************************
void loop()
{
  if (f_wdt == 1)
  {
    compteur_reveil++;
    if ((compteur_reveil*8)>= tempo_desiree)
    {
     delay(1000); //le temps de boire un café et d'etre opérationnel
       //lecture de l'état des entrées
     flag_ouvert = digitalRead(fdc_haut); // 1 au repos
     flag_ferme = digitalRead(fdc_bas);
     int seuil = analogRead(ldr);
     // _________________________action 
     //Il fait jour et la trappe est fermée. déclenche l'ouverture  
     if(seuil < jour && flag_ferme == 0){ouverture_porte();} 
     // Il fait nuit et la trappe est ouverte. déclenche la fermeture 
     if(seuil > nuit && flag_ouvert == 0){fermeture_porte;}
     delay(10);
     compteur_reveil = 0;
     }
   f_wdt = 0; // Ne pas oublier d'initialiser le flag, sinon pas de sommeil
   enterSleep(); //Revenir en mode veille
   } 
 }
//******************************************************************************
//******************************************************************************
// Watchdog Interrupt Service est exécité 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);
}
//******************************************************************************
//******************************************************************************
void enterSleep(void) 
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();    //Entre dans le mode veille choisi
  sleep_disable(); // La 1ère chose à faire est de désactiver le mode veille
}

Merci quand même dfgh ;)

Bonjour, J'ai encore amélioré la consommation : - fabriqué un pont H avec des transistors pour pouvoir diminuer la tension d'alimentation

Le programme n'est pas encore définitif, car je n'arrive pas à gérer l’interruption sur surcharge moteur mais j'ai encore des tests à faire et ici n'est pas le sujet ;)

Voilà un aperçu du projet

hello une remarque. dans ton système de moteur + corde imagine que tu as demandé une descente de la trappe si elle se bloque dans ses glissières, le moteur continue à tourner. arrivé au bout de la corde, le moteur tournant toujours, celle ci va s'enrouler à l'envers sur l'axe. la trappe se débloquera et remontera mais toujours avec une commande à descendre donc le fdc haut n'arrêtera pas le moteur.

dans le prg, il faut: dans le ctrl du fdc haut ou bas, arrêter la cde moteur ouverture [u]et[/u] fermeture ca ne mange pas de pain et évitera peut être des prob.

une autre remarque: je pense que tu peux supprimer la routine d'interruption du watchdog. elle sert d'horloge au compteur de périodes de sommeil de 8 secondes. mais vu la façon dont tu utilise la routine de sleep, ( tu n'as pas utilisé le compteur de période de sommeil) l'ISR WatchDog est inutile.

Bonjour,

dfgh: hello une remarque. dans ton système de moteur + corde imagine que tu as demandé une descente de la trappe si elle se bloque dans ses glissières, le moteur continue à tourner. arrivé au bout de la corde, le moteur tournant toujours, celle ci va s'enrouler à l'envers sur l'axe. la trappe se débloquera et remontera mais toujours avec une commande à descendre donc le fdc haut n'arrêtera pas le moteur.

Regarde bien la deuxième photo : La cordelette est fixée à 2 endroits, s'enroule à droite en descente et se déroule à gauche. Une poulie, en bas(non visible), avec le ressort maintien la corde tendue. En cas de blocage, le moteur s'arrête. Il ne risque pas de griller, une résistance de 4.7 ohm limite le courant à 250mA. J'ai construit ce dispositif, car avec une simple cordelette, ça coinçait des fois :/ Ce que je n'ai pas encore réussi à gérer est l'arrêt du moteur dans ce cas. Cela pourrait me permettre de gérer les fin de course uniquement sur blocage.

dans le prg, il faut: dans le ctrl du fdc haut ou bas, arrêter la cde moteur ouverture [u]et[/u] fermeture ca ne mange pas de pain et évitera peut être des prob.

Tu as raison mais si je mets la fonction stop(), tout s'arrête.

une autre remarque: je pense que tu peux supprimer la routine d'interruption du watchdog. elle sert d'horloge au compteur de périodes de sommeil de 8 secondes. mais vu la façon dont tu utilise la routine de sleep, ( tu n'as pas utilisé le compteur de période de sommeil) l'ISR WatchDog est inutile.

J'ai remarqué que(dans mon cas) ça ne servait à rien de le mettre à 0 et que le mode veille redémarre dès qu'on appelle enterSleep(), mesure de courant pour preuve.

J'ai commandé un module DS3132 qui devrait me permettre d'éteindre carrément le microP hors montée ou descente de trappe. Pour maintenant, avec un accu 4Ah, je devrais tenir au moins 40 jours ;)

hello, je viens de lire sur un autre post que tu as viré les fdc pour n'utiliser que la surintensité du moteur

si la trappe se bloque au milieu, tu coupe le moteur, c'est bien mais comment contrôle tu que la trappe est complètement ouverte ou fermée?

Bonsoir,

dfgh: hello, je viens de lire sur un autre post que tu as viré les fdc pour n'utiliser que la surintensité du moteur

si la trappe se bloque au milieu, tu coupe le moteur, c'est bien mais comment contrôle tu que la trappe est complètement ouverte ou fermée?

merci du retour,

J'ai mis un plexiglass en façade, et comme je visite au moins une fois par jour, je verrai le défaut. Avec un seuil assez élevé comme je l'ai réglé, un brin de paille ne la bloque pas, il y a peu de raison pour que ça arrive.

D'autre part, on peut ajouter des actions comme pour les portes d’ascenseur ou de métro : relancer le moteur en sens inverse et retenter au bout d'un certain délai. Pour ça il faut tenir compte du temps normal d'ouverture ou de fermeture. Je verrai si c'est nécessaire.

Pour l'instant, ça fonctionne bien comme ça, il se passe au moins une demi-heure entre le moment ou les poules rentrent et la trappe se ferme. Et puis je suis rassuré qu'elle ne se transformera pas en guillotine ;)

Tu préconise quoi ?

quand le moteur monte en intensité, tu ne peux savoir si c'est parce que la porte est coincée en milieu de course ou si elle est arrivée en haut ou en bas. le seul moyen pour faire la distinction est de remettre les fdc. meme si tu ne veux pas les utiliser en fdc qui stoppent le moteur, tu peux les considérer comme des témoins de porte fermée ou porte ouverte

ex: si le moteur force et pas de fdc => problème et éventuellement va et vient pour essayer de débloquer la porte

si le moteur force et fdc haut ou bas, tout va bien=> arrêt du moteur et dodo