Si on contrôle le moteur à l'aide d'un commutateur électronique comme un transistor bipolaire ou un transistor MOS, il faut garder à l'esprit que le moteur est une charge inductive. A chaque coupure du courant il génère une surtension qui peut atteindre des centaines de Volts et détruire le transistor. Pour protéger le transistor il faut absolument ajouter une diode de récupération
La commande de vitesse d'un moteur à courant continu (DC) se fait principalement par la modulation de la largeur d'impulsion (PWM, pour Pulse Width Modulation). Au lieu d'alimenter le moteur d'une manière permanente, on l'alimente a travers un commutateur commandé par un signal PWM.
Le signal PWM est caractérisé par une période fixe T. En faisant varier la largeur de l'impulsion active H au sein de cette période, on modifie le rapport cyclique, c'est-à-dire le ratio H/T. Ce rapport cyclique détermine la proportion de temps durant laquelle la tension est appliquée au moteur, influençant ainsi la puissance moyenne fournie et, par conséquent, la vitesse du moteur. Lorsque H est augmenté, le rapport cyclique augmente, ce qui accroît la vitesse du moteur. À l'inverse, en réduisant H, on diminue la vitesse
Pour contrôler le sens de rotation du moteur, on le commande à l'aide d'un pont en H.
Un pont en H est tout simplement un ensemble de 4 interrupteurs. Si on ferme A et D, le moteur est alimenté dans un sens. Si on ferme B et C, le moteur est alimenté dans l'autre sens
Le circuit L298 fabriqué par STMicroelectronics contient deux ponts en H ce qui permet de contrôler deux moteurs à courant continu ou un moteur pas à pas bipolaire.
Conformément à la table de vérité, si on applique un '1' (5V permanent) sur l'entré ENA (ou ENB), le moteur tourne à sa vitesse nominale
Pour controler la vitesse, on applique un signal PWM sur l'entrée ENA (ou ENB), La vitesse de rotation sera proportionnelle au rapport cyclique du signal PWM. La fréquence du signal PWM ne devrait pas être trop élevée, une valeur entre 60Hz et 500Hz me parait optimale. Voir Ce paragraphe pour savoir comment modifier la fréquence
Le branchement du L298 avec un seul Moteur est indiqué ci-dessous :
On y trouve :
Le module L298 disponible dans le commerce a l'avantage d'être tout équipé et prêt à l'emploi. Il intègre :
Dans cet exemple, on a un seul moteur branché sur le pont A
Dans cet exemple, on a un seul moteur branché sur le pont A
#define ENA 10
#define IN1 9
#define IN2 8
void setup() {
TCCR1B = TCCR1B & B11111000 | B00000100; // f = 122.55 Hz, T = 8.16ms (D9, D10)
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
analogWrite(ENA,0);
Serial.begin(9600);
Serial.setTimeout(5000);
Serial.println(F("F N --> Forward (Avant), vitesse ~ N/255"));
Serial.println(F("B N --> Backward (Arrière), vitesse ~ N/255"));
Serial.println(F("S --> Stop (Arrêt)"));
Serial.println("Le moniteur Série doit envoyer un Fin de Ligne");
}
void loop() {
if (Serial.available()) {
char c = toupper(Serial.read());
if(c == 'S'){
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
return;
}
uint8_t N = Serial.parseInt();
clearInputBuffer();
Serial.println(String(c)+" --> "+String(N));
if (c == 'F') {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW); // gauche
analogWrite(ENA,N);
} else if (c == 'B') {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA,N);
} else {
Serial.println(String(c)+" ---> Bad Command ");
}
}
}
void clearInputBuffer() {
do {
delay(2);
Serial.read();
} while (Serial.available());
}
Dans cet exemple, on va controller un moteur CC à l'aide d'un Joystick
[900→1023] ==> Rotation avant, Vitesse Forte [600→900] ==> Rotation avant, Vitesse Faible [400→600] ==> Arrêt [100→400] ==> Rotation arrière, Vitesse Faible [0 → 100] ==> Rotation arrière, Vitesse Forte
/*
0 100 400 600 900 1023
|Ariere fort|---arrière faible---|-----Arrêt-----|---Avant faible---|-Avant fort-|
Moteur branché sur pont A du L298
Joystick sur A0
*/
#define ENA 10
#define IN1 9
#define IN2 8
#define PWML 100 // vitesse faible
#define PWMH 255 // vitesse forte
#define N1 100 // modifier les paliers si nécessaire
#define N2 400
#define N3 600
#define N4 900
void setup() {
TCCR1B = TCCR1B & B11111000 | B00000100; // f = 122.55 Hz, T = 8.16ms (D9, D10)
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
}
void loop() {
delay(10);
int N = analogRead(A0);
if (N < N1) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, PWMH); // arrière Fort
} else if (N < N2) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, PWML); // arrière Faible
} else if (N < N3)analogWrite(ENA, 0); // Roue libre
else if (N < N4) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, PWML); // Avant faible
}
else {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, PWMH); // Avant fort
}
}
Le BTS7960 est un pont en H conçu pour contrôler des moteurs à courant continu (DC) de forte puissance. Il contient deux 1/2 ponts à base de transistors de puissance MOS
Ces caractéristiques principales sont :
La nomenclature des broches de contrôle porte à confusion. Il n'y a pas forcément une seule façon de controller le module. Nous proposons la méthode suivante :
Voici un exemple de branchement avec Arduino UNO et Arduino Mega
Pour le signal PWM, La fonction analogWrite() permet de régler le rapport cyclique mais pas la fréquence.
Pour contrôler un moteur CC, il me semble que la fréquence optimale devrait être dans la plage [60Hz, 500Hz]
En fonction de la sortie PWM choisie, on peut fixer la fréquence en ajoutant une ligne qui modifie un registre de configuration du timer qui gère la sortie.
// For Arduino Uno, Nano, Micro Magician, Mini Driver, Lilly Pad and any other board using ATmega 8, 168 or 328
//-------------- fréquences PWM sur les broches D5 & D6 -------------------------------
TCCR0B = TCCR0B & B11111000 | B00000001; // f = 62500.00 Hz, T = 0.016ms
TCCR0B = TCCR0B & B11111000 | B00000010; // f = 7812.50 Hz, T = 0.128ms
TCCR0B = TCCR0B & B11111000 | B00000011; // f = 976.56 Hz, T = 1.024ms (The DEFAULT)
TCCR0B = TCCR0B & B11111000 | B00000100; // f = 244.14 Hz, T = 4.096ms
TCCR0B = TCCR0B & B11111000 | B00000101; // f = 61.04 Hz, T = 16.383ms
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
TCCR1B = TCCR1B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR1B = TCCR1B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR1B = TCCR1B & B11111000 | B00000011; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR1B = TCCR1B & B11111000 | B00000100; // f = 122.55 Hz, T = 8.16ms
TCCR1B = TCCR1B & B11111000 | B00000101; // f = 30.64 Hz, T = 32.637ms
//---------------------------------------------- Set PWM frequency for D3 & D11 ------------------------------
TCCR2B = TCCR2B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR2B = TCCR2B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR2B = TCCR2B & B11111000 | B00000011; // f = 980.39 Hz, T = 1.020ms
TCCR2B = TCCR2B & B11111000 | B00000100; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR2B = TCCR2B & B11111000 | B00000101; // f = 245.10 Hz, T = 4.080ms
TCCR2B = TCCR2B & B11111000 | B00000110; // f = 122.55 Hz, T = 8.16ms
TCCR2B = TCCR2B & B11111000 | B00000111; // f = 30.64 Hz, T = 32.637ms
//For Arduino Mega1280, Mega2560, MegaADK, Spider or any other board using ATmega1280 or ATmega2560
//------------------------------ Set PWM frequency for D4 & D13 ------------------------------
TCCR0B = TCCR0B & B11111000 | B00000001; // f = 62500.00 Hz, T = 0.016ms
TCCR0B = TCCR0B & B11111000 | B00000010; // f = 7812.50 Hz, T = 0.128ms
TCCR0B = TCCR0B & B11111000 | B00000011; // f = 976.56 Hz, T = 1.024ms (The DEFAULT)
TCCR0B = TCCR0B & B11111000 | B00000100; // f = 244.14 Hz, T = 4.096ms
TCCR0B = TCCR0B & B11111000 | B00000101; // f = 61.04 Hz, T = 16.383ms
//------------------------------ Set PWM frequency for D11 & D12 -----------------------------
TCCR1B = TCCR1B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR1B = TCCR1B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR1B = TCCR1B & B11111000 | B00000011; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR1B = TCCR1B & B11111000 | B00000100; // f = 122.55 Hz, T = 8.16ms
TCCR1B = TCCR1B & B11111000 | B00000101; // f = 30.64 Hz, T = 32.637ms
//-------------------=---------- Set PWM frequency for D9 & D10 ------------------------------
TCCR2B = TCCR2B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR2B = TCCR2B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR2B = TCCR2B & B11111000 | B00000011; // f = 980.39 Hz, T = 1.020ms
TCCR2B = TCCR2B & B11111000 | B00000100; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR2B = TCCR2B & B11111000 | B00000101; // f = 245.10 Hz, T = 4.080ms
TCCR2B = TCCR2B & B11111000 | B00000110; // f = 122.55 Hz, T = 8.16ms
TCCR2B = TCCR2B & B11111000 | B00000111; // f = 30.64 Hz, T = 32.637ms
//------------------------------ Set PWM frequency for D2, D3 & D5 ---------------------------
TCCR3B = TCCR3B & B11111000 | B00000001; // f = 31372.55 Hz T = 0.032ms
TCCR3B = TCCR3B & B11111000 | B00000010; // f = 3921.16 Hz T = 0.255ms
TCCR3B = TCCR3B & B11111000 | B00000011; // f = 490.20 Hz T = 2.04ms (DEFAULT)
TCCR3B = TCCR3B & B11111000 | B00000100; // f = 122.55 Hz T = 8.16ms
TCCR3B = TCCR3B & B11111000 | B00000101; // f = 30.64 Hz T = 32.637ms
//------------------------------ Set PWM frequency for D6, D7 & D8 ---------------------------
TCCR4B = TCCR4B & B11111000 | B00000001; // f = 31372.55 Hz T = 0.032ms
TCCR4B = TCCR4B & B11111000 | B00000010; // f = 3921.16 Hz T = 0.255ms
TCCR4B = TCCR4B & B11111000 | B00000011; // f = 490.20 Hz T = 2.04ms (DEFAULT)
TCCR4B = TCCR4B & B11111000 | B00000100; // f = 122.55 Hz T = 8.16ms
TCCR4B = TCCR4B & B11111000 | B00000101; // f = 30.64 Hz T = 32.637ms
//------------------------------ Set PWM frequency for D44, D45 & D46 ------------------------
TCCR5B = TCCR5B & B11111000 | B00000001; // f = 31372.55 Hz T = 0.032ms
TCCR5B = TCCR5B & B11111000 | B00000010; // f = 3921.16 Hz T = 0.255ms
TCCR5B = TCCR5B & B11111000 | B00000011; // f = 490.20 Hz T = 2.04ms (DEFAULT)
TCCR5B = TCCR5B & B11111000 | B00000100; // f = 122.55 Hz T = 8.16ms
TCCR5B = TCCR5B & B11111000 | B00000101; // f = 30.64 Hz T = 32.637ms
/*
* Exemple de code pour tester le Module BTS7960
*/
#define PSTEP 10
#define EN_PWM 9
#define DR 2
#define DL 4
void setup() {
pinMode(EN_PWM, OUTPUT);
pinMode(DR, OUTPUT);
pinMode(DL, OUTPUT);
digitalWrite(EN_PWM,LOW); // roue libre au déppart
Serial.begin(9600);
Serial.println("Taper une commande");
Serial.println("L ---> Roue Libre");
Serial.println("D ---> Droite");
Serial.println("G ---> Gauche");
Serial.println("S ---> Stop (frein HIGH)");
Serial.println("s ---> Stop (frein LOW)");
Serial.println("+ ---> Accélerer");
Serial.println("- ---> Ralentir");
TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz
}
int pwm = 127;
void loop() {
if (Serial.available() > 0){
char c = Serial.read();
switch (c) {
case 'L':
digitalWrite(EN_PWM,LOW); // roue libre
Serial.println("Libre");
break;
case 'G':
digitalWrite(DR,LOW);
digitalWrite(DL,HIGH); // gauche
analogWrite(EN_PWM,pwm); // vitesse
Serial.println("G ---> " + String(pwm));
break;
case 'D':
digitalWrite(DR,HIGH);
digitalWrite(DL,LOW);
analogWrite(EN_PWM,pwm);
Serial.println("D ---> " + String(pwm));
break;
case 'S':
digitalWrite(DR,HIGH); // frein
digitalWrite(DL,HIGH);
digitalWrite(EN_PWM,HIGH);
Serial.println("Frein H");
break;
case 's':
digitalWrite(DR,LOW); // frein
digitalWrite(DL,LOW);
digitalWrite(EN_PWM,HIGH);
Serial.println("Frein L");
break;
case '+':
pwm += PSTEP;
if (pwm > 255) pwm = 255;
analogWrite(EN_PWM, pwm);
Serial.println(pwm);
break;
case '-':
pwm -= PSTEP;
if (pwm < 0) pwm = 0;
analogWrite(EN_PWM, pwm);
Serial.println(pwm);
break;
}
}
}