ACTIVITE ARDUINO : Contrôler un moteur à courant continu avec une carte Arduino

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 :

Dissipateur pour transistor sur Go Tronic

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 :

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)

L293D sur Go Tronic

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:

Configuration des broches
Enable 1Input 1Input 2Fonction
High  LowHighTourne dans le sens horaire
HighHighLowTourne dans le sens anti-horaire
HighLowLowMoteur à l’arrêt
HighHighHighMoteur à 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
}

Ce code est disponible ici

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

Motorshield Arduino sur Go Tronic

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

Module L298N disponible chez Go Tronic

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 …

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *