samedi 11 juin 2011

Pont H à transistor pour contrôler un Moteur DC dans les deux sens

06/05/2012: MCHobby propose maintenant un Breakout board permettant de piloter deux moteur CC dans les deux sens. Ce module est basé sur le L298 qui est un double Pont-H. Le module est en vente ici et la documentation (+exemple Arduino) disponible sur notre Wiki.
 
Introduction
L'article "Contrôle Moteur DC via transistor (PWM) " expliquait comment contrôler un moteur DC via un étage de puissance basé sur un transistor.
L'inconvénient de ce montage est qu'il n'est possible de faire fonctionner le moteur que dans un seul sens.
Il serait possible d'utiliser un relai pour inverser la connexion (polarisation) du moteur mais cette option serait extrêmement gourmande en énergie.

La solution réside dans le montage d'un pont H.

Le pont H - principe
Dans son principe de base, le pont H est un assemblage de 4 transistors (2 PNP et 2 NPN) monté de telle façon que le courant puisse passer soit dans un sens, soit dans l'autre dans la charge (le moteur par exemple).
Structure du pont H
Source: wikipedia
Fonctionnement du pont H
Source: Telecom-Robotics
Dans le dessins ci-dessus, il est clairement visible que le monteur fonctionne dans un sens si Q3 et Q2 sont commuté ET dans l'autre sens Q1 et Q4 sont commutés.

Bien évidemment, Q3 et Q1 ne peuvent jamais être commutés en même temps (tout comme Q4 et Q2) car cela provoque un court-circuit franc.

Pour plus d'information, voir cet article consacré au pont H (Wikipedia) ou encore celui-ci (telecom-robotics).

Le pont H à transistors
Le schéma suivant montre le montage d'un pont H à l'aide de transistors.
Ce type de montage éducatif fonctionne bien avec un petit moteur.
Pont H à transistor
Source: Fribotte

Après quelques révisions sur les transistors (part 1 & part 2), le fonctionnement d'un tel circuit est tout à fait compréhensible. 

Les diodes en roue libre sont intelligemment placées sur les transistors.
En effet, il serait impossible de les placer sur la charge où elles devraient être montées tête-bêche (pour être active dans les deux sens de polarisation), ce qui causerait inévitablement un court-circuit dans tous les cas de figure :-/ .

Comme précisé, en aucun cas, il ne faut alimenter simultanément les connexions J1 et J2, ce qui créerait également un court-circuit.

Fonctionnement de la commutation:

Sens 1: J2 = 5Volts:
Si l'on applique la tension de commande (généralement 5v) sur le connecteur J2.
La tension de commande s'applique via R2 et le transistor Q2 reçoit une tension de commande Vbe de +/- 0.7v.
Le transistor Q2 devient passant (saturé) et la tension appliqué du côté droit du moteur (mais aussi de R3) est très proche de Gnd (exactement Gng + Vce_Sat_Q2).
Ainsi donc, une tension est appliquée aux bornes (B-E) de la base de Q3 via R3.
Comme Q3 est un transistor NPN, la tension de commande doit être appliqué entre Vcc et la Base de Q3 (Vbe_Q3). Et comme R3 est appliquée presqu'à la masse (via Q2), une tension suffisante est appliqué sur la jonction Vbe_Q3.
Vbe_Q3 est donc égal à la tension de jonction (~0.7v) et Q3 devient également passant.
La borne gauche du moteur est donc raccordée à +Vcc (plus exactement +Vcc - Vce_sat_Q3).
Le courant passe de gauche à droite dans le moteur... et il tourne dans un sens donnée.
Puisque Q3 est passant, Une tension égale à Vce_Sat_Q3 (~0.2v) par rapport a VCC est appliquée sur la base de Q4 via R4.
Q4 étant également un PNP, cette tension Vbe_Q4 par rapport à Vcc n'est suffisante. Le transistor Q4 reste donc bloqué  :-) .
 
Finalement, comme on a appliqué une tension de commande sur J2, J1 doit impérativement être à la masse (Gnd).
Par conséquent, Q1 reste bloqué puisque Vbe_Q3 (par rapport à la masse) est ici également insuffisant.

Nous avons bien Q3 et Q2 commuté ainsi que Q1 & Q4 bloqué :-).

Sens 2: J1 = 5Volts:
Et bien entendu J2 = 0v.
Le raisonnement reste similaire au précédent.

Bien calculer son montage
Je parle de montage éducatif car bien évidemment il faut veiller à calculer correctement son montage ainsi que les courants mis en œuvre (courant de base et courant de collecteur).

Anticiper la chute de tension
Les transistors commuté en saturation présentent une légère chute de tension (Vce_Sat). Et comme le courant qui actionne le moteur passe par deux transistors, la chute de tension intervient donc deux fois! Soit 2*0.2v dans le meilleurs des cas (j'en suis à 0.9v au total dans mon montage).

Si votre moteur fonctionne sous 5Volts, il faudra donc prévoir une tension d'alimentation un peu plus élevée (par exemple 7.5v) qui à accompagner le moteur d'une résistance de charge complémentaire.

Testez convenablement le montage
Bien tester le montage avant de faire un branchement sur Arduino.

Vérifier les courants de base:
Il fait veiller à ce que les courants de commande Con1 et Con2 (de base des transistors) ne dépassent pas les limites admissible par Arduino (20-30 mA).
Faire quelques mesures est donc tout à fait approprié.

Tests manuels:
Ensuite, il est préférable de faire ses premiers tests sans utiliser Arduino.
Pour ce faire, vous placer vous même Vcc ou Gnd sur Con1 et Con2. Cela permet de vérifier le bon fonctionnement sans prendre de risque.

Test en charge:
Si vous utilisez un moteur DC, le courant à vide peut être assez faible (~25mA) alors qu'il pourrait être nettement plus important en situation de charge.
N'hésitez donc pas a freiner manuellement votre moteur (éventuellement jusqu'à l'arrêt) tout en surveillant le courant de charge.
Il serait bien dommage que votre montage rende l'âme si le moteur devait être bloqué... parce qu'on ne sait jamais si les dégâts n'entrainerons pas aussi Arduino dans la catastrophe.

Un pont H pour de vrai
Sur base du schéma précédent et d'un petit moteur DC récupéré dans un très vieux lecteur CD pour enfant.
Montage:
Q1 et Q2: PNP KSC1815, ECB, Ic=150mA, Vce_max=50v, Beta=70 a 400 (100 au multimètre). Vce_sat=0.25 (0.5v en réalité).
Q3 et Q4: NPN KSA1015, ECB, caractéristiques similaires à Q1.
R1, R2, R3, R4: 20 kOhms.
Charge: Moteur DC + Résistance de 35 Ohms.
Vcc: +7.5 volts (pour contrebalancer les pertes de Vce_Sat).
C1 et C2: Non utilisés.
Tension de commande: 5v (via arduino).


Mesures:
Ic = Imoteur = 25mA (à vide) - 40mA (bloqué).
Umoteur=5v (à vide), 3.2v (en charge), 0.6v (bloqué)
Lorsque Ic augmente, chute de tension Vce augmente aussi donc Umoteur chute.
Vbe=0.88v (à vide), 0.95v (bloqué).
Ib=0.25mA (à vide ou bloqué, semble ne pas être influencé par la charge).

Commande via Arduino
Description
Soit un programme de commande assez simple à l'aide de deux boutons "+" & "-".
Au démarrage, le moteur est à l'arrêt.
Quand on pousse sur "+", le moteur accélère dans un sens à chaque pression.
Quand on pousse sur "-", le moteur accélère dans l'autre sens à chaque pression.
Si le moteur est déjà lancé dans un sens, pousser sur le bouton opposé  décélère le moteur (à chaque pression). Le moteur doit passer par une phase d'arrêt avant de de commencer à tourner dans l'autre sens.
Deux Leds "Avant" & "Arrière" servent à indiquer le sens de rotation.
Lorsqu'elles sont toutes deux éteintes, le moteur est à l'arrêt.



Raccordement
  • Pour le montage proprement dit, voir le schéma et les spécifications présentées plus haut dans l'article.
  • Une alimentation externe de +7.5 volts est utilisé pour commander le pont H et le moteur. Attention a bien raccorder les masses ensembles.
  • Les pins de commande du Pont H raccordées sur les sortie PWM 10 et 11.
  • Deux boutons poussoir (pull-down) sont raccordés sur les pin 8 (+) et 9 (-).
  • Led 1: Pin 13 (on-board Led)
  • Led 2: Pin 3.
Programme


Le programme utilise encore le code prototype de la future classe PushButton.
Sinon, le reste du code est assez clair.
J'utilise une variable currentSpeed qui varie de -255 à +255. Dans les valeurs négatives, le moteur est commandé dans un sens, dans les valeurs positives, il est commandé dans l'autre sens.
La valeur de currentSpeed varie en fonction du nombre de pression sur les boutons Plus/Moins. Le code fait en sorte de toujours passer par la valeur 0 mais aussi +255 et -255.

Source: PontH_transistor.pde
/*
 *  Control d'un Pont H (pin 10 & 11) à base de transistor
 *
 *  A partir d'une commande bouton + et + (pin 8, 9)
 *  Affichage etat via led (pin 13 & 3)
 *
 * Schema sur article: 
 */

// ==========================================================
//     Button Helper
// ==========================================================

.... see source file

// ==========================================================
//     MAIN PROGRAM
// ==========================================================

const int pinH1 = 10;
const int pinH2 = 11;

const int pinDown = 8;   // jaune
const int pinUp   = 9;   // violet

const int pinLedDown = 3; // gris
const int pinLedUp = 13;  // on Board led

buttonData btnUp, btnDown;

void setup(){
  btnUp = attachButton( pinUp );
  btnDown = attachButton( pinDown );
  
  // Leds
  pinMode( pinLedDown, OUTPUT );
  pinMode( pinLedUp, OUTPUT );
  
  // Pont H handling
  pinMode( pinH1, OUTPUT );
  pinMode( pinH2, OUTPUT );
  analogWrite( pinH1, 0 );
  analogWrite( pinH2, 0 );
  
  Serial.begin( 9600 );
}

int currentSpeed = 0; // from -255 to +255
int newSpeed = 0;

void loop(){
  newSpeed = currentSpeed;
  
  updateButton( &btnUp );
  updateButton( &btnDown );
    
  // manage new speed
  if( pressedReadButton( &btnUp ) ){
    newSpeed += 25;
    if( newSpeed >= 255 )
      newSpeed = 255;
  }
  if( pressedReadButton( &btnDown ) ){
     newSpeed -= 25;
    if( newSpeed <= -255 )
     newSpeed = -255; 
  }
  
  // force a passage to Zero (when decreasing from max)
  if( newSpeed == 5 || newSpeed == -5 )
    newSpeed = 0;
    
  // Si pas de changement -> exit
  if( newSpeed == currentSpeed )
    return; 
    
  // Manage the Leds display
  if( newSpeed == 0 ){
    digitalWrite( pinLedUp, false );
    digitalWrite( pinLedDown, false );
  }
  else 
    if( newSpeed > 0 ) {
      digitalWrite( pinLedUp, true );
      digitalWrite( pinLedDown, false );
    }
    else {
      digitalWrite( pinLedUp, false );
      digitalWrite( pinLedDown, true );      
    }
    
Serial.println( newSpeed );
 
  // Manage the H Bridge - STOP
  if( newSpeed == 0 ) {
    analogWrite( pinH1, 0 );
    analogWrite( pinH2, 0 );
Serial.println( "0, 0");
  }  
  else
  
  // Manage the H Bridge - Direction 1
  if( newSpeed < 0 ) {
    // from positive to negative value
    // ensure H2 is down before setup H1
    if( (currentSpeed >=0) && (newSpeed<0) ) { 
      analogWrite( pinH2, 0 );
Serial.println( "h2 = 0 ");
    }
    int absNewSpeed = -1 * newSpeed;
Serial.print( "h1= " );
Serial.println( absNewSpeed );
    analogWrite( pinH1, (-1 * newSpeed) );
  }
  else

  // Manage the H Bridge - Direction 2
  if( newSpeed > 0 ) {
    // from negative to positive value
    // ensure H1 is down before setup H2
    if( (currentSpeed <=0) && (newSpeed>0) ) { 
      analogWrite( pinH1, 0 );
Serial.println( "h1 = 0 ");
    }
Serial.print( "h2= " );
Serial.println( newSpeed );
    analogWrite( pinH2, newSpeed );
  }
  
  // Remember speed
  currentSpeed = newSpeed;
}

Conclusion
Montage dont l'apprentissage est fort intéressant.
Dans la pratique, le "pont H" est disponible sous forme de circuit intégré directement utilisable (voir article à venir dans la section moteur DC).

Les moteurs DC de récupération en PWM
Par contre, l'utilisation de moteur de récupération montre quand même ses limites. Ces moteurs n'ont rien à avoir avec la robotique et sont prévus pour fonctionner directement dans leurs conditions optimales... (à pleine tension au démarrage).
Autrement dit, la commande PWM à basse vitesse est peu efficace et le moteur peine à démarrer (décoller).

Un autre désavantage des moteurs de récupération est que l'on ne connait pas leurs caractéristiques.
Ainsi, la mesure du courant à vide à pleine tension n'est pas forcement représentatif du courant qui circulera lors de l'utilisation d'un pont H (à cause de la chute de tension des transistors).
A vide j'avais mesuré 300mA en 4.5 volts, dans le pont H, ce courant est de l'ordre de 25 à 40 mA.

Il me faudra donc faire quelques recherches complémentaires sur les moteurs DC utilisés en robotique et de préférence utiliser des moteurs dont l'on connait les caractéristiques.
Cela fera également l'objet d'un autre article.

Les circuits intégrés à Pont-H
Il existe différents circuits intégrés constituant des pont-H prêts à l'emploi.
Certain d'entre-eux contiennent déjà les diodes de protections, d'autres pas.
Pour en savoir plus, vous pouvez consulter les différents articles relatifs à la famille de composant L293 et L298 dans la catégorie Moteur-DC.