Objectifs : Utiliser une carte Arduino pour contrôler un moteur continu. Savoir utiliser un transistor MOSFET pour une utilisation simple, ou un pont en H si on désire faire tourner le moteur dans les deux sens. Comprendre l’intérêt des sorties PWM pour faire varier la vitesse d’un moteur
Cet article ne prétend pas tout expliquer en détail, mais est plutôt destiné à présenter un résumé des meilleures façons d’utiliser la carte Arduino avec un moteur à courant continu.
Pour des compléments d’information (principe d’un moteur à courant continu, fonctionnement d’un transistor, rôle de la diode de roue libre, fonctionnement d’un pont en H, rôle des sorites PWM d’une carte Arduino,…), je vous invite à lire cette page qui est très complète :
Article Moteur à courant continu Zeste de Savoir
1. Montage simple pour faire tourner un moteur à courant continu, à l’aide d’un transistor MOSFET
Il n’est pas possible d’appliquer une tension directement au moteur à partir d’une carte Arduino. En effet, une carte Arduino peut fournir la tension nécessaire mais n’est pas assez puissante.
L’intensité du courant délivré par la carte ARDUINO ne sera donc pas assez élevée pour faire tourner le moteur.
Nous allons donc nous servir de la carte Arduino exclusivement pour contrôler le moteur (circuit de commande, encadré vert à gauche sur le schéma ci-dessous).
Pour résoudre le problème de puissance, nous allons utiliser un transistor MOSFET.
Transistor MOSFET sur Go Tronic
Pour que ce transistor puisse supporter des courants d’intensité supérieure à 2 A sans trop chauffer , il peut être judicieux d’utiliser un dissipateur :
Ce composant va agir comme un interrupteur sur le circuit de puissance (encadré rouge à droite sur le schéma ci-dessous) à partir des instructions données à la carte Arduino.
Le circuit de puissance est composé :
- du moteur
- d’une diode de roue libre pour éviter les surtensions dues aux interruptions de tension aux bornes du moteur (voir l’article mentionné ci-dessus pour les détails)
- d’une alimentation externe assez puissante pour faire tourner le moteur (une alimentation stabilisée, une pile ou batterie LiPO peuvent convenir).
Nous avons choisi la broche 9 de la carte Arduino car il s’agit d’une broche qui peut agir comme une sortie PWM (symbole de vague à côté du numéro).
Qu’est ce que le PWM ?
Toutes les sorties Arduino ne peuvent délivrer qu’une tension de 0 V (état LOW) ou de 5V (état HIGH).
Cependant avec les sorties PWM (Pulse Width Modulation, en français MLI ou Modulation de Largeur d’Impulsions ), il est possible de « hacher » cette tension de 5 V en faisant varier le rapport cyclique du signal donné par la broche (le rapport cyclique est le rapport de la durée du signal au niveau haut divisé par le temps de la période du signal).
Dans le code Arduino, il faut bien penser à définir la broche 9 comme OUTPUT dans le void setup(). De plus, au lieu de l’instruction digitalWrite, il faut utiliser l’instruction analogWrite (uniquement valable pour les sorties PWM) afin de jouer sur le rapport cyclique., avec une valeur comprise entre 0 (0%) et 255 (100%).
Ci-dessous un exemple très simple de code Arduino permettant de faire tourner le moteur à 50 % de sa vitesse maximale :
En recevant cet signal, le transistor va donc agir comme un interrupteur commandé qui va à son tour commander la vitesse de rotation du moteur (alimenté avec une alimentation fixe). Plus le rapport cyclique est élevé, plus la vitesse de rotation est élevée (Tension aux bornes du moteur = Tension d’alimentation x rapport cyclique)
const int motorPin = 9; // Numéro de broche pour contrôler le rapport cyclique, et donc la vitesse de rotation du moteur
void setup() {
// On définit la broche du moteur comme une sortie :
pinMode(motorPin, OUTPUT);
}
void loop() {
// vitesse de rotation à 50 % (avec l'instruction analogWrite)
analogWrite(motorPin, 128);
}
Ce code est disponible ici
2. Utilisation d’un pont en H pour faire tourner le moteur dans les deux sens
Pour faire tourner un moteur dans les deux sens, il est nécessaire d’utiliser un pont en H
De nombreux articles expliquent le fonctionnement de ce composant de manière très détaillée avec l’application sur un moteur à courant continu, en agissant sur le sens de rotation ainsi que sur la vitesse de rotation :
- Le même article cité plus haut sur le site Zeste de Savoir
- Utilisation avec un shield pour simplifier les branchements (site Electroile)
- Complément pour faire varier la vitesse (site Electrotoile)
Voici les différents fonctionnements d’un pont en H :
Il existe différentes solutions « clé en main » utilisant ces ponts H, nécessitant plus ou moins de câblages …
Il sera encore une fois nécessaire d’utiliser des diodes de roue libre pour éviter des phénomènes de surtension :
2.1. Utilisation d’un circuit intégré simple : le L193D
Une solution simple est d’utiliser un circuit intégré comme le L293D qui comporte deux ponts en H (avec diodes de roue libre intégrées)
Ci-dessous la configuration des broches du L293D et la table de la logique de commande, uniquement détaillée pour l’un des deux ponts en H (sur la partie gauche du composant), le principe est le même sur la partie de droite pour le deuxième pont en H:
Enable 1 | Input 1 | Input 2 | Fonction |
High | Low | High | Tourne dans le sens horaire |
High | High | Low | Tourne dans le sens anti-horaire |
High | Low | Low | Moteur à l’arrêt |
High | High | High | Moteur à l’arrêt |
Voici le montage à réaliser pour contrôler un seul moteur :
Et voici le code Arduino, avec dans la boucle (void loop) rotation sens horaire/arrêt/anti horaire/arrêt (chaque étape dure 3 secondes) :
int Moteur_sens1=4; // Pin 4 Arduino vers broche INPUT1 du L293D
int Moteur_sens2=2; // Pin 5 Arduino vers broche INPUT2 du L293D
int moteur1_PWM = 3; // Pin 10 Arduino PWM vers EN1 du L293D
int PWM=255; // Variable PWM image de la vitesse
void setup() {
Serial.begin(9600); // Ouverture du port série et debit de communication fixé à 9600 bauds
pinMode(moteur1_PWM, OUTPUT); // Pin 3 Arduino en sortie PWM
pinMode(Moteur_sens1, OUTPUT); // Pin 4 Arduino en sortie digitale
pinMode(Moteur_sens2, OUTPUT); // Pin 5 Arduino en sortie digitale
}
void loop() {
// Le moteur tourne dans le sens normal
digitalWrite(Moteur_sens1, HIGH); // Activation de la broche INPUT1 du L293D
digitalWrite(Moteur_sens2, LOW); // Désactivation de la broche INPUT2 du L293D
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
delay( 3000 ); // Attendre 3 secondes
// Le moteur est à l'arrêt
digitalWrite(Moteur_sens1, LOW); // Désactivation de la broche INPUT1 du L293D
digitalWrite(Moteur_sens2, LOW); // Désactivation INPUT2 du L293D
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
delay( 3000 ); // Attendre 3 secondes
// Le moteur tourne dans le sens inverse
digitalWrite(Moteur_sens1, LOW); // Désactivation de la broche INPUT1 du L293D
digitalWrite(Moteur_sens2, HIGH); // Activation de la broche INPUT2 du L293D
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
delay( 3000 ); // Attendre 3 secondes
// Le moteur est à l'arrêt
digitalWrite(Moteur_sens1, LOW); // Désactivation de la broche INPUT1 du L293D
digitalWrite(Moteur_sens2, LOW); // Désactivation de la broche INPUT2 du L293D
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
delay( 3000 ); // Attendre 3 secondes
}
2.2. Utilisation d’un motorshield
Une solution encore plus simple serait d’utiliser un motorshield qui ne nécessite plus de câblages sur une plaque d’essai.
Voici un motorshield contenant un L198P qui est un composant analogue au L193D avec quelques petites différences.
Tout déjà pré câblé sur ce motorshield. Il suffit de le superposer directement sur la carte Arduino.
Ensuite, il faut connecter les moteurs et l’alimentation externe directement sur les borniers
C’est un peu une « boîte noire », il est donc utile de regarder dans la documentation technique l’affectation des broches sur la carte Arduino. La voici :
Canal A :
- D12 – Direction
- D3 – PWM (fonctionnement en service)
- D9 – Frein
- A0 – détection de courant.
Canal B :
- D13 – Direction
- D11 – PWM (fonctionnement en service)
- D8 – Frein
- A1 – détection de courant.
Nous allons utiliser uniquement le canal A pour un seul moteur. La carte Arduino est programmée pour le cycle suivant : rotation sens horaire/arrêt/anti horaire/arrêt (chaque étape dure 3 secondes)
Voici le montage, qui est très simple :
Et voici le code Arduino, avec dans la boucle (void loop) rotation sens horaire/arrêt/anti horaire/arrêt (chaque étape dure 3 secondes) :
int PWM=255; // Variable PWM image de la vitesse
int directionPin = 12; // broche pour le sens de rotation du moteur
int pwmPin = 3; // broche PWM pour contrôler la vitesse
int brakePin = 9; // broche pour activer/désactiver le frein
//décommnenter pour utiliser le canal B
//int directionPin = 13;
//int pwmPin = 11;
//int brakePin = 8;
void setup() {
// définition des broches
pinMode(directionPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
pinMode(brakePin, OUTPUT);
}
void loop() {
// Le moteur tourne dans le sens horaire
digitalWrite(directionPin, HIGH);// indique le sens de rotation
digitalWrite(brakePin, LOW);// relâche le frein
analogWrite(pwmPin, PWM);// indique la vitesse de rotation
delay(3000); // Attendre 3 secondes
//Arrêt du moteur
digitalWrite(brakePin, HIGH);// active le frein
analogWrite(pwmPin, 0);// on remet la valeur de vitesse de rotation à 0
delay(3000); // Attendre 3 secondes
// Le moteur tourne dans le sens anti horaire
digitalWrite(directionPin, LOW);// indique le sens de rotation
digitalWrite(brakePin, LOW);// relâche le frein
analogWrite(pwmPin, PWM);// indique la vitesse de rotation
delay(3000); // Attendre 3 secondes
//Arrêt du moteur
digitalWrite(brakePin, HIGH);// active le frein
analogWrite(pwmPin, 0);// on remet la valeur de vitesse de rotation à 0
delay(3000); // Attendre 3 secondes
}
Ce code est disponible ici
2.3. Utilisation d’un double pont en H pour une solution plus « nomade »(application à deux roues de voiture)
Nous allons maintenant utiliser le même composant L298 assemblé directement sur un circuit appelé motordriver. Il s’agit d’une solution très simple pour commander par exemple deux moteurs d’une petite voiture.
L’utilisation vue ici est très simple car nous nous contentons de demander à la voiture d’aller vers l’avant pendant 1 seconde, ensuite s’arrêter pendant 1 seconde, de reculer pendant une seconde, de s’arrêter pendant une seconde … puis de recommencer.
Il faudra donc, une fois le code téléversé, que la carte Arduino et le moteur driver soient alimentés, par exemple avec une pile ou une batterie LiPo.
Un modèle très populaire pour piloter jusqu’à deux moteurs à courant continu est le module L298N
Le cavalier (jumper JMP1) permet d’activer un régulateur 5V. Avec ce cavalier, pas besoin de « ramener » le 5V à partir de la carte Arduino.
De plus, la broche 5 V pourrait être utilisée comme une sortie avec ce cavalier.
Attention, en présence de ce cavalier, à ne pas dépasser 12 V sur la broche alim 5V-35V pour ne pas endommager le module.
Voici le fonctionnement de ce module avec les instructions données à In1/In2 (moteur A) et In3/In4 (moteur B)
Voici le montage réalisé pour alimenter les moteurs de deux roues sur un châssis :
Et voici le code Arduino, avec dans la boucle (void loop) marche avant/arrêt/marche arrière/arrêt (chaque étape dure 1 secondes) :
//*******************************************************************************//
// Association des entrées du L298N, aux sorties utilisées sur notre Arduino Uno //
//*******************************************************************************//
#define borneENA 10 // On associe la borne "ENA" du L298N à la pin D10 de l'arduino
#define borneIN1 9 // On associe la borne "IN1" du L298N à la pin D9 de l'arduino
#define borneIN2 8 // On associe la borne "IN2" du L298N à la pin D8 de l'arduino
#define borneIN3 7 // On associe la borne "IN3" du L298N à la pin D7 de l'arduino
#define borneIN4 6 // On associe la borne "IN4" du L298N à la pin D6 de l'arduino
#define borneENB 5 // On associe la borne "ENB" du L298N à la pin D5 de l'arduino
int PWM=128; // Variable PWM image de la vitesse
//*******//
// SETUP //
//*******//
void setup() {
// Configuration de toutes les pins de l'Arduino en "sortie" (car elles attaquent les entrées du module L298N)
pinMode(borneENA, OUTPUT);
pinMode(borneIN1, OUTPUT);
pinMode(borneIN2, OUTPUT);
pinMode(borneIN3, OUTPUT);
pinMode(borneIN4, OUTPUT);
pinMode(borneENB, OUTPUT);
}
//**************************//
// Boucle principale : LOOP //
//**************************//
void loop() {
// Configuration du L298N en "marche avant", pour les 2 moteurs connectés au pont A et au pont B. Selon sa table de vérité, il faut que :
// Moteur A
digitalWrite(borneIN1, HIGH); // L'entrée IN1 doit être au niveau haut
digitalWrite(borneIN2, LOW); // L'entrée IN2 doit être au niveau bas
// Moteur B
digitalWrite(borneIN3, HIGH); // L'entrée IN3 doit être au niveau haut
digitalWrite(borneIN4, LOW); // L'entrée IN4 doit être au niveau bas
// Et on lance les moteurs
analogWrite(borneENA, PWM); // Active l'alimentation du moteur 1
analogWrite(borneENB, PWM); // Active l'alimentation du moteur 2
delay(1000); // et attend 3 secondes
// Arrêt des moteurs pendant 3 secondes
digitalWrite(borneIN1, LOW);
digitalWrite(borneIN2, LOW);
digitalWrite(borneIN3, LOW);
digitalWrite(borneIN4, LOW);
analogWrite(borneENB, 0);
analogWrite(borneENA, 0);
delay(1000);
// Puis on configure le L298N en "marche arrière", pour les 2 moteurs connectés au pont A et au pont B. Selon sa table de vérité, il faut que :
// Moteur A
digitalWrite(borneIN1, LOW); // L'entrée IN1 doit être au niveau haut
digitalWrite(borneIN2, HIGH); // L'entrée IN2 doit être au niveau bas
// Moteur B
digitalWrite(borneIN3, LOW); // L'entrée IN3 doit être au niveau haut
digitalWrite(borneIN4, HIGH); // L'entrée IN4 doit être au niveau bas
// Et on lance les moteurs
analogWrite(borneENA, PWM); // Active l'alimentation du moteur 1
analogWrite(borneENB, PWM); // Active l'alimentation du moteur 2
delay(1000); // et attend 3 secondes
// // Arrêt des moteurs pendant 3 secondes
digitalWrite(borneIN1, LOW);
digitalWrite(borneIN2, LOW);
digitalWrite(borneIN3, LOW);
digitalWrite(borneIN4, LOW);
analogWrite(borneENB, 0);
analogWrite(borneENA, 0);
delay(1000);
}
Ce code est disponible ici
Petit essai réalisé rapidement. ça manque de stabilité pour l’instant !
Ce type de montage ouvre la voie à plusieurs applications, notamment dans la robotique.
On pourrait par exemple contrôler cette voiture à l’aide d’un joystick, avec variation de la vitesse et la possibilité de faire tourner le véhicule en agissant différemment sur les deux moteurs.
Il est possible aussi de commander à distance le véhicule à l’aide d’une autre carte Arduino, qui communiquerait en Bluetooth avec le montage déjà présent sur le châssis.
On pourrait essayer d’imaginer de construire un véhicule plus sophistiqué avec des capteurs (capteurs de vitesse pour asservir les moteurs, capteurs de lumière, radar ultrason, camera, …) ou d’autres actionneurs (servomoteurs pour bras articulé, LED, ..)
D’autres infos à venir …