🏗️ Zealot - en construction 🏗️

headerContent
open

Arduino

Le projet Arduino permet de réaliser des prototypes, de se familiariser avec l'électronique numérique et la programmation temps réel.

Interruptions

Les interruptions sont exécutées de manière prioritaire, le programme est interrompu; la pile est sauvegardée et le microcontrôleur execute la fonction d'interuption ou ISR.
Les interruptions , qui se classe par priorité, sont de deux types :

  • internes : déclenchées par logiciel
  • externes : déclenchées par un changement d'état en entrée

Pour gérer les interruptions externes; on doit réserver une entrée pour détecter et déclencher l'interruption. Il faut configuer les registres du microcontrôleur.

Choix de l'entrée

Dans un premier temps on va déterminer une entrée. Les broches du microcontroleur peuvent avoir plusieurs fonctions.
On évite d'utiliser les broches reservées à la communication et on choisit le niveau d'interuption adaptée au besoins.
Il faut se documenter, une recherche sur internet pourra vous aiguiller. La lecture de cette page vous aidera comprendre la méthode.

La plateforme Arduino MEGA propose 54 broches, nous preferons employer une entrée analogique inutilisée.
Nous utiliserons la borne A8 de la carte.

La section : Pin Configurations, la figure 1-1 , de la documentation du microcontroleur confirme les informations du site. La borne A8 de la carte Arduino Mega correspond a la broche 89 du microconteleur.

La broche 89, identifié PK0 est associé au bit 0 du port d'entrees sorties K. Elle a les fonctions :
ADC8, entrée analogique
PCINT16, interuption externe.

Le tableau 13-30 reprend les interruptions PCINT16 à PCINT23 associés au port K. Nous employons l'interruption de priorité la plus elevée sur ce port.

Configuration des registres

Par défaut l'interruption n'est pas activée, il faut utiliser un registre du microcontroleur pour l'activer. Pour trouver le registre correspondant on recherche l'interruption PCINT16 dans la documentation.

On met le bit 0, PCINT16, du registre PCMSK2 à 1 pour activer l'interruption : PCMSK2 |= ( 1 << PCINT16);

En lisant attivement les informations sur le registre PCMSK2, on nous dit qu'il faut initialiser le bit 2 du registre PCICR
On met le bit 2, PCIE2 , du registre PCICR à 1 pour activer l'interruption : PCICR |= (1 << PCIE2);

Traitement de l'interruption

Pour exploiter l'interruption on utilise une fonction ISR dans l'IDE arduino. ISR recoit le vecteur d'interruption.
On declare la routine d'interruption ou ISR en precisant le vecteur d'interruption ISR(PCINT2_vect).
ici on definit un flag ou variable ,change pour permettre un traitment ultérieur.

ISR( PCINT2_vect ) { change = true; }
Le traitement d'une interruption externe déclenchée par un bouton poussoir ou un contact électrique nécessite un circuit RC anti rebond.

Les interruptions peuvent gérer les signaux PWM

Signal PWM

Le signal PWM est exploité en modelisme et robotique pour controler les servos et variateur.

L'état haut à une durée variable de 1 à 2 ms
La période est d'environ 20ms.

On déduit, de la durée del'état haut , une commande proportionnelle de 0% à 100%.
Ceci permet de réaliser une commande analogique avec des entrees et sortie numérique. Ce signal a aussi l'avantage de permettre une detection d'une coupure de ligne.

Pour mesurer le signal de commande on doit detecter les fronts montant et descendants.
On détermine la durée du signal de commande entre un front montant et un front descendant.
On mesure l'interval entre les fronts montants pour determiner la période.

Lecture PWM

Détection des fronts

A chaque changement d'état, le microncontroleur declenche une interruption.
Si l'état actuel est 0 et l'etat precedent 1 alors le front est descendant.
Si l'état actuel est 1 et l'etat precedent 0 alors le front est montant.

On commence le cycle de mesure, seulement apres avoir detecter un front descendant suivi du front montant ceci pour synchroniser le processus de mesure.
Au second front montant on pourra determiner la mesure de duree et de la période.

Durée du signal de commande

La duree du signal de commande se mesure entre deux fronts montants.On sauvegarde le temps au debut du cycle sur le front montant. On stocke le temps sur le front descendant qui suit le front descendant. Lorsque l'on detecte le front du cycle suivant on calcule et stocke la duree du signal de commande

Période

La période se détermine elle aussi entre deux fronts montants, lorsque survient le front montant suivant le cycle écoulé.
Les conditions sont réunis pour indiquer au programme principale que la lecture de la commande et de la période est terminée.

Le programme principale réalise les calculs et mesure le signal depuis les variables et exploite les resultats.

Ecriture PWM

Pour transmettre un signal PWM sur une sortie il est nécessaire de configurer le Timer

Timer

Nous avons abordé la lecture de signaux PWM issue par exemple d'un récepteur 2,4ghz. Le microcontrôleur gère des signaux en PWM en entrée et sortie
Pour décharger le processeur et la mémoire le microcontrôleur comporte des compteurs permettant de générer des signaux PWM, ces compteurs utilisent l'horloge principale du microcontrôleur.
Pour notre application nous utiliserons un signal PWM cadencé à 50Hz soit une période de 20ms sur la borne D5.
Nous allons utiliser le Timer 3 qui permet de commander indépendamment 3 sorties PWM au moyen de 3 comparateurs.
Les 3 sorties associés au comparateur du Timer 3 sont les bornes.

  • D5 PWM associé à la broche PE3/OC3A/AIN1
  • D2 PWM associé à la broche PE4/OC3B/INT4
  • D3 PWM associé à la broche PE5/OC3C/INT5
Le fonctionnent des compteurs et les registres associés sont détaillées a partir de la page P133 chapitre 17 compteurs PWM 16bit de la documentation du microcontrôleur.

Les registres du Timer3

La mise en oeuvre des compteurs va nécessiter de manipuler les registres du microcontroleur. Nous utilsons une seule sortie D5.
Les registres 16 bits comme OCR3A sont répartis sur 2 octets OCR3AH et OCR3AL mais nous pouvons y accéder directement en utilisant, un mot (2 octets), OCR3A.

Voici la liste des registres que nous emploierons, la section de la documentation est indiqué entre parenthèse.
  • TCCR3A - Timer/Counter 3 Control Register A ( 17.11.2 )
  • TCCR3B - Timer/Counter 3 Control Register B ( 17.11.6 )
  • OCR3 OCR3AH and OCR3AL - Output Compare Register 3 A ( 17.11.20 )
  • ICR3 ICR3H and ICR3L - Input Capture Register 3 ( 17.11.30 )

Configuration du du Timer3

Activation des sorties

Le registre TCCR3A permet de choisir les sorties qui renverront le signal PWM.
On utilise la borne D5 on active le bit COM3A1 : TCCR3A = _BV(COM3A1) ;
Pour utiliser les 3 sorties on utiliserait : TCCR3A = _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);

Mode de fonctionnement

Le bit WGM33 du registre TCCR3B permet de déterminer le mode de fonctionnement. Ici le mode 8, PWM frequence et phase correctes.
Voir 17.9.5 : phase and frequency correct Pulse Width Modulation, ce mode serait plus adapté au controle des moteurs.

Le bit CS31 du registre TCCR3B permet de régler le prédiviseur du compteur. Le rapport choisi est de 8.
Ce prediviseur permet de disposer d'une grande plage de fréquence. ce rapport interviendra dans le calcul de la fréquence.

reglage de la frequence PWM

On doit cadencé le signal à 20Hz, une formule est donnée pour la déterminer. La formule, Voir 17.9.5, est inversé pour retrouver la valeur du registre ICR3.
Le registre ICR3 comptient la valeur de fin comptage qui règle la frequence.

Pour calculer la valeur de fin comptage ICR3, on doit connaitre :

  • la fréquence d'horloge, fc, du microcontroleur, ici 16MHz donc 16 000 000 Hz.
  • le prédiviseur CS3 = 8 réglé avec le seul bit CS31 à 1
  • la frequence f de PWM : ici 50Hz
L'inversion de la formule se fait avec un peu de mathématiques
on donne : f = fc / ( 2 x CS3 x ICR3) ; on écrit : f x ( 2 x CS3 x ICR3) = fc et pour finir : ICR3 = fc / ( f x 2 x CS3 )

Une application numérique pour f= 50hz , fc = 16 000 000 et CS3 = 8, on obtient ICR3 = 16 000 000 / ( 50 x 2 x 8) = 20 000
Pour une période de 15ms, lue sur un simulateur on aurait 66,7Hz et ICR3 = 16 000 000 / ( 66,7 x 2 x 8) = 14992

durée du signal de commande

Avec ces réglages la durée de la période est réglée directement dans OCR3A et exprimée en microsecondes

Nous devons générer un signal de commande de 1ms à 2ms, la position neutre est obtenu pour une valuer de 1,5ms.
On règle cette durée, également en microseondes, soit 1000, 1500 ou 2000 µs et on l'écrit dans le registre OCR3A

La sortie, ici la borne D5 de la carte, est configuré en sortie : pinMode(5, OUTPUT);
La sortie D5 correpondant correspond à la broche PE3 / OCR3A, elle restera à 1 tant que TCNT3 < OCR3A
Par défaut on stocke une valeur de 1500 pour envoyer un signal neutre : OCR3A = 1500;