samedi 25 avril 2015

Ajouter une sortie analogique à notre Arduino

Aujourd'hui, je vous explique comment régler une sortie de l'Arduino à n'importe quelle tension continue située entre 0 et 5 V.


Entrée analogique vs entrée numérique

Comme vous le savez sans doute, une carte Arduino comporte un certain nombre d'entrée numériques et d'entrées analogiques.  Une entrée analogique peut distinguer n'importe quelle tension se situant entre 0 et 5 V.  Par exemple, une entrée analogique permet à l'Arduino de distinguer une tension de 2,1 V d'une autre de 2,2 V:  ces deux tensions seront perçues comme des valeurs différentes l'une de l'autre.

Quant aux entrées numériques, elles ne reconnaissent que deux états:  les tensions hautes et les tensions basses.  Ainsi, peu importe que la tension soit de 0 V,  0,5 V ou 1,2 V, elle sera reconnue comme un signal logique bas, alors qu'un signal sera reconnu comme haut peu importe qu'il soit de 3,3 V, de 4,2 V ou de 5,0 V.

La tension d'une entrée analogique se lit au moyen de la commande analogRead, alors que la tension d'une entrée numérique se lit au moyen de la commande digitalRead.

Sortie numérique, mais pas vraiment de sortie analogique

Tout comme les entrées numériques, les sorties numériques ne peuvent se trouver que dans deux états possibles: 0 V (bas) ou 5 V (haut).  On règle l'état de la sortie au moyen de la commande digitalWrite.

Puisqu'il existe une commande analogWrite, on pourrait croire qu'il est possible de régler une sortie de la carte à une valeur analogique, c'est à dire à une tension qui pourrait prendre n'importe quelle valeur située entre 0 et 5 V.  Mais ce n'est pas le cas (du moins, pas directement):  contrairement à ce que son nom pourrait laisser supposer, analogWrite produit un signal modulé par largeur d'impulsion.

Modulation par largeur d'impulsion (MLI, ou PWM pour Pulse Width Modulation)

Un signal modulé par largeur d'impulsion oscille très rapidement entre 0 et 5 V, sans jamais prendre de valeurs intermédiaires:  il ne s'agit donc pas d'un signal analogique.  Un des arguments de la commande analogWrite est le rapport cyclique, qu'on décrit au moyen d'un nombre allant de 0 à 255.
  • Lorsque le rapport cyclique est de 0, le signal est toujours à 0 volt.
  • Lorsque le rapport cyclique est de 20% (donc 51), le signal est à 5 volts pendant 20% du temps, et bas pendant 80% du temps (pour une moyenne pondérée de 1 volt)
  • Lorsque le rapport cyclique est de 40% (donc 102), le signal est à 5 volts pendant 40% du temps, et bas pendant 60% du temps (pour une moyenne pondérée de 2 volts)
  • Lorsque le rapport cyclique est de 60% (donc 153), le signal est à 5 volts pendant 60% du temps, et bas pendant 40% du temps (pour une moyenne pondérée de 3 volts)
  • Lorsque le rapport cyclique est de 80% (donc 204), le signal est à 5 volts pendant 80% du temps, et bas pendant 20% du temps (pour une moyenne pondérée de 4 volts)
  • Lorsque le rapport cyclique est de 100% (donc 255), le signal est toujours à 5 volts.
Voici un sketch qui règle successivement le rapport cyclique de la pin 8 à 20%, 40%, 60%, 80% et 100%. en conservant la même valeur pendant 5 secondes avant de passer à la valeur suivante.



Et voici ce que ça donne à l'écran de mon antique oscilloscope:



Tous ça est fort utile pour varier l'intensité lumineuse d'une LED ou la vitesse de rotation d'un moteur mais, au risque de me répéter: il ne s'agit pas d'un signal analogique.

La solution:  un filtre passe-bas

Comme nous l'avons déjà mentionné dans un autre article, un filtre passe-bas est un dispositif conçu pour atténuer les oscillations de haute fréquence.  Si notre signal modulé passe par un filtre dont la fréquence de coupure a été convenablement choisie, il sera transformé en une tension continue se situant entre 0 et 5 V, selon son rapport cyclique.

Alors essayons:  la version la plus simple d'un filtre passe-bas, c'est la combinaison d'une résistance et d'un condensateur (filtre passif).  Ici, j'ai utilisé une résistance de 15 kΩ et un condensateur de 1 µF (j'ai utilisé les valeurs conseillées sur ce blog).



Et voilà, ça marche!  À l'oscilloscope, la succession de signaux de 0 et 5 V s'est maintenant transformée en une tension continue se situant quelques part entre 0 et 5 V.



Si on mesure le résultat avec un multimètre, on trouve environ 1 V quand le rapport cyclique est de 20%, 2 V quand le rapport cyclique est de 40%, etc.



Mais attendez un instant: tous nos tests ont été réalisés à vide, sans qu'une charge soit alimentée par la sortie de notre Arduino.  Ce serait plus prudent de vérifier comment se comporte notre sortie analogique si elle alimente une résistance.  Essayons une résistance de 1 kΩ, par exemple.



C'est la catastrophe!   Notre charge (pourtant très raisonnable) de 1 kΩ ne reçoit qu'une minuscule tension continue qui représente environ le dixième de ce qu'elle devrait être.  La raison:  la résistance de charge modifie les caractéristiques de notre filtre, qui se comportera différemment selon la charge qui y sera branchée.

La solution à ce nouveau problème:  un amplificateur opérationnel

La solution consiste à isoler le filtre de sa charge, en insérant entre les deux un amplificateur opérationnel branché en suiveur de tension (ça aussi nous en avons déjà parlé dans un précédent article).


Pour les tests, j'ai utilisé un UA741 alimenté à ±12 V au moyen d'une alimentation ATX, mais il est certainement possible d'utiliser un amplificateur "rail to rail" alimenté directement par l'Arduino.

Problème réglé!  La tension de sortie reprend la valeur désirée malgré la présence d'une résistance de charge à la sortie.



Et pourquoi pas une tension analogique supérieure à 5 V?

Pourquoi pas, en effet?  Puisque de toute façon il faut utiliser un amplificateur opérationnel, on peut très bien lui donner un gain supérieur à 1, de façon à ce que la tension de sortie soit supérieure à sa tension d'entrée.  Si votre amplificateur est suffisamment alimenté, rien ne vous empêche, par exemple, de régler la sortie à une valeur analogique située entre 0 et 10 V, par exemple.  Voir par exemple les montages proposés sur le site Sonelec, toujours aussi excellent.

Mais est-ce VRAIMENT un signal analogique?

Presque...  Un véritable signal analogique pourrait prendre n'importe quelle valeur entre la tension minimale et la tension maximale.  Par exemple, si vous tourner le bouton d'un potentiomètre pour le faire passer de 0 V à 5 V, vous pouvez être certain qu'en cours de route il est passé par la valeur 2,34348512 V, car la variation est continue.  Le signal "analogique" généré par notre dispositif ne peut prendre que 256 valeurs possibles.  Entre 0 et 5 V, ça représente une résolution de 5/256, donc environ 0,02 V.  Le signal de sortie passera donc directement de 0 à 0,2 V, sans passer par des valeurs intermédiaires comme 0,01 V ou 0,014 V.

Voir aussi cette autre méthode:  Ajouter une sortie analogique à l'Arduino:  réseau R-2R

Yves Pelletier   (Twitter, Facebook

2 commentaires:

  1. Très intéressant comme sujet.
    Par contre dans quel cas est-ce qu on aurait par exemple besoin d'une vrai tension continue de 2v et non un rco a 40% de 5v ?

    RépondreSupprimer
  2. Merci , cela m'a donné quelques idées sur un devoir que je suis entrain de faire
    MHD

    RépondreSupprimer