LOCODUINO

Les Timers (II)

Les interruptions

. Par : Christian

Qu’est-ce qu’une interruption ? C’est ce qui nous arrive à tous dans notre vie de tous les jours. Imaginez que vous soyez au téléphone et que l’on sonne à votre porte. Vous demandez à votre interlocuteur de patienter, vous posez votre téléphone puis vous allez ouvrir. C’est le facteur qui vous apporte un colis. Une fois celui-ci réceptionné (…)

Retourner à l'article

Vous répondez à :

Les Timers (II) 13 octobre 2020 11:32, par Christian

Ecrire directement dans le port peut améliorer l’obtention du signal.
Mais dans certain cas, il est nécessaire de programmer directement le microcontrôleur en langage machine et donc utiliser l’assembleur. L’IDE permet de le faire mais quelle galère ! Je l’ai fait une fois avec le programme Blink et effectivement, mon code était plus concis qu’avec la compilation classique.
Mais si on doit se lancer dans cette aventure, il vaut mieux se procurer les bons outils et donc un vrai programme d’assemblage.
Après, il faut aussi pouvoir déboguer : en assembleur, c’est aussi une autre histoire !
C’est pourquoi, sur ce site qui est fait surtout pour des amateurs (et souvent débutants), nous restons fidèles au bon vieux IDE qui utilise gcc.
Allez voir l’article de Thierry https://www.locoduino.org/spip.php?...;: ce sera aussi un bon début pour vous y remettre.

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

28 Messages

  • Les Timers (II) 9 avril 2017 18:02, par PIVAR

    J’ai bien mijoté timer 1 et 2 ; bon ,je connais des basics et je commence en arduino (du C ?), mais j’ai remarqué les lignes :"#define LedToggle digitalWrite (Led, !digitalRead(Led))" ; et l’on peut appeler LedToggle comme si c’était une fonction ! ; là , je reste pantois..
    Un petit truc , en ligne 14 on désactive les interruptions pour les réactiver en ligne 19 ; est-ce pour prendre en compte la nouvelle interruption ?

    Répondre

    • Les Timers (II) 10 avril 2017 01:16, par Christian Bézanger

      Le #define permet de dire au préprocesseur de remplacer l’expression de gauche (inconnue dans le monde Arduino) par celle de droite (fonctions classiques).
      Ici, LedToggle permet d’inverser l’état d’une LED : le préprocesseur remplacera ce terme par digitalWrite(Led, !digitalRead(Led)) c’est-à-dire écrire sur la sortie reliée à la LED l’inverse de ce qu’on peut y lire (si la sortie est à HIGH, on l’écrira à LOW et réciproquement).
      Avec #define, j’ai écrit le programme Blink tout en français, ce qui n’a pas d’autre intérêt que de faire taire les détracteurs d’Arduino sous prétexte qu’il faudrait parler anglais...
      Pour déclarer des numéros de broches, on peut utiliser #define mais il est conseillé de préférer des ’const int’.
      Dominique a parfaitement répondu à la question suivante.
      Enfin, nul besoin d’apprendre le C pour Arduino : les fonctions de base sont bien suffisantes pour débuter (voir page Reference du site arduino.cc). Avec le temps et l’expérience, des bases de C++ permettent de faire des choses bien plus puissantes.

      Répondre

      • Les Timers (II) 10 avril 2017 11:04, par PIVAR

        Merci à Christian et Dominique ; pour le #define , c’est une commodité d’écriture ; bon au cas ou , l’expression de droite doit tenir sur une ligne ou peut-elle se prolonger ?
        De mon coté , pour mon appli , je trouve sur votre site pas mal d’infos il est aussi vrai qu’il y a pas mal de similitudes entre les séquences pour trains et celles d’un appareil pour labo ; mon appli sera en 2 parties :l’une sur le pc pour une belle interface graphique et des enregitrements(b4j compilé java) et l’autre sur arduino en C pour une gestion nette et synchrone des stepper , pin entrées sorties ; cela va causer au travers du serial ...mais , je sais , c’est hors sujet
        Bonne journée

        Répondre

        • Les Timers (II) 10 avril 2017 12:02, par Christian Bézanger

          Nous trouvons très bien que des gens qui s’intéressent à la robotique ou bien à la domotique ou encore à d’autres domaines viennent consulter notre site pour y trouver des informations ou des astuces dont ils pourront s’inspirer.
          Néanmoins, nous serions débordés si nous devions répondre à toutes les questions de ces gens, c’est pourquoi nous nous limitons au train miniature et nous renvoyons ces personnes vers d’autres sites spécialisés dans les autres domaines.
          Dans le #define, une expression de droite trop longue n’aurait aucun sens car cela diminuerait la lisibilité du code. Il vaut mieux dans ce cas recourir aux fonctions.

          Répondre

        • Les Timers (II) 10 avril 2017 12:06, par Jean-Luc

          Bonjour,

          L’expression doit tenir sur une ligne mais on peut utiliser le \ en fin de ligne pour faire en sorte que le préprocesseur ignore cette fin de ligne. Par exemple :

          #define uneMacroCompliquee    \
          if (val == 0) {               \
              val = 1;                  \
          }

          Attention, il ne doit pas y avoir de caractères, notamment des espaces, entre le \ et la fin de ligne

          On peut également faire des macros avec des arguments. Christian aurait pu écrire :

          #define pinToggle(aPin)     digitalWrite(aPin, !digitalRead(aPin))

          Répondre

          • Les Timers (II) 10 avril 2017 15:52, par PIVAR

            Merci , je ne veux pas gêner , mais on apprend vite avec vous ; dans la doc arduino ,pour define il est dit que cela sert à définir des constantes , vous êtes mieux que la doc !
            et ce que j’interprète de ce qu’aurait pu Christian :la fonction pinToggle à qui on a transmis la valeur aPin , ecrit à aPin le not de ce qu’on peut lire à aPin (surement que l’on peut mieux dire)
            Je suis curieux et je vais aussi acheter une Wemos mini pro qui se programme sous IDE arduino (7€),moins d’entrées sorties , avec un wifi intégré ..mais pour les timer , je me demande , très peu d’infos

            Répondre

            • Les Timers (II) 10 avril 2017 19:04, par Christian Bézanger

              Pour avoir de la documentation sur les timers, c’est très simple : il suffit de se référer à la datasheet du constructeur du microcontrôleur qui équipe la carte. C’est en anglais et ça ne se comprend pas forcément à la première lecture ; il faut s’accrocher, mais il n’y a que là qu’on trouve ce dont on a besoin.

              Répondre

              • Les Timers (II) 11 avril 2017 10:34

                Merci , c’est en effet en passant par le microcontroleur que l’on trouve des infos , pas par la datasheet qui est en chinois mais sur le web , d’autres se sont déjà posé les questions et se sont répandus ; bon , je ne polluerais plus votre site (bien tenu)
                D.P.

                Répondre

  • Les Timers (II) 9 avril 2017 22:47, par Dominique

    "Un petit truc , en ligne 14 on désactive les interruptions pour les réactiver en ligne 19 ; est-ce pour prendre en compte la nouvelle interruption ?"
    Non c’est pour éviter qu’une interruption arrive pendant la manipulation des registres, ce qui ficherait la pagaille !

    Répondre

  • Les Timers (II) mnemoniques des ISR 17 avril 2017 18:37, par Michel Jevaud

    J’ai cherché sur le web les mnémoniques arduino pour les interrupts : par exemple, vous avez trouvé la mnémonique ISR(TIMER2_OVF_vect) pour le débordement du Timer Counter n°2 (déjà, comment avez vous trouvé cette mnémonique ?), mais pour toutes les autres interrupts possibles ?
    Bon, on trouve à droite à gauche des exemples, par exemple heureusement pour le port série on a la routine serialEvent(), mais existe-t-il une liste officielle Arduino de ces mnémoniques ?
    un grand merci pour votre site, il est très clair

    Répondre

    • Les Timers (II) mnemoniques des ISR 17 avril 2017 19:45, par christian

      Tout cela est décrit dans la datasheet du microcontroleur ATmega328P qui peut être téléchargée sur le site Atmel.
      Quand on veut travailler avec les entrailles d’un microcontroleur, il faut toujours s’y référer.
      Pour le Timers 1, cela aurait été ISR(TIMER1_OVF_vect) : tout cela est donc assez logique et facile à manipuler. De la même façon, les noms des registres sont connus du compilateur.

      Répondre

  • Les Timers (II) 9 juillet 2020 11:30, par Schweitzer

    Bonjour , je suis en train de réaliser un programme avec les timer pour lire a toute les interruptions un signal analogiques cependant je ne sais pas pas ou est mon problème de compréhension. J’
    Je souhaite lire un signal de 50hz par exemple. Je sais que la fonction analogread doit prendre 116 us pour chaque lecture.

    /* Programme viisant a determiner la frequence et l'amplitude d'un signal simple compris entre 0/5V
     * pour un frequence de (50Hz , tension entre 0/5V
     * Soit une periode de 20ms , nous prendrons toute les 0.1 ms
     * 
     * Nous uiliserons le TIMER2 de l'arduino Mega2560;
     * 
    */
    
    /*** Signal SBT1************** ***********************************************/
    void Signal_SBT1(float Tension_SBT1_instant);
    
    #define S_SBT1 A0
    #define Val_SBT1 500 //Nombre de valeur souhaté (je devrais obtenir 2 periode de mon signal)
    
    int i=0;
    
    boolean var=0;
    
    float Tension_SBT1_instant;
    float Tension_SBT1_Tab[Val_SBT1]; 
    
    int   Nbr_x_0=0;
    
    boolean x=1;
    /******************************************************************************************/
    
    void setup()
     {  
      pinMode(S_SBT1,INPUT);
     
      cli();
      bitClear (TCCR2A, WGM20); // WGM20 = 0
      bitClear (TCCR2A, WGM21); // WGM21 = 0 
      
      TCCR2B = 0b00000010; // Clock /8 soit 0.1ms  
      TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
      sei();
      Serial.begin(9600);
    
     }
    
    byte flag=0;
    
    ISR (TIMER2_OVF_vect)
     {
        TCNT2=96;   
        
       if(flag++ >= 1) // toute les 0.1ms
       {
        flag=0;
        
       }
     }
    
    void loop() 
    {   
    
        if(flag==0)  // on verifie l'etat du compteur 
        {
        Tension_SBT1_instant=(analogRead(S_SBT1)*(5.000/1023));
        Signal_SBT1(Tension_SBT1_instant)
      
        }
    }
    
    
    
    void Signal_SBT1(float Tension_SBT1_instant)
    {
    
        if((Tension_SBT1_instant==0) && x==1)  //fonction permettant de debuter l'acquisition a 0; 
            {  
              Serial.println("debut de l'acquisition");
               var=1;
               x=0;
               i=0;
            }
            
            if(var == 1)
            { 
               Tension_SBT1_Tab[i]= Tension_SBT1_instant; 
               
               
               if(i==Val_SBT1)
               {
                Serial.println("********NOUS REGARDONS LES  VALEURS********");
                 for(i=0;i<=Val_SBT1;i++)   //analyse complet du tabeleau obtenu a
                 {
                   Serial.println();
                   Serial.print("Pour la valeurs : ");
                   Serial.print(i) ;
                   Serial.print("du tableau, nous observons une tension de: ");
                   Serial.println(Tension_SBT1_Tab[i]) ;
                   Serial.print("  Volt");
                   Serial.println();
                        
                 }
              
                  
                  
              
                i=0; // on remet i a 0;
                var=0; /on remet var a 0 qui permet de s'assurer du debut de l'acquisiton 0
                x=1; // Variable qui assure le fait que l'on entre qu'un seul fois dans la fonction (acquisition a 0 ) 
               }
              i++; // on incremente 
             }
      
    }

    Répondre

    • Les Timers (II) 9 juillet 2020 12:30, par Christian

      Juste une question : quelle est l’application au modélisme ferroviaire de ce que vous cherchez à faire ?
      En effet, nous ne répondons qu’aux questions qui ont un intérêt pour le modélisme ferroviaire afin d’en faire profiter toute la communauté. Selon votre domaine d’application, nous serons peut-être amenés à vous rediriger vers d’autres sites ou forum plus spécialisés, mais si cela a un intérêt pour l’ensemble de nos lecteurs, alors nous ferons tout notre possible pour vous aider.
      Bien cordialement.

      Répondre

      • Les Timers (II) 9 juillet 2020 13:39, par Schweitzer

        c’est un programme pour apprendre a utiliser arduino. en Application ferroviaire ou autre. Dans le future j’aimerai etre capable d’analyser des singaux simples , carré , continues , sinusoidale etc etc....

        J’ai vu des programme faisant des teste avec le theoreme de fourrier discret mais ce n’est pas encore dans mon niveau.
        En se qui concerne le ferroviaire il serait par exemple utile pour déterminer ou se situe un problème de réseau électrique. par exemple un problème d’alimentation .

        Répondre

        • Les Timers (II) 10 juillet 2020 10:45, par Christian

          Apprendre à utiliser Arduino est tout à fait louable et nous espérons que LOCODUINO aide le lecteur dans ce sens.
          Lorsque je parle d’application au modélisme ferroviaire, je pense plutôt à ce qui peut se passer sur un réseau de trains miniatures et surveiller une alimentation électrique est plutôt un problème d’électronique.
          Pour trouver de l’aide, le mieux serait pour vous d’ouvrir un fil sur notre forum dès maintenant, et comme les gens sont déjà en vacances, revenir à la charge à la rentrée.
          Enfin, puisque votre but est d’analyser des signaux avec Arduino, vous pouvez essayer de voir les différents articles et projets qui ont été écrits pour utiliser Arduino en tant qu’oscilloscope. Commencez votre recherche directement sur le site www.arduino.cc et ensuite, faites une recherche avec le moteur de recherche de votre navigateur.
          Je pense que cette façon de faire sera beaucoup plus efficace car votre domaine d’application n’est pas vraiment notre spécialité.

          Répondre

    • Les Timers (II) 9 juillet 2020 18:59, par Jean-Luc

      Bonsoir. Si analogRead prend 116 microsecondes comment peut on l’appeler toutes les 100 microsecondes ?

      Répondre

      • Les Timers (II) 10 juillet 2020 08:53, par Schweitzer

        C’etait un programme test car le probleme est que sur mon traceur séries , le signal s’affichait tout aussi bien que lorsque je mettais du 0.2ms et plus.
        _Le but de mettre du 0.1ms est la confirmation qu’il y a une erreur dans mon programme car si avec du 0.1 j’obtiens le meme résultats qu’avec du 0.3ms ou plus c’est que mon Timer ne fonctionne pas comme il devrait. Le probleme maitenant est de savoir ou .

        Répondre

        • Les Timers (II) 10 juillet 2020 10:51, par Jean-Luc

          Bonjour,

          C’est assez simple à comprendre : si le temps d’exécution du code entre 2 tops du timer est supérieur à la période du timer alors la période sera déterminée par le temps d’exécution et pas par le timer dont une partie des interruptions partira dans les choux car le programme n’a pas le temps de les traiter. Autrement dit, vous demandez au CPU de travailler à plus de 100% ce qu’il ne peut évidemment pas faire. (Sans parler des Serial.print dont le temps d’exécution dépend de la vitesse de la ligne série dès que le tampon d’émission est plein. Et à 9600 bauds ca va venir vite).

          Vous pouvez verifier que votre timer fonctionne à la période que vous souhaitez en mettant seulement l’incrémentation d’une variable dans la routine d’interruption et en affichant cette variable toutes les secondes dans loop.

          Répondre

  • Les Timers (II) 12 octobre 2020 16:54, par YOU Anthony

    Bonjour,
    Je suis en train de faire des essais pour monter autour des 400khz avec les interruptions.
    Celles ci semblent bloquées à 80khz, impossible de monté plus haut, est-ce normal ?
    Cordialement.

    Répondre

    • Les Timers (II) 12 octobre 2020 19:25, par Christian

      Je pense que la lecture de l’article suivant "Les Timers (III)" vous permettra de trouver une solution pour atteindre les 400 kHz.
      Vous avez un exemple avec des valeurs différentes qu’il suffira d’adapter.

      Répondre

      • Les Timers (II) 12 octobre 2020 20:24, par YOU Anthony

        J’ai effectué un essai avec le timer1 de la page suivante.
        J’ai mis le prescaler sur 1 et OCR1A à 80. En théorie, je devrais avoir une fréquence de 100KHz (puisque c’est un toggle).
        Pourtant j’ai un signal de sortie a 35.5KHz.

        Répondre

        • Les Timers (II) 12 octobre 2020 21:58, par YOU Anthony

          Je viens de me rendre compte qu’il y a une limite du à l’utilisation de digitalWrite et digitalRead.
          si je fais une boucle avec juste digitalwrite low puis high et ça me fait un signal a 127khz.

          Répondre

          • Les Timers (II) 13 octobre 2020 09:43, par Christian

            Effectivement, les fonctions d’Arduino comme digitalRead ou digitalWrite prennent du temps pour être exécutées, et forcément cela va ralentir l’exécution de votre programme donc la création d’un signal à 400 kHz, voire moins comme dans cet essai.
            C’est le revers de la médaille, d’un côté on nous propose des fonctions simples à utiliser, mais d’un autre côté ces fonctions ne sont pas optimum dans certains cas.
            La solution, c’est de se rapprocher du microcontrôleur et donc de le programmer d’une autre façon, plus rapide. Pour inverser l’état de la LED, il faut directement intervenir sur le port de sortie (donc écrire sur ce port) de la même façon que vous savez écrire dans les registres du microcontrôleur.
            Si vous n’êtes pas familier, je vous conseille de regarder le chapitre 28 de mon cours d’électronique (article démarrer en électronique, dans la rubrique composants électroniques) qui s’appelle : La face cachée des fonctions pinMode, digitalWrite et digitalRead.
            Cela devrait résoudre votre problème puisque écrire directement dans le port ne prendra que quelques cycles d’horloge (à 16 MHz, un cycle dure 62,5 nanosecondes) et cela ne devrait pas perturber (ou très peu) un signal de 400 kHz).

            Répondre

  • Les Timers (II) 13 octobre 2020 11:15, par YOU Anthony

    Je pense que je vais me replonger dans mes vieux cours et le programmer directement. ça m’amusera plus et fera remonter de bons souvenirs :)

    Répondre

    • Les Timers (II) 13 octobre 2020 11:32, par Christian

      Ecrire directement dans le port peut améliorer l’obtention du signal.
      Mais dans certain cas, il est nécessaire de programmer directement le microcontrôleur en langage machine et donc utiliser l’assembleur. L’IDE permet de le faire mais quelle galère ! Je l’ai fait une fois avec le programme Blink et effectivement, mon code était plus concis qu’avec la compilation classique.
      Mais si on doit se lancer dans cette aventure, il vaut mieux se procurer les bons outils et donc un vrai programme d’assemblage.
      Après, il faut aussi pouvoir déboguer : en assembleur, c’est aussi une autre histoire !
      C’est pourquoi, sur ce site qui est fait surtout pour des amateurs (et souvent débutants), nous restons fidèles au bon vieux IDE qui utilise gcc.
      Allez voir l’article de Thierry https://www.locoduino.org/spip.php?...;: ce sera aussi un bon début pour vous y remettre.

      Répondre

      • Les Timers (II) 13 octobre 2020 11:47, par Thierry

        Une autre possibilité est d’utiliser une bibliothèque comme DIO2 (chercher dans l’IDE ou prendre là : https://github.com/Locoduino/DIO2) qui permet de réduire fortement la latence générée par digitalWrite et Read. Cette bibliothèque fournit de nouvelles fonctions digitalWrite2 et digitalRead2 bien plus proches du matériel et donc plus rapides.

        Répondre

  • Les Timers (II) 2 décembre 2021 19:35, par tribion

    Bonjour, je m’arrache les cheveux depuis plusieurs jours, je dois mal m’y prendre.
    J’ai une ILS sous une rame qui est sur l’interrupt 0 (pin2), cela fonctionne parfaitement.
    cependant j’aimerais que l’orsque cette interruption a lieu, sa lance le timer2 afin d’avoir une temporisation non bloquante car actuellement elle me fige le programme.
    Merci

    Répondre

    • Les Timers (II) 2 décembre 2021 20:34, par Christian

      Il suffit de mettre le code d’utilisation du timer2 dans l’ISR liée à l’interruption 0 (celle de la pin 2).
      Lorsque le timer2 débordera, il exécutera une autre ISR dans laquelle vous mettrez le traitement à exécuter.
      L’espace en fin d’articles est plutôt réservé aux questions sur l’article lui-même ; pour des problèmes techniques, utilisez plutôt notre forum où beaucoup plus de monde pourra vous aider.

      Répondre

Rubrique Programmation

Les derniers articles

Les articles les plus lus