SE3 2025/2026 EC3
Jour 1 : Moteur et Boutons
Pour cette première étape, j’ai choisi d’avancer progressivement. L’objectif était simplement de lire les boutons S1 et S2 afin de commander la rotation du servo-moteur dans les deux sens.
Configuration des boutons
En consultant la datasheet ATmega328P,la section 13.2.1 (page 59),
- Lorsqu’une broche est configurée en entrée DDR = 0 et que l’on écrit un 1 dans le registre PORT correspondant, la résistance pull-up interne est activée. Cela maintient la broche à 5V au repos.
on a donc :
- Bouton non appuyé : niveau 1
- Bouton appuyé : niveau 0
C’est pour cette raison que, dans la boucle principale, je teste un état logique bas 0 pour détecter un appui.
Désactivation du buzzer du shield
Au démarrage, le buzzer du shield émettait un signal sonore en continu. Après vérification, celui-ci est piloté par un transistor PNP Q1. Pour le désactiver, il faut imposer un niveau logique haut (5V) sur la broche de commande. D’après la table 13-1 (page 60), cela se fait en configurant la broche en sortie DDR = 1 et en forçant le bit correspondant du registre PORT à 1. J’ai donc configuré la broche PD3 en sortie et fixé son état à 1 dès l’initialisation du programme.
Génération du signal PWM pour le servo
Le servo-moteur nécessite un signal PWM d’environ 60 Hz.
J’ai utilisé le Timer 0 en mode Fast PWM (Mode 3), en activant les bits WGM01 et WGM00, conformément à la table 14-8 (page 86).
- Dans ce mode, le compteur évolue de 0 à 255.
- Pour que le signal soit transmis sur la broche PD6 (OC0A), j’ai activé le bit COM0A1 (table 14-3, page 84). "If one or both of the COM0A1:0 bits are set, the OC0A output overrides the normal port functionality of the I/O pin it is connected to."
Étant donné que le microcontrôleur fonctionne à 16 MHz, j’ai appliqué un prescaler de 1024 via les bits CS02 et CS00 (page 87). Le calcul de la fréquence obtenue est le suivant :
La fréquence obtenue est donc d’environ 61 Hz, ce qui est compatible avec les exigences d’un servo-moteur standard.
Justification des valeurs matérielles pour le servo Hitec HS-422
Le moteur utilisé pour ce projet est un servo Hitec HS-422. En étudiant ses spécifications techniques officielles, le constructeur définit la plage de fonctionnement suivante :
- Le point central (neutre) est fixé à 1500 µs (1,5 ms).
- La plage d'impulsion garantie (Pulse Width) s'étend de 900 µs (0,9 ms) à 2100 µs (2,1 ms).
Calcul des valeurs du registre OCR0A : Notre horloge Arduino fonctionne à 16 MHz. Avec un prescaler de 1024, la durée d'une seule incrémentation (un "tic") du Timer 0 est de :
Pour trouver la valeur technique à envoyer au registre, on divise le temps d'impulsion du constructeur par la durée de notre tic :
- Point central (1,5 ms) :
. En arrondissant, on obtient notre position de démarrage 23.
- Butée minimale constructeur (0,9 ms) :
. La limite officielle basse est de 14.
- Butée maximale constructeur (2,1 ms) :
. La limite officielle haute est de 33.
Dans le code final, les limites ont été étendues de 8 à 38, correspondant environ à 0,5 ms et 2,4 ms pour exploiter le maximum la mécanique du servo.
Code du Jour 1
#ifndef F_CPU
#define F_CPU 16000000UL // On définit la vitesse de l'horloge
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
// On définit les pins comme des sorties (DDR = 1)
DDRD |= (1<<PD6) | (1<<PD3);
// On force le buzzer au silence
PORTD |= (1<<PD3);
// On active les résistances internes pour les boutons
PORTC |= (1<<PC1) | (1<<PC2);
// On crée un signal PWM rapide pour piloter le servo sur la pin D6
TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1<<CS02) | (1<<CS00); // On ralentit le chrono pour avoir du 61Hz
uint8_t pos = 23; // Valeur de démarrage (moteur à l'arrêt)
while (1) {
// Lecture des boutons
if (!(PINC & (1<<PC1)) && pos > 8) pos--; // Bouton S1 diminue
if (!(PINC & (1<<PC2)) && pos < 38) pos++; // Bouton S2 augmente
OCR0A = pos; // On envoie l'ordre de vitesse au moteur
_delay_ms(100); // Délai pour que le réglage du servo ne soit pas trop rapide
}
}