Pleine puissance monsieur Sulu !

Comme déjà évoqué précédemment je me suis mis à l'électronique amateur depuis quelques temps, et j'en arrive aujourd'hui au point où j'ai assez de matière pour écrire un nouveau petit billet. Dans ce billet je vais donc tenter d'expliquer clairement les problèmes qui se sont posés lorsque j'ai tenté de controller des moteurs avec mon micro-controlleur, et surtout la solution que j'ai trouvé ! Vous allez voir c'est amusant :)

DC Engine - Creative Common by "Zach Hoeken" on Flickr

La problématique

Tout est parti de l'envie de controller des moteurs à partir de mon arduino. Pour être plus précis je voulais controller des moteurs assez puissants pour pouvoir mouvoir un robot autonome embarquant donc l'arduino, des batteries, et tout un tas d'électronique et de mécanique utile ou inutile.

Concernant les moteurs le choix s'est immédiatement porté sur des moteurs à courant continu. J'aurai pu viser des servo-moteurs à rotation continue ou des moteurs pas à pas qui sont beaucoup plus simples à commander, mais ces solutions sont beaucoup plus honéreuses et ont donc vite été oubliées étant donné que le but est de jouer à moindre cout. Un moteur à courant continu c'est tout bête : on applique une tension entre les deux bornes du moteur et celui-ci se met à tourner à une vitesse proportionnelle à la tension appliquée[1]. Petite subtilité : si vous fournissez une tension variable périodiquement (sinusoïdale, carrée, triangle, ou n'importe quoi d'autre) de fréquence "suffisante" le moteur ne prendra en compte que la moyenne de votre signal et tournera donc de façon régulière comme si vous lui aviez appliquée une tension continue équivalent à la moyenne de votre signal périodique[2].

Pour controller la vitesse de rotation d'un moteur à courant continu on a donc une solution ultra classique qui consiste à lui appliquer une tension périodique en forme de créneau de valeur maximale fixe. En faisant varier la proportion de temps où le créneau est haut par rapport à la proportion de temps où le créneau est bas on fait très simplement varier la moyenne de la tension appliquée, et donc la vitesse de rotation du moteur. Ce système est connu sous le nom "modulation de largeur d'impulsion" l'équivalent anglais c'est "Pulse Width Modulation" qui lui donne son patronyme le plus connu (même pour les francophone) : PWM ! Ca tombe bien : pleins de micro-controlleurs sont capables de sortir des PWM, et en particulier l'arduino sait faire ça très bien et très simplement grace à la commande analogWrite(PIN, valeur). Si on résume voilà la tête de deux signaux exemples, l'un avec une PWM qui a un voltage moyen de 2,5V (50% du temps à 5V, 50% du temps à 0V) et l'autre qui a un voltage moyen de 1V (20% de 5V, 80% du temps à 0V)[3] :

PWM signals

Si on résume : je n'ai qu'à brancher une borne de mon moteur à la masse et l'autre borne à une broche de mon arduino sur laquelle j'utilise la commande analogWrite. Ainsi mon arduino va générer un signal PWM sur cette broche, signal que le moteur va comprendre comme un ordre de tourner à une vitesse correspondant à la moyenne de ma PWM, donc juste en jouant sur le second paramètre de analogWrite(PIN, vitesse) entre 0 et 255 je fait varier la vitesse de rotation de mon moteur de 0% à 100% de ses possibilités. Ca a l'air trop simple pour être vrai, mais en fait ça marche :) ! Par contre ce système a 2 gros problèmes, que nous allons voir les uns après les autres.

Sans puissance, la maitrise n'est rien

Lorsque je vous ai dit qu'un moteur à courant continu c'était simple et qu'il suffisait d'appliquer une tension à ses bornes pour qu'il tourne j'ai bien pris soin de préciser que ça ne marchait que si on lui fournissait une intensité de courant suffisante. C'est là que la premier problème se pose : un micro-controlleur (comme ceux qui sont au coeur des arduino) ce n'est pas prévu pour fournir une forte intensité de courant, et généralement ça n'en fournit pas assez pour faire tourner un moteur. A titre informatif l'arduino UNO peut sortir jusqu'à 40mA par PIN, ce qui est pile le courant consommé par un de mes mini-moteurs quand ils n'a aucune charge à entrainer (c'est donc, grossièrement, un dixième du courant maximal que ce même moteur est susceptible de demander s'il est chargé à son maximum). Sachant que mes mini-moteurs sont environ 3 fois plus petits qu'une pile AA j'espère que vous réalisez maintenant à quel point 40mA est une intensité liliputienne dans notre contexte :-) Le premier problème qui se pose à nous est donc : comment vais-je augmenter l'intensité du courant envoyé à mes moteurs :( ?

La réponse la plus triviale qui peut venir c'est : utiliser un transistor :) Pour ceux qui ne savent pas du tout comment marche un transistor sachez que, en très résumé, c'est un composant qui posssède trois pattes appelée "Base", "Collecteur", et "Emetteur".[4] Dans le mode de fonctionnement qui nous intéresse voilà comment se comporte le transistor :

  • Quand on envoie un courant, même de faible intensité, sur la base du transistor celui-ci "ouvre une vanne" entre son collecteur et son emeteur ce qui permet de faire passer de l'une de ces pattes à l'autre environ 100 fois le courant que l'on a envoyé sur la base.
  • Quand on ne fournit pas de courant sur la base du transistor alors celui-ci se comporte comme un interrupteur ouvert entre le collecteur et l'emetteur.

Une fois ce mécanisme bien compris il devient naturel d'envisager l'utilisation d'un transistor pour controller nos moteurs : on branche le signal PWM du micro-controlleur sur l'entrée "Base" du transistor et on se sert du courant 100 fois plus important circulant entre le collecteur et l'emetteur pour alimenter le moteur. Aussitôt dit aussitôt fait :

Amplification de puissance simple à base de transistor
Le transistor que j'utilise est un 2N1711. Ce transistor a pour principale qualité de correspondre à mes besoins puisqu'en lui fournissant environ 5mA sur sa base il permet de faire circuler jusqu'à 500mA entre son collecteur et son émetteur. La seconde grande qualité de ce transistor c'est que je l'ai trouvé à pas trop cher dans une boutique d'électronique à Nation ^_^ ! Quoiqu'il en soit le montage fonctionne, et le moteur tourne ! ... Mais fournir une intensité suffisante n'est pas le seul problème que l'on doit traiter.

Quand je m'avance toi tu recules, comment veux-tu que je ...?

Jusqu'à présent le branchement de notre moteur est plutôt simple : on branche une borne à la masse, et on envoie la commande PWM (amplifiée ou non en puissance) sur l'autre borne. Ce cablage "fixe" est simple à comprendre mais il ne permet de faire tourner le moteur que dans un seul sens :-/ En effet pour le faire tourner dans l'autre sens il faudrait pouvoir inverser le cablage en live, ce qui n'est pas vraiment réaliste. Sachant qu'à terme on aimerait bien faire rouler un robot, et donc disposer d'une marche arrière, il faut se résigner à abandonner ce branchement (et nos transistors) afin de se pencher sur un montage un poil plus complexe.

La solution à ce petit problème a, heureusement, été donnée il y a longtemps : le pont en H ! Pour résumer ce qu'est le pont en H : c'est un montage qui permet d'inverser le sens de branchement d'un dipole à la volée, sans toucher aux branchements physiques. Bonne nouvelle : ce montage étant ultra-classique on trouve des dizaines et des dizaines de circuits intégrés implémentant des pont en H ! Seconde bonne nouvelle : ils font quasiment tous l'amplification d'intensité par la même occasion. Pour ma part j'ai acheté un L293D (parce que, comme pour les 2N7111, je les ai trouvé pas cher et qu'ils répondent à mes besoins) mais d'autres références existent comme par exemple les SN754410 ou les L298[5].

Une fois notre pont en H à disposition le montage est simple. Tout d'abord les branchements essentiels pour que le circuit intégré puisse fonctionner :

  • Une PIN à la masse (sans commentaire).
  • Une PIN au voltage de référence correspondant au niveau "haut" logique (dans notre cas 5V car les signaux PWM générées par l'arduino sont entre 0 et 5V)
  • Une PIN à l'alimentation de puissance des moteurs (dans mon cas une batterie de 7.2V, mais on peut remplacer par n'importe quoi fournissant de la puissance avec un voltage compris entre 5V et 36V).

Les branchements de base effectués il suffit de relier "Input 1" et "Input 2" à deux bornes de l'arduino capables de générer des PWM, et "Output 1/Output 2" aux bornes du moteur. Pour faire tourner le moteur dans un sens il suffit par exemple d'envoyer une PWM sur "Input 1" et un signal nul sur l'autre; puis pour inverser le sens de rotation du moteur (sans toucher au cablage :D !) il suffit d'envoyer "0V" sur "Input 1" et une PWM sur "Input 2" ! Simple, non ^_^ ?

What else ?

Une fois que l'on est capables de faire tourner nos moteurs dans les 2 sens à une vitesse variable arbitraire on a déjà fait un grand pas vers la réalisation d'un robot mobile autonome, mais les pistes d'améliorations sont plus que nombreuses et feront peut-être l'objet d'articles ultérieurs. Pour vous donner quelques idées voici deux améliorations que j'ai déjà apporté à mon robot :) :

  • Dans l'article on utilise 2 signaux PWM pour controller un seul moteur mais ça serait mieux d'utiliser un unique signal PWM et un bit de sens en tout ou rien (l'arduino, comme tout les micro-controlleurs, n'étant capable de générer des PWM que sur un nombre réduit de ses sorties il est toujours bon d'économiser ces sorties là). Pour information ce petit tour de passe-passe peut être réalisé en utilisant, par exemple, un circuit intégré de la famille des 74XX pour faire de l'algèbre de bool sur nos signaux. En particulier le 7404 peut s'avérer utile (et suffisant :)) pour résoudre notre problème. Je vous laisse trouver la solution exacte ;-)
  • Il n'y a pas d'isolation sérieuse entre nos moteurs et notre arduino. Donc si nos moteurs se mettent à générer de l'électricité pour une raison ou pour une autre (oui, ça peut arriver) toute la puissance électrique générée risque de remonter jusqu'à notre arduino et peut potentiellement le griller :-/ Pour contrer ce risque on peut utiliser des "optocoupleurs"[6]. Ces petits circuits intégrés ont pour unique fonction d'apporter justement une isolation entre commande et puissance. En très résumé vous leur donnez à manger un signal logique en entrée et il vous le recopie sur sa sortie en vous garantissant qu'aucun reflux de puissance ne pourra remonter sur le signal logique :) Pour les plus intéressés d'entre vous sachez que la magie s'opère généralement grace à une LED et un photo-transistor, et voilà quelques références si vous en cherchez : 4N35, PC845, etc.

Notes

[1] pourvu que l'intensité du courant fournie soit suffisante

[2] La "magie" derrière tout ça c'est qu'un moteur à courant continu, de par sa construction même, peut être modélisé comme un circuit RLC qui s'avère être un filtre fréquentiel passe-bas :)

[3] La première PWM s'obtient avec analogWrite(PIN,125) et la seconde avec analogWrite(PIN,51)

[4] Je commence par parler des bipolaire car ils sont simples :)

[5] Les L298 proposent d'ailleurs nettement plus de puissance que les L293D, intéressez-vous à ceux là si vous voulez avoir des moteurs capables de bouger rapidement un robot digne de ce nom.

[6] un autre mot clef de la même famille c'est photocoupleurs

Commentaires

1. Le mercredi, août 24 2011, 16:13 par Gorgonite

A force de faire de l'électronique, tu finis par tout concevoir en ce sens... et à y passer des heures pour réinventer la roue (faudra que tu me montres xD )
Une fois ce "détail" réglé, que comptes-tu faire ? une montée en abstraction ? la coupe e=M6 (donc un bon automate robuste ^^) ? de la domotique et des robots qui balaieront les restes de tes soirées ?

2. Le dimanche, août 28 2011, 19:18 par Ozwald

Faut bien avouer que ça prend du temps, mais c'est fun :-D Je te montrerai avec plaisir en tout cas :)

Maintenant que ces "détails" sont réglés j'ai plusieurs axes d'amusements possibles :
- Remplacer l'arduino par un uControlleur plus petit (je viens justement de réussir à programmer un attiny85 en utilisant mon arduino comme un programmeur ISP :) !) afin de pondre des petits circuits autonomes pour pas cher. [FYI : http://hlt.media.mit.edu/wiki/pmwik... ]
- Réaliser des communications sans fil entre mon pc et mes montage (je pense faire un truc genre : PC==usb==>Arduino==InfraRouge==>Montage_autonome). J'ai reçu hier les composants électroniques pour générer/recevoir de l'infra-rouge donc "y'a plus qu'à" ;-) D'ailleurs ça pourrai également servir à faire communiquer les montages autonomes entre eux.
- Le robot qui nettoie le reste des soirées ça c'est évidemment dans les cartons :D ! A priori il passerait la serpillère (enfin, l'éponge ;-))
- La coupe de France de robotique : pourquoi pas si j'ai encore le droit de m'inscrire et que le sujet m'inspire (il devrait être publié début Septembre si je ne m'abuse).
- Je verrai également bien un petit robot (ultra simple) pour arroser mes plantes quand j'ai la chance d'avoir des vacances et de partir. Un truc à base de capteur d'humidité et d'une petite pompe à eau centrifuge faite maison ça doit le faire...

Bref : pleins de trucs à faire :-) !

3. Le lundi, août 29 2011, 22:11 par Gorgonite

pour le sans-fil, regardes du côté de ZigBee, c'est relativement économe en énergie et assez souple :)

tiens ton truc d'arrosage me fait penser à un article que j'ai vu dans une conférence en Chine sur un système multi-agent pour gérer automatique une serre ;)

4. Le jeudi, janvier 31 2013, 13:48 par yacine

merci parce que javai besoin d'aide je suis entrain de faire un projet je dois programmer une mini tourelle a 2 axe est ce que tu pourais m'aider a mieux comprendre merci

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.

La discussion continue ailleurs

URL de rétrolien : http://www.ozwald.fr/index.php?trackback/40

Fil des commentaires de ce billet