Arduino comme bloquée

Bonjour a tous, depuis 2 jours le comportement de la trappe de poulailler est étrange . La porte ne se ferme plus le soir et ne s'ouvre plus le matin, alors que tout fonctionnait nickel. même en simulant la nuit en cachant le capteur de lumière , rien ne se passe. Par contre, quand je coupe l'alimentation de la carte arduino, au redémarrage tout ré fonctionne parfaitement . Que se passe t il ???

on peut pas deviner comme ça. Mais il est fort possible qu’une variable dépasse sa taille maximale. Elle écrase donc d’autres choses qui sont dans la ram. Et ton programme ne fonctionne plus.

Est ce que tu as une variables qui augmente chaque secondes par exemple et qui n’est jamais remis à 0 ?
Ou alors cette variable n’est pas définie comme un unsigned, et lorsqu’elle arrive au maximum, elle recommence dans les négatifs

voici mon code, mais je ne vois pas ou peut etre le problème

//************************************************//
//  GESTION D'UNE TRAPPE DE POULAILLER EN FONCTION DE LA LUMIERE
//  zimmermann frédéric
//  18 01 2015
//************************************************

unsigned long tempsdebutouv  = 0;
unsigned long tempsdebutferme = 0 ;


int PinLumiere=0;        //Broche Analogique de mesure d'éclairement
int PinSeuilLumiere=3;   //Broche Numérique mesure d'éclairement
int tension=0;     //Mesure de tension (valeur élevée si sombre)
int eclaire =0;    //0 ou 1 (0=éclairé>seuil, 1=ombre<seuil)
int ENB = 11; //  Reglage vitesse moteur
int IN3 = 8; // pont en H moteur A
int IN4 = 9; // pont en H moteur A
int fin_coursebas = 2; // bouton pin 2
int fin_coursehaut = 4; // bouton pin 2
int ledbas = 6;
int ledhaut= 5;
int etatcapteurbas= HIGH;  // etat du capteur bas
int etatcapteurhaut = LOW; // etat du capteur haut
int bouton = 12;
int iphone = 13;
int etatiphone = 0;
int etatbouton = 0;
int buzzer = 7;
int etatmoteur = 0;  // 0 = moteurarret , 1 = moteur fermeture, 2= moteur ouverture

boolean trappe_ferme ;
boolean trappe_ouverte;
boolean trappe_milieu_course;



void setup() { 
    
    Serial.begin(9600);  //Connection série à 9600 baud
    pinMode(PinLumiere,INPUT);       //pin A0 en entrée analogique
    pinMode(PinSeuilLumiere,INPUT);  //pin 3 en entrée numérique
    pinMode(ENB,OUTPUT);
    pinMode(IN3,OUTPUT);
    pinMode(IN4,OUTPUT);
    pinMode(fin_coursebas,INPUT);
    pinMode(fin_coursehaut,INPUT);
    pinMode(ledbas, OUTPUT);
    pinMode(ledhaut, OUTPUT);
    pinMode(bouton, INPUT);
    pinMode(buzzer,OUTPUT);
    pinMode(iphone, INPUT);
}

void loop() { //boucle principale

    etatbouton = digitalRead(bouton);
    etatiphone = digitalRead(iphone);
    etatcapteurbas = digitalRead(fin_coursebas);
    etatcapteurhaut = digitalRead(fin_coursehaut);
   tension = analogRead(PinLumiere); // Lit la tension analogique
    eclaire = digitalRead(PinSeuilLumiere); 
    Serial.begin(9600);  //Connection série à 9600 baud
    Serial.println( etatiphone); 
    Serial.println( tension);
    
    
 delay (400);
   //---------------------------------------------------//  VERIF DE L'ETAT DE LA TRAPE
   // verif si trappe fermé 
   
   if (etatcapteurbas == LOW && etatcapteurhaut == HIGH)
         { trappe_ferme = true;
           
           digitalWrite(ledbas, HIGH);
           
          }  // la trappe est fermé
             else { digitalWrite(ledbas, LOW);
                    trappe_ferme = false;}
     
         
   // Vérif si trappe ouverte  
    
    if (etatcapteurhaut == LOW && etatcapteurbas == HIGH)
         {trappe_ouverte = true;
          
          
           digitalWrite(ledhaut, HIGH); 
           
          }  // la trappe est ouverte                        
      
              else { digitalWrite(ledhaut, LOW);
                     trappe_ouverte = false; }
     
          
     // si la trappe se trouve à mi-course
        
    if (etatcapteurhaut == HIGH  && etatcapteurbas == HIGH)
         {trappe_milieu_course = true;
                    
              digitalWrite (buzzer, HIGH);  // buzzer en route
                   delay (300);
              digitalWrite (buzzer, LOW);
                   delay (300);                  }
   

    
    //____________________________________________________//   ACTIONNEMENT DU MOTEUR DANS LES 2 SENS
       
       // si il fait nuit et la trappe est ouverte 
       
         if (analogRead(PinLumiere) > 1015  &&  trappe_ouverte == true)
       
         {   
             moteurfermeture();  // on ferme
             etatmoteur = 1;  // le moteur est actionné
                          }
            
         
        // si il fait jour et trappe fermé
        
        if (analogRead(PinLumiere) < 600  &&  trappe_ferme == true)
         { 
           moteurouverture(); // on ouvre
           etatmoteur = 2;
            
                                             }
     
         
        
     //_______________________________________________________//   ARRET DU MOTEUR
       // si moteur fermeture en route et si trappe fermé
          
           if (  etatmoteur == 1 && trappe_ferme == true)
             { moteurarret();
                  etatmoteur = 0;
                     } 
       
       // si moteur ouverture en route et si trappe ouverte
          
           if (  etatmoteur == 2 && trappe_ouverte == true )
               
                { moteurarret();
                etatmoteur = 0;
                  }
                  
               // gestion bloquage moteur 
     
          
           // __________________________________________________________GESTION DU BOUTON    
        // bouton appuyé et trappe ouvert
     
        if ( etatbouton == 1 && trappe_ouverte == true)
            {moteurfermeture();
             etatmoteur = 1 ;
              etatbouton = !etatbouton ;
}

         // bouton appuyé et trappe fermé
     
        if ( etatbouton == 1 && trappe_ferme == true)
            {moteurouverture();
             etatmoteur = 2 ;
              etatbouton = !etatbouton ;
              
            }
        
        // trappe mi-course et bouton appuyé
        
        if (trappe_milieu_course == true) 
           { while( etatbouton == HIGH)
              {moteurouverture();
             etatmoteur=2 ;
              etatbouton = !etatbouton ;
        
      }}
// __________________________________________________________GESTION DE L'IPHONE    
        // iphone appuyé et trappe ouvert
        if ( etatiphone == 1 && trappe_ouverte == true)
            {moteurfermeture();
             etatmoteur = 1 ;
              etatiphone = !etatiphone ;
}

         // iphone appuyé et trappe fermé
     
        if ( etatiphone == 1 && trappe_ferme == true)
            {moteurouverture();
             etatmoteur = 2 ;
              etatiphone = !etatiphone ;
              
            }
        
        // trappe mi-course et iphone appuyé
        
        if (trappe_milieu_course == true) 
           { while( etatbouton == HIGH)
              {moteurouverture();
             etatmoteur=2 ;
              etatiphone = !etatiphone ;
        
      }}
      
      //____________________________________________________ GESTION PROBLEME MOTEUR 
    
    // blocage pendant la fermeture
    
     if ((etatmoteur == 1) && (trappe_milieu_course == true) && (( millis()-tempsdebutferme)>= 18000))
     { moteurarret();
        etatmoteur = 4;}
        
         // blocage pendant l'ouverture
    
     if ((etatmoteur == 2) && (trappe_milieu_course == true) && (( millis()-tempsdebutouv)>= 25000))
     { moteurarret();
        etatmoteur = 4;}
        
} 
       
       
       
void moteurouverture(){
    
    tempsdebutouv = millis();
     digitalWrite(ENB, HIGH);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, HIGH);   
     }
       
       
void moteurfermeture() 
      
       { tempsdebutferme = millis();
     
     digitalWrite(ENB, HIGH);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, LOW);
     }


void moteurarret()
     {digitalWrite(ENB, LOW);
              }
     
/code]

Comment est alimenté le montage ?

Je précise que tout fonctionnait parfaitement pendant plus d'un mois et demi

arduino alimenté avec une alim standard pour arduino, le moteur est alimenté en 12 v par un transfo

50 jours environ ?

millis()

Oui ça peut être 50 jours , pourquoi ?

bigben99> oops j'ai rien dit, confondu avec un autre topic :D

Fredericzim > il y a un lien dans sa réponse qui t'explique

pour être précis : 49j17h2min47s295ms

la raison est ici

Ok, la fonction millis est bloquante après 47j mais concrètement comment je fais, je dois rebalancer mon code tous les 47 j alors ?

Utiliser des unsigned long avec toutes les variables agissant avec millis comme tu l’as fait devrait suffire normalement.

Je vais chercher si y a pas autre chose

Mais je pense que le plus simple, serait peut être que chaque 30 jours, tu redémarres l’arduino

Pas la peine de rebalancer ton code, un reset tous les 49j ca suffira, sinon, il faut que tu gères le retour à 0 de la fonction millis.

Bon ben moi, avant de répondre, j'ai pris 5 min pour jeter un oeil au code, au demeurant fort propre.

D'habitude on râle dès qu'il n'y est pas. Là il est fourni et j'ai l'impression que personne ne le regarde :smiling_imp:

millis() est bien gérée. Aucun souci avec le roll over au bout de 50 jours. Pas de librairie douteuse (d'ailleurs aucune librairie utilisée) Pas d'allocation de variables à tire larigot. Un structure de programme simple Des instructions simples : on ne sort pas d'un gestion de variables globales, avec les instructions basiques read/write sur les pin d'entrée sortie. Quelques delay

bref jusqu'ici tout va bien

Une instruction qui me semble inutile : Serial.begin() dans la fonction loop()

Mais surtout : un balayage des instructions while (toujours un bon suspect au blocage d'un système) révèle la présence d'une boucle infernale dont on ne ressort jamais :

     // trappe mi-course et iphone appuyé
        
        if (trappe_milieu_course == true) 
           { while( etatbouton == HIGH)
              {moteurouverture();
             etatmoteur=2 ;
              etatiphone = !etatiphone ;
        
      }

vu que etatbouton n'est jamais modifiée dans le corps du while, ni dans la fonction moteurouverture()

Rien vu d'autre de louche dans le code.

En effet, le problème vient sans doute de là.

par contre, le retour à 0 de millis aura un impact sur la gestion des problèmes moteur (à étudier)

bigben99 > non, car le fait que les autres variables soient aussi unsigned long, fait que le résultat de la soustraction sera quand même juste

Effectivement, je maintiens : pas de problème avec millis() sur ce type de coding

tempsdebutouv = millis();
...
if (millis()-tempsdebutferme>= 18000)
{
...
}

Le retour à zéro de la valeur renvoyée par millis() au bout de 47j ne perturbe pas le résultat de l'opération de soustraction. C'est bien comme ça qu'il faut coder les délais.

A noter que la forme ci-dessous ne convient pas, bien qu'identique d'un point de vue mathématique. Elle est en effet sensible au roll over de milis()

tempsdebutouv = millis();
...
if (millis()>= tempsdebutferme + 18000)
{
... // déclenché à tort tout de suite, dès que tempsdebutferme s'approche à moins de 18000 de la valeur max
}

=> les joies des calculs sur les entiers, lorsqu'il y a dépassement de capacité. Si vous n'êtes pas convaincus, écrivez quelques lignes de code pour vérifier.

Pour tester qu'un programme continue à bien fonctionner après le retour à zéro de millis(), il y a un moyen plus simple que d'attendre 47 jours. ==> remplacer temporairement tous les appels à millis() par des appels à ma_millis(), avec

unsigned long ma_millis()
{
  const unsigned long delai_avant_roll_over = 60000L; // 1 minute après démarrage de l'arduino
  return millis() - delai_avant_roll_over;
}

Bon j'ai modifié mon petit soucis de while, j'ai démonté mon système et reteleversé le code , je vous tiendrai au courant. Encore merci a vous tous

Donc pour ce soir la trappe vient de se fermer normalement , le renard ne viendra pas, ouf mes poules sont en sécurité ! Lol

Bon, le problème est tj présent . Ce matin, la les 2 voyants de capteur haut et bas était allumés et le buzzer émettait un bruit anormal . Par contre la trappe ne s'est pas ouverte . Le pb ne venait donc pas de milli(). Il y a sûrement un autre problème matériel quelque part , le buzzer ????