Maîtriser le contrôle de moteur à courant continu : Astuces et conseils d'expert
Composants et fournitures
| Composant | Quantité | Remarques |
|---|---|---|
| Arduino Due | 1 | Tout autre Arduino convient. |
| Écran TFT Makeblock Me | 1 | Optionnel, un autre affichage ou aucun possible. |
| Résistance 4,75 kΩ | 4 | Les valeurs peuvent varier selon l'implémentation. |
| Potentiomètre rotatif | 4 | 3 sont optionnels (ajustement coefficients PID). |
| Transistor PNP usage général | 4 | Le choix dépend de l'implémentation. |
| Moteur DC générique | 1 | |
| Interrupteur à glissière | 1 | Pour sélection du sens de rotation. |
| Capteur de vitesse photoélectrique HC-020K | 1 | |
| Plaque d'essai (breadboard) | 1 | |
| Fils de liaison (jumper wires) | 1 |
Applications et services en ligne
- Arduino IDE
À propos du projet
Contrôle de la vitesse et du sens des moteurs DC par régulateur PID et sorties PWM
Introduction
La plupart des projets tentent de contrôler vitesse et sens en envoyant directement un signal PWM au moteur (via un circuit de commande). Mais cette méthode échoue si l'on doit atteindre une vitesse précise à cause de deux « jumeaux » : le frottement et l'inertie.
Si vous envoyez directement votre consigne en PWM, la vitesse réelle ne correspondra jamais au point de consigne, avec une erreur significative. La solution : le contrôle PID.
Le régulateur PID
Imaginez la conduite d'une voiture : au démarrage, vous appuyez fort sur l'accélérateur ; en vitesse de croisière, vous maintenez légèrement ; si vous accélérez trop, vous relâchez. C'est aussi la conduite « efficace ».
Le régulateur PID fait de même : il lit l'erreur (différence entre consigne et sortie réelle) et possède trois composantes :
- Proportionnelle (P) : définit la pente (accélération) de la sortie par rapport à l'erreur.
- Intégrale (I) : somme les erreurs dans le temps pour minimiser l'erreur finale.
- Dérivée (D) : surveille l'accélération de l'erreur et apporte un ajustement.
Sur mon programme Arduino, le PID est implémenté comme une fonction :
float controllerPID(float _E, float _Eprev, float _dT, float _Kp, float _Ki, float _Kd) {
float P, I, D;
P = _Kp * _E; // Composante proportionnelle
I = _Kp * 0.5 * _Ki * (_E+_Eprev) * _dT; // Composante intégrale
D = _Kp * _Kd * (_E-_Eprev) / _dT; // Composante dérivée
return (P+I+D);
}
La sortie finale est obtenue en ajoutant la sortie courante et la sortie du PID :
E = RPMset - RPM;
float cPID = controllerPID(E, Eprev, dT, Kp, Ki, Kd);
if (RPMset == 0) OutputRPM = 0;
else OutputRPM = OutputRPM + cPID;
if (OutputRPM < _minRPM) OutputRPM = _minRPM;
Circuit d'alimentation du moteur DC
Il ne faut jamais piloter un moteur DC directement depuis une sortie Arduino (courant insuffisant). Les relais ont des pièces mécaniques qui s'usent. J'ai utilisé des transistors. Les moteurs DC sont pilotés par le courant, pas la tension.
J'ai choisi quatre transistors PNP BC307A en pont en H pour inverser le courant dans les bobines. (Des NPN BC337 seraient meilleurs pour des courants plus élevés, mais je n'en avais pas.)
Il faut sélectionner des transistors avec un gain en courant (hfe) similaire. Pour ce faire, on mesure le courant collecteur avec un circuit de test.
Calcul de la résistance de base
- Trouver la tension base-émetteur (VBEon) – tension minimale pour saturer le transistor.
- Trouver le gain hfe typique au courant collecteur visé (hfe = IC / IB).
- Vérifier le courant collecteur maximal continu (ICmax) – le courant moteur ne doit jamais le dépasser.
Formule combinée : R = (VT - VBEon) * hfe / IM
- Courant moteur IM = 70 mA
- BC307A : ICmax = 100 mA, hfe ≈ 140 (mesuré), VBEon = 0,62 V
- Tension de commande VT = 3,3 V (PWM Arduino Due)
- R = 5360 Ω → j'ai utilisé 4900 Ω (2,2 kΩ + 2,7 kΩ) pour couvrir toute la plage de vitesse et ne tirer que ~0,6 mA de la sortie PWM.
Inversion du sens et notes importantes
Pour inverser le sens, on inverse le courant dans le moteur. Un pont en H avec quatre transistors fait cela : PWM sortie #2 active T1A/T1B, PWM sortie #3 active T2A/T2B.
Attention au courant de démarrage : Au démarrage, les moteurs absorbent un courant transitoire bien supérieur au nominal (jusqu'à 130 % pour petits moteurs). Si on inverse la polarité alors que le moteur tourne encore, le pic de courant peut endommager l'alimentation ou les bobines. Avec des transistors, le courant est limité.
J'ai ajouté une routine logicielle : lors d'un changement de sens en marche, les deux sorties PWM sont mises à zéro et on attend l'arrêt complet du moteur avant de reprendre.
if (Direction != prevDirection) {
analogWrite(_chMotorCmdCCW,0);
analogWrite(_chMotorCmdCW,0);
do {
RPM = 60*(float)readFrequency(_chSpeedRead,4)/_DiscSlots;
} while (RPM > _minRPM);
}
Lecture de la vitesse
J'ai utilisé le capteur HC-020K (alimenté en 3,3 V sur Arduino Due). Il envoie des impulsions à chaque passage de fente (20 fentes). Voici la fonction de lecture de fréquence :
int readFrequency(int _DI_FrequencyCounter_Pin, float _ReadingSpeed) {
pinMode(_DI_FrequencyCounter_Pin,INPUT);
byte _DigitalRead, _DigitalRead_Previous = 0;
unsigned long _Time = 0, _Time_Init;
float _Frequency = 0;
if ( (_ReadingSpeed<=0) || (_ReadingSpeed>10) ) return (-1);
else {
_Time_Init = micros();
do {
_DigitalRead = digitalRead(_DI_FrequencyCounter_Pin);
if ( (_DigitalRead_Previous==1) && (_DigitalRead==0) ) _Frequency++;
_DigitalRead_Previous = _DigitalRead;
_Time = micros();
} while ( _Time < (_Time_Init + (1000000/_ReadingSpeed)) );
}
return (_ReadingSpeed * _Frequency);
}
Calcul du RPM : RPM = 60 * (float)readFrequency(_chSpeedRead,4) / _DiscSlots;
Affichage graphique (optionnel)
J'ai utilisé un écran TFT Makeblock Me avec des fonctions de tracé (Cartesian_Setup, Cartesian_ClearPlotAreas, Cartesian_Line). Ces fonctions gèrent l'affichage des courbes de consigne et vitesse réelle.
Conclusion
Normalement, on ne peut descendre en dessous de 10-20 % de la vitesse nominale d'un moteur DC sans charge. Avec le PID, on peut descendre à ~5 % une fois le moteur lancé.
Édition (25/02/2018) : Si vous utilisez des transistors NPN au lieu de PNP, attention au sens du courant : sur PNP, courant de l'émetteur vers le collecteur quand déclenché ; sur NPN, du collecteur vers l'émetteur. Donc polarisation inverse : PNP E(+) C(-), NPN C(+) E(-).
Code
Deux versions sont fournies : avec affichage graphique et sans affichage graphique. Les deux sont disponibles en téléchargement dans la section Code du projet original.
Schémas
Schéma de principe du prototype pour expliquer le contrôle de vitesse par PID et les précautions pour l'inversion de sens.
Processus de fabrication
- Améliorer la performance des moteurs DC avec les alliages Tungstène-Cuivre
- Créer des effets audio pilotés par capteurs avec le kit Satellite CCRMA
- Contrôler 2 moteurs pas-à-pas avec Arduino Nano et joystick – Tutoriel Visuino
- Maîtriser une matrice LED 8×8 avec Arduino Uno : Guide pas à pas
- Système de Surveillance Thermique Scolaire : Précis, Temps Réel et Sécurisé
- Bibliothèque Arduino efficace pour port E/S 8 bits — Étendez le contrôle numérique
- Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
- Circuit d'entrée analogique isolée pour Arduino : Protection contre les parasites industriels
- Kit de robot de navigation intérieure intelligente pour projets Arduino