lundi, août 22 2011

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

jeudi, juin 23 2011

Les mains dans le cambouis

Après avoir passé des mois à faire de la sécurité informatique à haute dose on peut avoir envie de se changer un petit peu les idées (mais vraiment juste un peu). Ce genre de moment est l'occasion révée pour ressortir des vieux projets des placards ! Pour ma part j'ai ressorti 3~4 vieux projets et en moins de 2h ils ont tous, sauf un, dérivé vers la sécurité informatique (on ne se refait pas ^^ !). Histoire de jeter malgré tout une petite pierre hors de la thématique usuelle de ce blog je vais donc vous parler du dernier de ces projets (ça reste du Hack, ne vous inquiétez pas ;) )

Robot - Based on a picture published under the Creative Common license by "vmario" on Flickr
Il y a fort fort longtemps dans une contrée pas si éloignée que ça j'ai participé deux années de suite à la coupe de France de robotique. Nos deux participations furent des fiascos mais tant pis, on s'était quand même bien amusé ! Mes responsabilités dans l'équipe se cantonnaient au domaine informatique[1] et il faut bien avouer que c'était pour le mieux car j'étais une quiche en électronique (surtout en comparaison avec les brutes qu'on avait de ce coté là !). Le temps a passé et j'ai toujours considéré que connaitre un peu d'électronique m'ouvrirait pleins de nouveaux horizons d'amusements... Il y a quelques mois de celà j'ai donc craqué et j'ai investi lourdement (au moins...pfiou....facilement...oula....25£ au bas mot :D !) dans un arduino !!! J'ai également ratissé ebay, dealextreme, et oomlout pour obtenir une plaque de prototypage, des cables, des résistances de toutes les valeurs possibles, quelques diodes, et un capteur de distance infra-rouge [2].

Une fois tout ce petit matériel reçu j'ai enfin pu m'amuser à faire clignoter mes LED, à changer les patterns de clignotements en fonction de la distance retournée par le capteur, etc. Puis mon jouet est tombé dans l'oubli, submergé par un ras de marré de sécu informatique. La semaine dernière l'envie de ressorti mon arduino s'est fait sentir et en particulier celle de lui faire commander des moteurs ! Pour le signal de commande aucun problème, l'arduino possède une commande toute faite pour envoyer une PWM sur un port de son choix. Reste donc à acheter des moteurs adéquats, et à trouver une façon de leur envoyer de la puissance.

Pour faire simple j'ai d'abord acheté deux micro moteurs 6V consommant 40mA. C'est extrèmement faible, mais c'est pour une bonne raison : l'arduino est capable de fournir cette puissance là tout seul, sans électronique de puissance supplémentaire :) En choisissant ces moteurs je m'assure donc de pouvoir jouer un petit peu mais probablement pas de faire un robot capable de se déplacer. En effet l'arduino seul fournira à mes moteurs la modeste puissance de 0,2W[3], à titre de comparaison à la coupe de France nos moteurs tournaient autour des 30~40W :-D

Seulement voilà : la livraison de mes moteurs devrait prendre au moins 10 jours :-( ...Du coup je me suis dit qu'en les attendant j'allais réfléchir à une carte de puissance capable d'alimenter de plus gros moteurs (et donc, pourquoi pas, de rendre mon arduino mobile). C'est à ce moment du billet qu'on retombe dans l'informatique (et qu'on compte sur les doigts d'une main le nombre de mes lecteurs qui sont arrivés jusqu'ici lol) : pour confirmer les cartes de puissance que je pourrait imaginer j'ai décidé de les simuler sur ordinateur plutôt que d'envoyer un mail toutes les 10mn pour demander leur avis à mes amis qui sont forts en électroniques. Mais pour simuler un circuit électronique il faut un logiciel de simulation électronique, or il s'avère que ce n'est pas si simple à trouver. C'est donc là que ce billet prend tout son intéret : vous faire part de mon retour d'expérience en la matière et vous éviter de galérer autant que moi si l'envie vous prend de faire mumuse avec un fer à souder virtuel.

Le cahier des charges est simple : il me faut un logiciel gratuit, fonctionnant sous linux, et qui soit capable de simuler tout les petits circuits simples auxquels je pourrai penser. Après quelques recherches sur google j'ai trouvé pas mal de pages faisant des comparatifs des différents logiciels disponibles malheureusement beaucoup des infos présentes sur ces pages étaient vieilles et ne correspondaient plus du tout à la réalité. Du coup j'ai passé plusieurs jours à débrousailler le terrain pour ne finalement conserver que deux logiciels valables : Oregano d'une part, et gEDA d'autre part.


Oregano

Oregano - screenshot by Ozwald

J'ai commencé par Oregano parcequ'il a une interface super user-friendly et semble monolythique (donc simple). A l'usage il est effectivement très agréable mais je lui ai très vite trouvé deux inconvénients :

  • Impossible de trouver comment faire des mesures de courant. Poser des sondes de tension est enfantin, mais les sondes de courant doivent se cacher quelque part au fin fond d'un menu d'option et je ne les ai pas trouvé...
  • régler finement les paramètres de ses composants (en particulier des semi-conducteurs) parait impossible. En pratique c'est possible mais ça n'a rien d'intuitif. En effet, alors que toute l'interface est ultra simpliste, il faut aller éditer l'onglet "model" des propriétés du composant pour y renseigner le model SPICE brute (ce qui est franchement cabalistique et semble contre-nature par rapport au reste de l'interface "clic clic").

Finalement je pourrai l'utiliser...d'autant qu'il permet d'exporter les schéma au format netlist (j'expliquerai ce que c'est un peu plus tard) et que je pourrai donc facilement faire mes mesures de courant. Mais bon...comme je suis passé à gEDA quand je n'arrivais pas à spécifier les caractéristiques d'un pauvre transistor bipolaire, je reste pour l'instant sur gEDA !


gEDA

Alors là c'est du lourd ! gEDA est en fait un conglomérat de plusieurs logiciels spécialisés chacun dans une étape du travail de l'électronique, ce qui lui permet d'être très puissant[4] mais aussi de faire très peur aux débutants :-D En réalité, après m'être penché un petit peu sur le monstre, les fonctions que je souhaite réaliser se résument dans seulement deux tout petit logiciels qui se maitrisent finalement assez vite.

gschem - Screenshot by Ozwald Tout d'abord il y a gschem qui permet de "dessiner" son schéma électronique. Le maniement est beaucoup moins intuitif que celui d'oregano mais au moins il est homogène : que celà soit pour paramétrer un transistor ou une résistance la démarche est la même (à savoir : vous n'avez qu'à ajouter manuellement à votre objet un paramètre de nom "value" qui contient le code SPICE du composant). Cet outil ne sert qu'à dessiner le schéma par contre, vous ne pourrez pas faire de routage avec, et vous n'avez pas à placer de sondes de tensions/courants/autre sur le schéma comme vous devez le faire avec oregano. Une fois le schéma dessiné vous le sauvegarder au format gschem (format par défaut) et vous passez au logiciel suivant...

gspiceui - Screenshot by Ozwald ...gspiceui ! Le petit logiciel gspiceui (qui ne fait pas parti de la suite gEDA d'ailleurs lol) va vous permettre de simuler votre circuit. D'ailleurs si vous êtes sous gentoo pensez à le compiler avec les flags "waveform" et "schematics"[5], si vous êtes sous ubuntu n'utilisez pas la version packagée mais allez plutôt télécharger la dernière[6].

Bref, pour réaliser une simulation avec gspiceui vous devrez importer le schéma réalisé avec gschem (menu File>Import), vous sélectionnez les composants du schéma que vous voulez observer, vous sélectionnez le type de simulation à faire (la simulation temporelle correspond à l'onglet "Transient"), vous choisissez les paramètres temporels de la simulation, les grandeurs que vous voulez observer (courant, tensions, etc.) puis il ne reste plus qu'à créer un fichier de simulation (menu "Simulate>Create"), à lancer la simulation (menu "Simulate>Run"), et à lancer l'appli de visualisation de vos courbes (menu "Simulate>Data viewer").

Une fois le "Data Viewer" lancé vous pouvez glisser/déposer les grandeurs que vous voulez observer depuis la fenêtre flotante contenant la liste de toutes les grandeurs disponibles jusqu'à la zone de traçage de courbe et voilà !

Il ne me reste plus qu'à conclure en vous disant qu'aussi bien oregano que gspiceui s'appuient en fait discrètement sur des moteurs de simulation électronique indépendants (le plus connu étant "SPICE", mais gnucap fonctionnant tout aussi bien si ce n'est mieux (c'est d'ailleurs ce dernier que j'utilise)) ; Que ces moteurs de simulation mangent des fichiers au format "netlist" qui sont générées par oregano ou gspiceui[7] ; Que les deux derniers screenshots (gschem et gspiceui) correspondent justement à un schéma d'alimentation de puissance pour moteur que j'ai moi-même pensé ; Que cet amplificateur de puissance fonctionne ; Qu'il est super simple et tout pourri aussi bien en rendement qu'en fonctionnalités (il ne permet de faire tourner le moteur que dans un seul sens par exemple) ; Mais qu'il fonctionne (oui, j'en suis fier :-p !) ; Et enfin que je vous déconseille de l'utiliser en l'état car sur les screenshots il manque la diode de roue libre.

Allez, on se quite sur la description SPICE d'une diode (pour vous prouver que c'est vraiment cabalistique et que ça ne colle pas du tout avec l'interface bisounours d'oregano) :

MODEL 1N1004 D (IS=0.5UA RS=6 BV=5.20)

Notes

[1] et un petit peu de mécanique quand ça se résumait à manier l'arme ultime du travail propre : le pistolet à colle

[2] le même type que ceux qu'on avait utilisé sur notre robot :)

[3] Souvenez-vous : P = UI. Dans mon cas I=40mA et U=5V (et non pas 6V, car l'arduino sort en 5V tout simplement)

[4] Vous pouvez tout faire avec gEDA, du design de schémas aux plans de routage en passant par les simulations électriques de tout poil

[5] sinon vous ne pourrez pas tracer de courbes, ou vous ne pourrez pas importer les schémas dessinés par gschem

[6] la version packagée sous ubuntu souffre d'un bug tout con qui rend le lancement de simulation impossible si vos paramètres de langue utilisent une virgule au lieu d'un point pour les nombres décimaux...ce qui est le cas en Français

[7] C'est justement lors de la génération des fichiers netlist que le problème de séparation des décimales rend la version de gspiceui packagée Ubuntu (9.98) inutilisable en environnement français

page 2 de 2 -