Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino probléme avec la fonction millis()

ARDUINO

Sujet résolu
    22 juillet 2017 à 15:35:07

    Bonjour à tous,

    Je viens vers vous car j'ai un problème concernant mon projet pour une barre motorisé et time lapse pour mon appareil photo.

    J'ai créé un petit menu lcd dans le quel je peux choisir différent paramètre et programme. Je possède deux gros menus qui sont :

    Le time lapse, et le time lapse sur barre motorisé.

    Pour le time lapse, tout est ok, j'intègre la fonction millis() et ma mise au point et mon déclenchement fonctionne. Voici ce que j'utilise :

    void loop() {
    
    
      
      if(millis() - temps >= 1500){
        digitalWrite(AF_PIN, HIGH);
      }
    if(millis() - temps >= 5000){
    digitalWrite(AF_PIN, LOW);
    temps = millis();
    
    }
    
    
    
      
    if(millis() - temps2 >=2500){
      digitalWrite(DEC_PIN, HIGH);
    }
    if(millis() - temps2 >= 5000){
    digitalWrite(DEC_PIN, LOW);
    
    temps2 = millis();}
    }
    

    Ensuite je joue sur les tempos pour choisir le temps souhaité à chaque déclenchement. Grâce à la fonction millis(), je peux démarrer ou interrompre mon programme via le menu lcd.

    Maintenant, la ou j'ai mon problème c'est dans le menu "time lapse sur barre motorisée". Voici le programme avec le delay :

    /*Programme permettant un cycle time lapse mouvementé sur la barre traveling à l'aide du moteur pas à pas*/
    /*Il se compose de deux relais pour la mise au point et le déclenchement de l'APN, motorisé sur la barre à l'aide d'un moteur pas à pas de type NEMA
     * et de son pilote A3967 ( à changer pour le projet car trop faible en courant*/
     
    /*déclaration des variables pour le pilote du moteur pas à pas*/
    
    int dirpin = 2;
    int steppin = 3;
    
    /*déclaration des variables pour les relais qui commandent le 'APN*/
    
    #define AF_PIN   10
    #define DECL_PIN  11
    
    /*déclaration des tempos de la mise au point et du déclenchement de l'APN*/
    
    int tempo_AF = 1200; // durée de la mise au point, à déterminer selon la durée du cycle.
    int tempo_DECL = 800;  // durée de déclenchement de l'APN, à déterminer selon la durée du cycle.
    
    
    /***************************************************************************************************************************/
    
    void setup() 
    {
    
    /*Déclaration de la valeur des commandes APN en sortie gérée pas 2 relais*/
       
     pinMode(AF_PIN, OUTPUT);
     pinMode(DECL_PIN, OUTPUT);  
    
     
    /*Déclaration de la valeur des commandes moteur PAP en sortie*/ 
    
    pinMode(dirpin, OUTPUT);
    pinMode(steppin, OUTPUT);
    
    }
    
    
    /****************************************************************************************************************************/
    
    void loop()
    {
    
      int i;
    
      digitalWrite(dirpin, LOW); 
      delay(100);
    
    /*j'agis sur cette valeur, pour déterminer le nombre de pas par cycle (nombre de degrés de rotation du moteur) à modifier selon la longueur de la barre traveling*/
    
      for (i = 0; i<1000; i++)     
      {
        digitalWrite(steppin, LOW);  
        digitalWrite(steppin, HIGH);
    
    /*j'agis sur cette valeur pour déterminer la vitesse de rotation, plus elle tend vers zéro, plus la vitesse est rapide*/
        
        delayMicroseconds(500);
      }
        digitalWrite(dirpin, HIGH);
    
    /*C'est le temps d'atente entre chaque cycle "rotation" du moteur*/
    
    delay(1000);
    
     digitalWrite(AF_PIN, HIGH);
     delay(tempo_AF);
     
     digitalWrite(DECL_PIN, HIGH);
     delay(tempo_DECL);
       
     digitalWrite(AF_PIN, LOW);
     
     digitalWrite(DECL_PIN, LOW);
      }

    Le problème de ce programme est le delay. En effet, puisqu'il fait une pause dans la loop, je n'ai plus aucun contrôle du fonctionnement.

    J'ai donc voulu prendre le premier programme avec la fonction millis() de l'intervalomètre et le placer dans le second code à la place du fonctionnement avec le delay.

    Je rappel que j'utilise un moteur pas à pas pour le déplacement sur la barre. Quand je lance le programme, cela fait du n'importe quoi. Le moteur fonctionne en continu, avec un la mise au point et le déclenchement qui s'active quand ca lui chante. Mais je me suis dis que c'est un problème de tempo puisque la fonction millis() débute dés l'allumage d'arduino. Loupé.

    Je sèche, un grand merci pour celui qui peut m'aider



    • Partager sur Facebook
    • Partager sur Twitter
      24 juillet 2017 à 8:25:58

      Si tu veux garder de la réactivité, il te faut supprimer tous les delay ou limiter grandement les temps de blocages.

      Comme tu l'as dis, le delay(1000) bloque le programme pendant une seconde donc ça va retarder d'autant ton déclenchement avec millis.

      Mais il y a aussi ta boucle de déplacement qui pose problème car 1000*500us = 0.5 secondes de bloquage.

      ----------

      Pour supprimer tes delay, tu peux très bien utiliser millis.

      Par exemple, ce code :

      digitalWrite(led, HIGH);
      delay(100);
      digitalWrite(led, LOW);
      delay(100);

      Pourrait être remplacé par :

      if ( ( delayH != 0 ) && ( millis() - delayH > 100 ) ) {
          digitalWrite(led, HIGH);
          delayH = 0;
          delayL = millis();
      }
      if ( ( delayL != 0 ) && ( millis() - delayL > 100 ) ) {
          digitalWrite(led, LOW);
          delayL = 0;
          delayH = millis();
      }

      Bref, chaque bloque de code avant un delay doit être entouré d'un bloc if.

      ----------

      Quand à la gestion du moteur pas à pas, tu pourrais faire la même chose en exploitant millis (ou micros) pour déclencher tes actions sans bloquer le programme.

      Il me semble qu'il existait aussi une lib pour ça.

      Mais cette lib exploite elle aussi millis donc si tu as un élément bloquant quelque part, elle ne marchera pas.

      • Partager sur Facebook
      • Partager sur Twitter
        24 juillet 2017 à 21:17:50

        Bonsoir,

        Merci lorrio de ta réponse, j'essaye ça! Petite question : lorsque je mets un delay dans ma loop (delay(2500); par exemple), ensuite j'effectue une fonction millis()(=3000 par exemple), plus loin dans ma loop.

        Est ce que le delay de 2500ms s'ajoute sur la tempo millis(); ou alors millis() continu sans savoir qu'il y a eu un delay avant?

        Au cas ou :  delay de 2500 + 3000 alors millis() = 5500

        Ou alors delay de 2500 + 3000  alors millis() = 3000 quand même?

         Je ne sais pas si je m'exprime bien, c'est assez dur à décrire comme question.

        Merci.

        • Partager sur Facebook
        • Partager sur Twitter
          24 juillet 2017 à 21:30:11

          La fonction millis te retourne le nombre de ms écoulé depuis le début du programme, tout simplement.

          • Partager sur Facebook
          • Partager sur Twitter
            24 juillet 2017 à 21:37:59

            Ok merci, j'ai déja fais la modif pour les deux premères tempos du moteur, ca marche plutot bien. Par contre la pause de 1 sec plus précisément celle-ci :

            /*C'est le temps d'atente entre la fin du cycle rotation du moteur et le début de la prise de vue*/
            
            delay(1000);

            Comment puis-je la transformer en fonction millis(); en sachant que le but est de ne RIEN faire pendant une sec. (en gros rien n'est activé pendant c'est une seconde)

            Je ne sais pas comment lui dire de ne rien faire. Il faut créer une variable?

            Merci lorrio

            EDIT : Je confirme c'est le seul paramètre qu'il me manque : une pause. (le moteur tourne en continu quand j'essaye de mettre le step et la dir du moteur à LOW.

            Ce qui est bizzard c'est que les relais s'arrêtent au bout de 5 ou 6 cycles...alors la je ne sais pas. 

            Voici ma modif sans la pause du moteur :

            /* Début projet barre automatisé avec time lapse*/
            
            
            /*Programme permettant un cycle time lapse mouvementé sur la barre traveling à l'aide du moteur pas à pas*/
            /*Il se compose de deux relais pour la mise au point et le déclenchement de l'APN, motorisé sur la barre à l'aide d'un moteur pas à pas de type NEMA
             * et de son pilote A3967 ( à changer pour la phase finale car trop faible en courant*/
             
            /*déclaration des variables pour le pilote du moteur pas à pas*/
            
            int dirpin = 2;
            int steppin = 3;
            
            /*déclaration des variables pour les relais qui commandent le 'APN*/
            
            #define AF_PIN   10
            #define DECL_PIN  11
            
            /*déclaration des tempos de la mise au point et du déclenchement de l'APN*/
            
            int tempo_AF = 800; // durée de la mise au point, à déterminer selon la durée du cycle.
            int tempo_DECL = 1200;  // durée de déclenchement de l'APN, à déterminer selon la durée du cycle.
            
            int delayL = 0;
            int delayH = 0;
            
            int temps = 0;
            int temps2 = 0;
            /***************************************************************************************************************************/
            
            void setup() 
            {
            
            /*Déclaration de la valeur des commandes APN en sortie gérée pas 2 relais*/
               
             pinMode(AF_PIN, OUTPUT);
             pinMode(DECL_PIN, OUTPUT);  
            
             
            /*Déclaration de la valeur des commandes moteur PAP en sortie*/ 
            
            pinMode(dirpin, OUTPUT);
            pinMode(steppin, OUTPUT);
            
            }
            
            
            /****************************************************************************************************************************/
            
            void loop()
            {
            
              int i;
            
            if ((delayL != 0 ) && ( millis() - delayL > 100)){
              digitalWrite(dirpin, LOW); 
             delayL = 0;
             delayL = millis();}
            
            /*j'agis sur cette valeur, pour déterminer le nombre de pas par cycle (nombre de degrés de rotation du moteur) à modifier selon la longueur de la barre traveling*/
            
              for (i = 0; i<1000; i++)     
              {
               
                digitalWrite(steppin, LOW);  
                digitalWrite(steppin, HIGH);
            
            /*j'agis sur cette valeur pour déterminer la vitesse de rotation, plus elle tend vers zéro, plus la vitesse est rapide. A déterminer selon la configuration du système de la barre*/
                
                delayMicroseconds(200);
              }
            
            
                
            
            /*C'est le temps d'atente entre la fin du cycle rotation du moteur et le début de la prise de vue*/
            
            
              if(millis() - temps >= 3000){
                digitalWrite(AF_PIN, HIGH);
              }
            if(millis() - temps >= 6000){
            digitalWrite(AF_PIN, LOW);
            temps = millis();
            
            }
            
            
            
              
            if(millis() - temps2 >=4000){
              digitalWrite(DECL_PIN, HIGH);
            }
            if(millis() - temps2 >= 6000){
            digitalWrite(DECL_PIN, LOW);
            
            temps2 = millis();}
            }
            
            
            

            MERCI

            -
            Edité par GaelApper1 24 juillet 2017 à 22:10:38

            • Partager sur Facebook
            • Partager sur Twitter
              24 juillet 2017 à 22:04:38

              Il faut voir la chose autrement.

              Le but n'est pas de ne rien faire pendant une seconde mais plutôt de faire la suite une seconde après.

              Donc c'est tout le code qu'il y a après ce delay qui doit être placé dans un if déclenchant l'action après un certain temps grace à millis.

              • Partager sur Facebook
              • Partager sur Twitter
                24 juillet 2017 à 22:13:24

                Lorrio, je suis désolé mais la je sèche, je comprends le fait de mettre toute la condition du moteur dans un "if" mais comment l'écrire....avec tout ce qu'il y a à l'intérieur, je ne sais pas du tout.
                • Partager sur Facebook
                • Partager sur Twitter
                  24 juillet 2017 à 22:42:01

                  unsigned long timer1;
                  unsigned long timer2;
                  
                  void setup() {
                  
                      // ICI: ton code setup
                  
                      delay(5);
                  
                      timer1 = millis();
                      timer2 = 0;
                  
                  }
                  
                  void loop() {
                  
                      if ( ( timer1 != 0 ) && ( millis() - timer1 > 0 ) ) {
                  
                          // ICI: ton code AVANT le millis
                  
                          timer1 = 0;
                          timer2 = millis();
                  
                      }
                  
                      if ( ( timer2 != 0 ) && ( millis() - timer2 > 1000 ) ) {
                  
                          // ICI: ton code APRES le millis
                  
                          timer1 = millis();
                          timer2 = 0;
                  
                      }
                  
                  }

                  -
                  Edité par lorrio 24 juillet 2017 à 22:42:40

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 juillet 2017 à 23:05:39

                    Ca marche! Merci lorrio après trois soirées bloquées, mon programme marche super bien. Soulagé!

                    A bientôt!

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Arduino probléme avec la fonction millis()

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown