Contrôler un servo avec Arduino Uno
Le code d'exemple Arduino Uno ci-dessous montre comment contrôler un simple servo en utilisant le Timer 2. Nous utilisons le
Timer 2 à la place du Timer 1 parce que le Timer 1 est utilisé par la bibliothèque ZumoMotors (ce qui interfère avec la
bibliothèque servo d'Arduino). Il nous faut donc gérer notre servo moteur nous même avec un autre timer (le Timer 2).
Utiliser le Timer 2 interfère avec la bibliothèque ZumoBuzzer, il ne sera donc pas possible d'utiliser le Buzzer et le Timer 2 en
même temps. Vous pouvez intégrer ce code avec d'autre codes pilotant des moteurs.
/** Exemple Servo Timer 2 sur Arduino Uno
Ce code d'exemple est pour un Arduino Uno et montre comment utiliser le
Timer 2 d'un ATmega328P pour controler un simple servo moteur.
Cela est tule pour les gens qui ne peuvent pas utiliser la
bibliotheque Servo d'Arduino IDE.
Par exemple, la bibliotheque ZumoMotors utilise le même timer que
la bibliotheque Servo (Timer 1). Il y a donc un conflit.
La macro SERVO_PIN ci-dessous spécifie la broche sur laquelle
est branché le servo moteur. Cette broche doit être raccordée
sur l'entrée signal du servo. La masse du servo doit être connecté
sur la masse de votre Arduino (masse commune). Pour finir
la masse et broche d'alimentation du servo doivent être connecté
sur une source d'alimentation adéquate.
*/
// Cette ligne indique quel est la broche utilisée pour envoyer
// le signal au servo moteur. Vous pouvez changer cette valeur.
#define SERVO_PIN 11
// Le temps depuis le dernier flan montage (rising edge) en unités de 0.5us.
uint16_t
volatile
servoTime
=
0;
// Contient la largeur d impulsion désirée en unités de 0.5us.
volatile
uint16_t
servoHighTime
=
3000;
// Vrai (true) si la broche servo est actuellement au niveau haut.
volatile
boolean
servoHigh
=
false;
void
setup()
{
servoInit();
}
void
loop()
{
servoSetPosition(1000);
// Envoi une impulsion de 1000 us.
delay(1000);
servoSetPosition(2000);
// Envoi une impulsion de 2000 us.
delay(1000);
}
// Cette routine d'interruption (ISR) est appelée après que
// le Timer 2 ait atteind OCR2A et resets.
// Dans cet ISR, nous initialisons OCR2A pour déterminer
// quand la prochaine interruption est déclenchée.
// Généralement, nous fixons OCR2A à 255 pour avoir une
// interruption toutes les 128 us, mais les deux premiers
// intervales d'interruption après le flan montant (rising edge)
// seront plus petit ce qui nous empêche d'atteindre la
// largeur d'impulsion désirée.
ISR(TIMER2_COMPA_vect)
{
// Le temps qui est passé depuis la dernière interruption est
// égale à OCR2A + 1 parce que la valeur du timer sera égale
// à OCR2A avant de revenir à 0.
servoTime
+=
OCR2A
+
1;
static
uint16_t
highTimeCopy
=
3000;
static
uint8_t
interruptCount
=
0;
if(servoHigh)
{
if(++interruptCount
==
2)
{
OCR2A
=
255;
}
// La broche du signal Servo est au niveau haut (high).
// Vérifier s'il est temps d'avoir le flan descendant
// du signal (falling edge).
// Note: Nous pouvons utiliser == à la place de >=.
if(servoTime
>=
highTimeCopy)