Outils pour utilisateurs

Outils du site


arduinoisr

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
arduinoisr [2017/11/06 22:18]
bvandepo
arduinoisr [2020/01/27 16:43] (Version actuelle)
bvandepo
Ligne 61: Ligne 61:
 Dans l'​onglet "​Outils",​ accédez au menu "Port Série"​ et cliquez sur la valeur /​dev/​ttyACM0 ou /​dev/​ttyUSB0. Accédez aussi eu menu "​Carte"​ et vérifiez que la valeur sélectionnée est "​Arduino Uno". Dans l'​onglet "​Outils",​ accédez au menu "Port Série"​ et cliquez sur la valeur /​dev/​ttyACM0 ou /​dev/​ttyUSB0. Accédez aussi eu menu "​Carte"​ et vérifiez que la valeur sélectionnée est "​Arduino Uno".
 ==== Votre premier sketch ==== ==== Votre premier sketch ====
-Maintenant que l'editeur ​est lancé, nous pouvons entrer dans la fenêtre le programme suivant+Maintenant que l'éditeur ​est lancé, nous pouvons entrer dans la fenêtre le programme suivant
    
 <file cpp blink.ino>​ <file cpp blink.ino>​
Ligne 99: Ligne 99:
  
 ==== Précautions à prendre avec la plateforme et l'IDE ==== ==== Précautions à prendre avec la plateforme et l'IDE ====
-<color red>​Sauvegarder vos fichiers en LOCAL sur la machine dans le dossier /​home/​IUT/"​login"/​Sketchbook/ et copier ces fichiers vers le disque réseau /​mnt/​ponsan..../​ A CHAQUE FIN DE SEANCE!!!</​color>​+<color red>​Sauvegarder vos fichiers en LOCAL sur la machine dans le dossier /​home/​IUT/"​login"/​Arduino/ et copier ces fichiers vers le disque réseau /​mnt/​ponsan..../​ A CHAQUE FIN DE SEANCE!!!</​color>​
   * Sauvegarder vos programmes sous des noms différents pour chaque exercice   * Sauvegarder vos programmes sous des noms différents pour chaque exercice
   * Lors de la sauvegarde, une fenêtre apparaît pour demander quels noms donner au programme. Si vous ne faites pas attention, cette fenêtre peut passer en arrière plan et l'IDE Arduino ne répondra plus à aucune sollicitation tant que vous n'​aurez pas ré-ouvert cette fenêtre.   * Lors de la sauvegarde, une fenêtre apparaît pour demander quels noms donner au programme. Si vous ne faites pas attention, cette fenêtre peut passer en arrière plan et l'IDE Arduino ne répondra plus à aucune sollicitation tant que vous n'​aurez pas ré-ouvert cette fenêtre.
Ligne 108: Ligne 108:
  
  
-=====Comment gérer l'​absence de déboggeur=====+=====Comment gérer l'​absence de débogueur=====
 Nous allons utiliser la librairie Serial pour échanger des caractères ASCII entre le PC et la carte Arduino de manière bidirectionnelle. Vous pouvez accéder au descriptif de cette librairie en sélectionnant le menu "​Aide"​ puis le menu "​Référence"​. Nous allons utiliser la librairie Serial pour échanger des caractères ASCII entre le PC et la carte Arduino de manière bidirectionnelle. Vous pouvez accéder au descriptif de cette librairie en sélectionnant le menu "​Aide"​ puis le menu "​Référence"​.
  
-Le deboggage ​de votre application pourra se faire à l'aide d'​affichage vers la console MAIS il faut tenir compte du fait que le code ainsi modifié ne sera pas exactement le même code que celui sans les appels d'​affichage.+Le debogage ​de votre application pourra se faire à l'aide d'​affichage vers la console MAIS il faut tenir compte du fait que le code ainsi modifié ne sera pas exactement le même code que celui sans les appels d'​affichage.
  
 Egalement, vous pourrez utiliser des broches du microcontroleur pour indiquer l'​entrée ou la sortie d'une portion de code, afin de tester précisement le timing. Egalement, vous pourrez utiliser des broches du microcontroleur pour indiquer l'​entrée ou la sortie d'une portion de code, afin de tester précisement le timing.
Ligne 142: Ligne 142:
 { {
   char car ;   char car ;
-  if (Serial.available()){+  if (Serial.available()>0){
      car = Serial.read();​      car = Serial.read();​
      if ( (car>​='​a'​) && (car<​='​z'​) )      if ( (car>​='​a'​) && (car<​='​z'​) )
Ligne 151: Ligne 151:
 </​file> ​ </​file> ​
  
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​TODO.jpg}} Compiler et charger ce programme sur la carte.
 ==== Utilisation de la console série sur le PC ==== ==== Utilisation de la console série sur le PC ====
  
Ligne 168: Ligne 169:
 Les caractères émis par l'UART HARD du Arduino doivent ensuite s'​afficher dans la partie basse de la fenêtre. Les caractères émis par l'UART HARD du Arduino doivent ensuite s'​afficher dans la partie basse de la fenêtre.
  
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​TODO.jpg}} Vérifier la communication avec la carte Arduino en utilisant le programme chargé ​ précédemment.
  
 ===== Exercice 2 : Accès bas niveau aux broches du microcontroleur===== ===== Exercice 2 : Accès bas niveau aux broches du microcontroleur=====
Ligne 181: Ligne 183:
  
  
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​TODO.jpg}} Ecrire un programme le plus simple possible permettant de générer un signal carré de rapport cyclique 50% et de période la plus courte possible. On autorisera ici à écrire une boucle while(1) dans la fonction loop(). Afin d'​obtenir un rapport cyclique de 50%, vous pourrez faire appel à l'​instruction suivante qui génère un délai de 62.5ns (soit 1 cycle à 16Mhz):
 +  __asm__("​nop\n\t"​); ​
  
-A faireEcrire un programme ​le plus simple possible permettant de générer un signal ​carré de rapport cyclique 50% et de période ​la plus courte possible+<ifauth @prof> 
 +===Solution:=== 
 +Avec DigitalWrite,​ impossible d'​obtenir des périodes inférieures à 10us. Avec accès via registres, ​le signal ​généré est de période ​0.5us soit de fréquence 2Mhz: 
 +<file cpp carre.ino>​ 
 +    void setup() ​  
 +    { 
 +      pinMode(8, OUTPUT); ​   
 +    } 
 +    void loop() 
 +    { 
 +    while(1) { 
 +      PORTB &= ~0x01 ; 
 +      __asm__("​nop\n\t"​);​  
 +      __asm__("​nop\n\t"​);​  
 +      PORTB |= 0x01 ; 
 +      } 
 +    } 
 +</​file>​ 
 +</​ifauth>​
  
 ===== Exercice 3 : Gestion du temps sur le  microcontroleur===== ===== Exercice 3 : Gestion du temps sur le  microcontroleur=====
 La gestion du temps peut se faire généralement de deux manières: La gestion du temps peut se faire généralement de deux manières:
-  - La plus simple consiste à faire appel à des boucles d'​attente durant lesquelles le processeur perd du temps à ne (quasiment) rien faire. Les fonctions Arduino ​Delay(...) et DelayMicrosecond(...) utilisent ce principe. Le problème est que les temps d'​attente s'​ajoutent à la durée d'​exécution des instructions (de calcul etc...) ce qui conduit à une mauvaise maîtrise du temps.+  - La plus simple consiste à faire appel à des boucles d'​attente durant lesquelles le processeur perd du temps à ne (quasiment) rien faire. La plus petite durée d'​attente possible est obtenue en exécutant l'​instruction assembleur NOP. Les fonctions Arduino ​delay(...) et delayMicroseconds(...) utilisent ce principe ​pour des durées plus longues exprimées en millisecondes et en microsecondes. Le problème est que les temps d'​attente s'​ajoutent à la durée d'​exécution des instructions (de calcul etc...) ce qui conduit à une mauvaise maîtrise du temps.
   - La seconde méthode consiste à faire appel à un périphérique intégré au microcontroleur:​ le TIMER, qui va (dé)compter des périodes d'un signal de référence,​ généralement l'​horloge système du microcontroleur (ou un signal générée à partir du signal de référence mais dont la fréquence aura pu être prédivisée par un facteur entier réglable). Pour générer un signal périodique,​ le timer pourra être configuré en mode rechargement automatique. Afin de générer des périodes plus longue que ce qu'il est possible d'​obtenir juste avec le prédiviseur et le timer, il est possible de mettre ​ en cascade un facteur de prédivision,​ un facteur de timer matériel suivi d'un facteur de compteur logiciel, ce dernier étant réalisé à l'aide d'une variable et d'​opérations de calcul. ​   - La seconde méthode consiste à faire appel à un périphérique intégré au microcontroleur:​ le TIMER, qui va (dé)compter des périodes d'un signal de référence,​ généralement l'​horloge système du microcontroleur (ou un signal générée à partir du signal de référence mais dont la fréquence aura pu être prédivisée par un facteur entier réglable). Pour générer un signal périodique,​ le timer pourra être configuré en mode rechargement automatique. Afin de générer des périodes plus longue que ce qu'il est possible d'​obtenir juste avec le prédiviseur et le timer, il est possible de mettre ​ en cascade un facteur de prédivision,​ un facteur de timer matériel suivi d'un facteur de compteur logiciel, ce dernier étant réalisé à l'aide d'une variable et d'​opérations de calcul. ​
  
Ligne 194: Ligne 215:
 Dans le cas de l'​utilisation d'un timer servant à déclencher l'​exécution d'une tâche périodique,​ il est possible de mettre en oeuvre deux approches: Dans le cas de l'​utilisation d'un timer servant à déclencher l'​exécution d'une tâche périodique,​ il est possible de mettre en oeuvre deux approches:
   - La **scrutation** consiste à venir tester l'​état d'un indicateur (bit d'un registre) régulièrement afin de détecter le débordement du timer par exemple. Cette approche permet d'​intégrer le code de la tâche périodique à l'​intérieur du programme principale mais ne permet pas une très bonne maîtrise du temps, ce qui peut conduire à de la gigue.   - La **scrutation** consiste à venir tester l'​état d'un indicateur (bit d'un registre) régulièrement afin de détecter le débordement du timer par exemple. Cette approche permet d'​intégrer le code de la tâche périodique à l'​intérieur du programme principale mais ne permet pas une très bonne maîtrise du temps, ce qui peut conduire à de la gigue.
-  - L'​**interruption** consiste à interrompre l'​exécution de la tâche en cours (généralement le programme principal) pour aller exécuter un programme spécifique à l'​événement qui l'a déclenchée. L'​exécution du programme qui a été interrompu reprend généralement à la fin de l'​exécution du programme d'​interruption. Cette approche permet généralement une meilleure maîtrise du temps séparant l'​occurence de l'​événement et l'​exécution du programme associé mais nécessite des précautions ainsi qu'une configuration adéquate.+  - L'​**interruption** consiste à interrompre l'​exécution de la tâche en cours (généralement le programme principal) pour aller exécuter un programme spécifique à l'​événement qui l'a déclenchée. L'​exécution du programme qui a été interrompu reprend généralement à la fin de l'​exécution du programme d'​interruption. Cette approche permet généralement une meilleure maîtrise du temps séparant l'​occurence de l'​événement et l'​exécution du programme associé mais nécessite des précautions ainsi qu'une configuration adéquate. Afin de vérifier le bon réglage du timer ainsi que le temps passé dans le programme d'​interruption (qui doit être inférieur à la période entre deux interruptions),​ nous conseillons d'​utiliser une broche du microcontroleur qui sera par exemple mise à 1 à l'​entrée dans le programme d'​interruption puis remise à 0 au moment de la sortie.
  
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​TODO.jpg}} Dans un premier temps, modifier votre programme précédent pour générer un signal de rapport cyclique 50% et de période ​ 624us à l'aide de la fonction delayMicroseconds(...). Vérifier à l'​oscilloscope le signal obtenu et adapter votre programme.
  
 +<ifauth @prof>
 +===Solution:​===
 +<file cpp carre2.ino>​
 +       void setup()  ​
 +    {
 +         ​pinMode(8,​ OUTPUT); ​  
 +    }
 +    void loop()
 +    {
 +    while(1) {
 +      PORTB &= ~0x01 ;
 +      __asm__("​nop\n\t"​); ​
 +      __asm__("​nop\n\t"​); ​
 +      delayMicroseconds(311); ​      
 +      PORTB |= 0x01 ;
 +      delayMicroseconds(311); ​      
 +      }
 +    }
 +</​file>​
 +</​ifauth>​
  
-A faire: +{{http://homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​TODO.jpg}} Ensuite, générer le même signal en faisant appel à l'​interruption TIMER. Conseil: utiliser le timer 2 et lire la documentation de l'​ATMEGA328P pour sa configuration. ​
-  - Dans un premier temps, modifier votre programme précédent pour générer un signal de rapport cyclique 50% et de période ​ 624us à l'aide de la fonction DelayMicrosecond(...). Vérifier à l'​oscilloscope le signal obtenu et adapter votre programme. +
-  - Ensuite, générer le même signal en faisant appel à l'​interruption TIMER. Conseil: utiliser le timer 2 et lire la documentation de l'​ATMEGA328P pour sa configuration.+
  
 +
 +<ifauth @prof>
 +===Solution:​===
 +<file cpp carre3.ino>​
 +//624us de période=312us de demi période (entre chaque interruption)
 +//                =156*32*62.5ns
 +void setupTimer2(){
 +  TCCR2A = 0;// set entire TCCR2A register to 0
 +  TCNT2  = 0;//​initialize counter value to 0 
 +  OCR2A = 156-1;// (must be <256)
 +  // turn on CTC mode
 +  TCCR2A |= (1 << WGM21);
 +  //​prescaler= 1/32 , see p162 https://​docs.google.com/​viewer?​a=v&​pid=sites&​srcid=ZGVwaW5mb25hbmN5Lm5ldHxtaW5lc3xneDo0NjFmYzI1NTdkZDU2YmE2
 +  TCCR2B = (1 << CS21)|(1 << CS20);
 +  // enable timer compare interrupt
 +  TIMSK2 |= (1 << OCIE2A); ​
 +}
 +// TIMER ISR VECTOR and configuration
 +ISR(TIMER2_COMPA_vect){
 +     PORTB ^= 0x01 ;
 +}
 +void setup() ​   ​
 +    {
 +    pinMode(8, OUTPUT); ​  
 +    cli();//​stop interrupts
 +    setupTimer2();​ // setup interrupt with prescaler (see datasheet for prescaler value, and reload value)
 +    sei();//​allow interrupts
 +    }
 +void loop()
 +    {
 +    }
 +</​file>​
 +</​ifauth>​
  
 ===== Exercice 4 : Gestion des bits sur le  microcontroleur===== ===== Exercice 4 : Gestion des bits sur le  microcontroleur=====
-Le signal numérique a générer sur la broché ​est généralement issu d'une valeur sur plusieurs bits qui est **sérialisée**. Ceci revient, à chaque période bit, à extraire la valeur du bit (depuis une variable par exemple) et a appliquer ​une valeur dépendante ​de ce bit sur la broche.+Le signal numérique a générer sur la broche ​est généralement issu d'une valeur sur plusieurs bits qui est **sérialisée**. Ceci revient, à chaque période bit, à extraire la valeur du bit (depuis une variable par exemple) et a appliquer ​un signal dépendant ​de ce bit sur la broche.
  
 +
 +
 +=====Programme d'​exemple=====
 +<file cpp exemple.ino>​
 +
 +
 +//macro à activer pour afficher des infos de debug dans le programme, la commenter sinon
 +//#define DEBUG
 +
 +    //int led = A2; //si le shield RS232 est présent ​
 +    int led =   3; //si le shield RS232 n'est pas présent, pour utiliser la led de la carte UNO
 +    // the setup routine runs once when you press reset:
 +    void setup() {                ​
 +      // initialize the digital pin as an output.
 +      pinMode(led,​ OUTPUT); ​    
 +       ​Serial.begin(9600); ​
 +      Serial.println("​Hello,​ world?"​);​ // Envoi de la chaîne terminée par un saut de ligne
 +   
 +    }  ​
 +     ​unsigned int compteur=0;
 +    // the loop routine runs over and over again forever:
 +    void loop() {
 +      /*
 +      compteur=compteur+1;​
 +      digitalWrite(led,​ HIGH); ​  // turn the LED on (HIGH is the voltage level)
 +      delay(3); ​
 +        Serial.println("​+"​);​ // Envoi de la chaîne terminée par un saut de ligne
 +      ​
 +      //if (false)// wait for a second
 +      {
 +        digitalWrite(led,​ LOW);    // turn the LED off by making the voltage LOW
 +       ​delay(200); ​              // wait for a second
 +       ​Serial.println("​."​);​ // Envoi de la chaîne terminée par un saut de ligne
 +
 +      }
 +
 +      Serial.println(compteur);​
 +*/
 +
 +#ifdef DEBUG
 +  Serial.println("​je debuggue"​);​
 +#endif
 +  ​
 +/*
 +
 +char car;
 +  if (Serial.available()>​0){
 +         car = Serial.read();​
 +         if ((car%2)==0) //est ce que le code ascii est pair?
 +           ​digitalWrite(led,​ HIGH); ​  
 +         else
 +           ​digitalWrite(led,​ LOW);   
 +           
 +
 +  }
 +  */
 +
 +  /* génère un signal de fréquence 102kHz)
 + ​digitalWrite(led,​ HIGH); ​
 + ​digitalWrite(led,​ LOW);    ​
 + */
 +
 +
 + //la broche 3 de l'​arduino est connectée au bit 3 du port D
 +
 +   /* génère un signal de fréquence 841.5kHz)
 +    PORTD|=0x8; // met à 1 le bit 3 du port D
 + ​PORTD&​= ~0x8;  // met à 0 le bit 3 du port D
 +    */
 +
 +
 +/* génère un signal de fréquence 2,​664MHz) ​   ​
 +    while(1){
 + ​PORTD|=0x8;​ // met à 1 le bit 3 du port D
 + ​PORTD&​= ~0x8;  // met à 0 le bit 3 du port D
 +    }
 +    */
 +
 +// génère un signal de rapport cyclique 50% de fréquence 2MHz)    ​
 +while(1){
 + ​PORTD|=0x8;​ // met à 1 le bit 3 du port D
 + ​__asm__("​nop\n\t"​); ​
 + ​__asm__("​nop\n\t"​); ​
 + ​PORTD&​= ~0x8;  // met à 0 le bit 3 du port D
 +    }
 +
 +    ​
 +    }
 +
 +
 +</​file>​
arduinoisr.1510003098.txt.gz · Dernière modification: 2017/11/06 22:18 par bvandepo