La section 3 de notre article sur les registres de contrôle du microcontrôleur de la carte Arduino est consacrée à l’utilisation des registres pour contrôler les périphériques externes. Dans cette section, nous allons expliquer comment utiliser les registres pour clignoter une LED et contrôler un servomoteur. Nous allons également expliquer comment les registres permettent un contrôle plus fin sur les broches d’entrée/sortie, offrent une vitesse accrue par rapport aux fonctions prédéfinies et permettent une gestion plus fine de l’énergie.
- Contrôler une LED à l’aide des registres La LED est l’un des composants les plus couramment utilisés dans les projets électroniques, et l’un des plus simples à contrôler. Dans cette section, nous allons expliquer comment utiliser les registres pour clignoter une LED connectée à une broche d’entrée/sortie (GPIO).
La première étape consiste à déclarer la broche GPIO à l’aide de la fonction pinMode. Dans cet exemple, nous allons utiliser la broche 13 :
int LED_PIN = 13; // déclarer la broche de la LED
void setup() {
pinMode(LED_PIN, OUTPUT); // configurer la broche comme sortie
}
Ensuite, nous pouvons utiliser la fonction digitalWrite pour allumer ou éteindre la LED. Toutefois, cette méthode utilise une fonction prédéfinie qui est relativement lente en termes de temps de traitement, ce qui peut être un problème si vous devez effectuer des opérations rapides et répétitives. Une alternative consiste à utiliser les registres directement pour contrôler la broche.
La broche 13 correspond au port B5 du microcontrôleur ATmega328P utilisé dans la plupart des cartes Arduino. Pour allumer la LED, nous devons écrire une valeur 1 dans le cinquième bit (comptant à partir de 0) du registre PORTB :
void loop() {
PORTB |= (1 << PB5); // allumer la LED
delay(1000); // attendre 1 seconde
PORTB &= ~(1 << PB5); // éteindre la LED
delay(1000); // attendre 1 seconde
}
Ce code utilise l’opérateur de décalage << pour déplacer la valeur 1 sur le cinquième bit de la variable PB5, qui correspond à la broche 13. L’opérateur binaire | est utilisé pour écrire cette valeur dans le registre PORTB, ce qui allume la LED. Lorsque nous voulons éteindre la LED, nous utilisons l’opérateur de négation ~ pour inverser la valeur de PB5 et l’opérateur & pour écrire cette valeur dans le registre PORTB.
- Contrôler un servomoteur à l’aide des registres Les servomoteurs sont des composants qui permettent de contrôler la position angulaire d’un axe de rotation. Ils sont largement utilisés dans les projets de robotique, de drones et d’automatisation. Dans cette section, nous allons expliquer comment utiliser les registres pour contrôler un servomoteur connecté à une broche PWM.
Les servomoteurs fonctionnent en recevant des signaux de commande PWM (modulation de largeur d’impulsion) qui définissent la position angulaire souhaitée. Le signal PWM est un signal carré dont le rapport cyclique (la durée de l’impulsion par rapport à la période totale) varie en fonction de la position souhaitée. La plupart des cartes Arduino ont plusieurs broches PWM qui permettent de générer des signaux PWM avec une résolution de 8 bits (256 niveaux de largeur d’impulsion).
Dans cet exemple, nous allons utiliser la broche 9 pour contrôler un servomoteur. Nous allons également utiliser la bibliothèque Servo pour simplifier le contrôle du servomoteur :
#include <Servo.h>
int SERVO_PIN = 9; // déclarer la broche du servomoteur
Servo servo_motor; // créer une instance de la bibliothèque Servo
void setup() {
servo_motor.attach(SERVO_PIN); // attacher le servomoteur à la broche 9
}
void loop() {
for (int angle = 0; angle <= 180; angle += 1) {
servo_motor.write(angle); // définir l'angle de rotation
delay(10); // attendre 10 ms
}
}
Ce code utilise la fonction attach de la bibliothèque Servo pour attacher le servomoteur à la broche 9. La fonction write est utilisée pour définir l’angle de rotation souhaité, qui varie de 0 à 180 degrés dans une boucle for. La fonction delay est utilisée pour attendre 10 ms entre chaque changement d’angle.
Cependant, la bibliothèque Servo utilise également des fonctions prédéfinies qui peuvent ralentir le temps de traitement. Si vous devez effectuer des opérations rapides et répétitives, vous pouvez utiliser les registres directement pour contrôler la broche PWM.
La broche 9 correspond au port B1 du microcontrôleur ATmega328P, qui est associé au compteur de 16 bits TIMER1. Ce compteur peut générer des signaux PWM avec une résolution de 16 bits, offrant une précision de contrôle beaucoup plus fine que les broches PWM standard. Le registre de contrôle du compteur TIMER1 est le registre TCCR1B.
Pour générer un signal PWM avec une résolution de 16 bits, nous devons configurer le compteur TIMER1 pour qu’il utilise le mode Fast PWM avec ICR1 comme valeur maximale. La fréquence de la PWM est déterminée par la vitesse de l’horloge interne du microcontrôleur et par la valeur de ICR1. Dans cet exemple, nous allons utiliser une fréquence de 50 Hz, ce qui correspond à une période de 20 ms, en définissant la valeur de ICR1 à 39999 :
int SERVO_PIN = 9; // déclarer la broche du servomoteur
void setup() {
pinMode(SERVO_PIN, OUTPUT); // configurer la broche comme sortie
TCCR1A = (1 << COM1A1) | (1 << WGM11); // configurer le compteur TIMER1
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // mode Fast PWM, ICR1 comme valeur maximale,
//prescaler de 8
ICR1 = 39999; // définir la valeur maximale à 39999
}
void loop()
{
for (int angle = 0; angle <= 180; angle += 1)
{ int pulse_width = 1500 + angle * 11; // calculer la largeur d'impulsion
int duty_cycle = pulse_width * 2 / 20; // calculer le rapport cyclique
OCR1A = duty_cycle * 39999 / 100; // définir le rapport cyclique dans OCR1A
delay(10); // attendre 10 ms }
}
Ce code configure les registres TCCR1A et TCCR1B pour utiliser le mode Fast PWM avec ICR1 comme valeur maximale et un prescaler de 8. La valeur maximale de ICR1 est définie à 39999, ce qui correspond à une période de 20 ms à une fréquence de 50 Hz. La broche 9 est configurée comme sortie avec la fonction pinMode.
La boucle for calcule la largeur d’impulsion souhaitée à partir de l’angle de rotation souhaité, en supposant que la largeur d’impulsion est comprise entre 500 et 2500 µs (microsecondes). Le rapport cyclique est calculé à partir de la largeur d’impulsion, en supposant que le signal PWM a une fréquence de 50 Hz. Le rapport cyclique est ensuite converti en une valeur entre 0 et 39999 pour correspondre à la résolution de 16 bits du compteur TIMER1. Enfin, le rapport cyclique est écrit dans le registre OCR1A pour définir la position angulaire souhaitée.
Ce code est beaucoup plus rapide que l’utilisation de la bibliothèque Servo, car il utilise directement les registres de contrôle du microcontrôleur. Cependant, il est également plus complexe à comprendre et à mettre en œuvre, en particulier pour les débutants en électronique.
Conclusion
Les registres de contrôle sont des éléments essentiels des microcontrôleurs, qui permettent de contrôler le fonctionnement des broches d’E/S, des timers, des interruptions et des autres périphériques. Les débutants en électronique peuvent trouver la lecture des registres intimidante au début, mais c’est un moyen efficace de contrôler précisément les fonctions du microcontrôleur.
Dans cet article, nous avons examiné les bases des registres de contrôle Arduino, en expliquant comment accéder et modifier les valeurs des registres à l’aide de la notation de pointeur et de la définition de bits. Nous avons également exploré quelques exemples pratiques, tels que la génération de signaux PWM pour contrôler un servomoteur.
Il est important de comprendre que l’utilisation directe des registres de contrôle est plus complexe que l’utilisation des bibliothèques préfabriquées, mais elle offre également une plus grande flexibilité et une meilleure performance. Les débutants en électronique doivent commencer par comprendre les concepts de base de l’électronique, tels que les résistances, les condensateurs et les diodes, avant de passer à des sujets plus avancés tels que les registres de contrôle. Les ressources en ligne, les forums et les tutoriels peuvent aider à surmonter les difficultés et à développer des compétences avancées en électronique.
Enfin, n’oubliez pas qu’il est important de comprendre les limites du microcontrôleur et de ne pas dépasser les spécifications recommandées, afin d’éviter les dommages potentiels au matériel.
En résumé, les registres de contrôle sont un élément clé des microcontrôleurs Arduino, offrant une grande flexibilité et une meilleure performance que les bibliothèques préfabriquées. Bien que leur utilisation directe puisse sembler intimidante pour les débutants, elle peut être maîtrisée avec de la pratique et de la patience. Les développeurs Arduino avancés peuvent profiter de l’utilisation des registres pour optimiser les performances et personnaliser les fonctions du microcontrôleur.