jeudi 4 juillet 2019

Mesurer une résistance avec un Raspberry Pi...sans ADC

Dans le présent billet, nous allons mesurer la résistance d'un potentiomètre, d'une photorésistance ou d'une thermistance grâce à un Raspberry Pi, en chronométrant le temps de charge d'un condensateur.

Un convertisseur analogique/numérique? Pas besoin!

Lorsqu'on désire lire la valeur d'une résistance avec un Arduino, par exemple, la méthode classique consiste à insérer la résistance inconnue dans un diviseur de tension, puis mesurer le potentiel au moyen d'une entrée analogique (l'entrée analogique étant équipée d'un convertisseur analogique-numérique, ou ADC pour analog-digital converter).

Le Raspberry Pi, toutefois, ne comporte pas d'ADC. Pour mesurer une résistance de cette façon, il faut ajouter un module ADC externe au Raspberry Pi (voir à ce sujet mes billets sur le MCP3008 ou le PCF8591).

La méthode que nous explorons aujourd'hui ne nécessite pas l'utilisation d'un ADC externe.

Le circuit

Le circuit schématisé ci-dessous est présenté dans le livre Raspberry Pi Cookbook, par Simon Monk. En plus de la résistance qu'on désire mesurer au moyen du Raspberry Pi (ici: un potentiomètre de 10 kΩ), le circuit est constitué de deux résistances de 1 kΩ et d'un condensateur de 220 nF.


Comme l'indique le schéma, une des 3 broches du potentiomètre n'est pas branchée au circuit. 

Vous pouvez très bien remplacer le potentiomètre par un autre capteur résistif comme, par exemple, une photorésistance ou une thermistance. Il pourrait être approprié de modifier la capacité du condensateur si votre résistance variable prend des valeurs qui ne sont pas de l'ordre du kΩ.

Principe de fonctionnement

Les entrées du Raspberry Pi sont numériques, ce qui signifie qu'on mesure un niveau logique BAS lorsque la tension est nulle, et un niveau logique HAUT si la tension est de 3,3 V. Mais qu'arrive-t-il si la tension varie de façon à passer progressivement de 0 à 3,3 V? Le niveau logique, initialement BAS, deviendra HAUT à un certain moment pendant l'augmentation de la tension. Le seuil entre BAS et HAUT est d'environ 1,2 V sur le Raspberry Pi que j'ai utilisé, mais ça peut varier d'un Raspberry Pi à l'autre.

Au départ, le condensateur n'est pas chargé, et le potentiel mesuré par l'entrée GPIO 23 du Raspberry Pi est donc nulle. On règle la sortie GPIO 18 au niveau logique HAUT, ce qui a pour effet d'amourcer la charge du condensateur. Plus la résistance du potentiomètre est élevée, plus le condensateur prend du temps à se charger.  À un certain point pendant la charge du condensateur, la tension mesurée par l'entrée GPIO 23 atteint la valeur à partir de laquelle le niveau logique est HAUT. Il s'agit de chronométrer le temps nécessaire pour que le niveau logique de l'entrée GPIO 23 passe de BAS à HAUT pour obtenir une valeur proportionnelle à la résistance du potentiomètre.

Il faut ensuite décharger le condensateur en vue de la prochaine mesure. Pour ce faire, la broche GPIO 23 devient une entrée (son impédance est alors très grande) et la broche GPIO 18 devient une sortie (faible impédance) au niveau logique BAS. Le condensateur se décharge donc à travers la broche GPIO 18.

La résistance de 1 kΩ  branchée à la broche GPIO 18 évite de court-circuiter cette broche si la résistance du potentiomètre devient trop basse. La résistance de 1 kΩ branchée à la broche GPIO 23 protège cette broche en évitant que la décharge du condensateur soit trop rapide.

Script en Python

Toutes les secondes, ce script affiche le nombre de microsecondes nécessaires pour que le condensateur se charge jusqu'à provoquer le niveau logique HAUT sur la broche GPIO 23.


Résultats

En faisant tourner le potentiomètre d'une position extrême à l'autre, j'obtiens un temps de charge qui varie entre 230 microsecondes et 1140 microsecondes environ. La position du potentiomètre a donc un effet évident sur la valeur mesurée.


Lorsque je ne change pas la position du potentiomètre, les résultats sont un peu fluctuants: à une extrémité, on peut lire 230, puis 317 à la lecture suivante...


À l'autre extrémité, on peut aussi bien avoir 1130 que 1228.


Ces fluctuations peuvent s'avérer problématiques si vous avez besoin d'une valeur très précise (il faut alors prendre quelques mesures consécutives et éliminer les valeurs aberrantes). Mais dans de nombreuses applications, ça n'aura pas d'impact majeur.

Une courbe d'étalonnage

Je me suis ensuite amusé à étalonner mon dispositif, afin d'afficher à l'écran la valeur de la résistance en ohms (ce qui est rarement utile, remarquez...). Pour ce faire, j'ai remplacé le potentiomètre par une résistance de valeur connue, et j'ai noté le temps de charge affiché par mon script.

Résistance (kΩ)
Temps (µs)
1,0
230
2,2
320
3,3
436
4,7
580
5,6
680
6,8
820
8,2
965
10
1150


Le résultat est linéaire. Je peux maintenant convertir le temps de charge en résistance en faisant ce calcul:     R = 0,00955 * t - 0,957

(notez que cette équation pourrait ne pas être valable sur un autre Raspberry Pi)

Script en Python donnant la valeur en 

J'ai donc modifié mon script pour qu'il affiche la valeur de la résistance en  plutôt que le temps de charge en µs.



Conclusion

La méthode fonctionne très bien. Les avantages par rapport à l'utilisation d'un module ADC externe sont surtout d'ordre économique: un condensateur et deux résistance, ça ne coûte pratiquement rien.

Certains inconvénients pourraient s'avérer problématiques pour certaines applications:

  • Les valeurs obtenues sont un peu fluctuantes et, occasionnellement, des lectures sont carrément aberrantes.
  • Le temps de charge, pour une résistance de 10 kΩ, est de l'ordre de la milliseconde, et on laisse le condensateur se décharger pendant 5 millisecondes: c'est beaucoup plus lent que la vitesse de lecture typique d'un ADC.
  • La plage des valeurs mesurées demeure inconnue avant d'en avoir fait l'essai, contrairement aux résultats d'un ADC (qui varient de 0 à 1023, par exemple, pour un ADC à 10 bits).
  • Les résultats pourraient être très différents d'un Raspberry Pi à l'autre, puisque la tension constituant la frontière entre l'état logique BAS et l'état logique HAUT n'est pas le même pour deux exemplaires différents.

Yves Pelletier   (TwitterFacebook)

2 commentaires:

  1. Merci pour cet article très intéressant. Il vient bien complété celui de mon blog qui lui explique la mesure d'une tension avec l'ADC des ESP8266:https://framboiseaupotager.blogspot.com/2019/07/tout-connaitre-du-suivi-des-charges-et.html
    Si vous m'y autorisez j'aimerai évoquer votre site et vos articles dans les miens ?
    Amicalement.

    RépondreSupprimer
    Réponses
    1. Oui, bien sûr.
      Bravo pour cet excellent blog, que je ne connaissais pas.

      Supprimer