Mesures analogiques
Mettre en place des mesures analogiques de tension ou courant sur un Raspberry Pi n'est pas une mince affaire.Le problème tient essentiellement au matériel disponible.
Le problème du matériel
La très grande majorité des modules, cartes, hats disponibles pour le Raspberry Pi et qui comportent un convertisseur analogique numérique (CAN, ADC en anglais) ont des limites d'utilisation qui les rendent pratiquement inutilisables. Quelles sont ces limites :
- Presque jamais de protection électrique : Mettez une dizaine de volts en entrée et la carte fume. Et, 10 volts, c'est ce que sortent de simples piles.
- Pas d'ampli mesure et référence de tension généralement à 2,048V : Vous ne pouvez même pas mesurer le 3,3 VDC de la prise GPIO du Raspberry Pi.
- Les entrées analogiques sont toutes référencées à la masse : Pas de mesures flottantes et si la masse est bruitée, vous mesurez le bruit, qui par rapport,
à un référence de tension à 2,048V ne sera jamais négligeable.
Et ce ne sont la, que les principaux pépins.
A la limite, si vous acceptez de travailler sans protection électrique, et en mesures référencées à la masse, vous pouvez mettre en place un pont diviseur avec 2 simples résistances que vous aurez mesurées avec la meilleure précision possible. Vous divisez la, ou les tensions à mesurer pour obtenir des tensions en entrée du module toujours inférieures à 2,048V. Mais si un jour une des deux résistances de votre pont diviseur claque et devient passante... Une fois de plus, vous obtiendrez un peu de fumée.
Si vous en avez les moyens, vous pouvez développer vos propres amplis mesure à positionner devant les entrées d'un module d'acquisition analogique. Ci-dessous un schéma typique autour d'un ampli opérationnel. A vous de déterminer les bons composants en fonction de la gamme d'entrée en tension recherchée.

Il y a moins de 3€ de matériel, mais il faut se faire son PCB et être un champion du fer à souder. Pas mon truc !
Quelles solutions ?
On peut décider de passer en USB. Dans le monde professionnel, il existe une quantité impressionante de modules d'acquisition de données en USB et qui ont tout ce qui est nécessaire. Il y a pourtant deux soucis : Le prix explose (rien de correct à moins de 200€), et le nombre de produits supportant Linux se réduit à peau de chagrin (Dans ce métier, Windows reste très largement dominant).
Il existe des solutions spécifiques pour le Rapsberry Pi en bus I2C chez MCC sous la forme de cartes filles s'enfichant directement sur la prise GPIO. Leurs spécifications sont idéales, elles sont livrées avec des pilotes logiciels pour C/C++ et Python, elles permettent d'atteindre des fréquences d'acquisition jusqu'à 100 KHz, elles ont des gains programmables, des entrées différentielles ou référencées à la masse. Bref, tout le toutim. C'est du matériel professionel. Seul problème, le ticket d'entrées est à 200$ au minimum. Mon Raspberry Pi m'a couté environ 40€, je me vois mal mettre 5 fois ce prix pour 4 entrées analogiques différentielles. Tout du moins, pas pour ce que je fais à la maison.
Mais pour ceux que cela interesserai : MCC 128
Après avoir pas mal erré sur le WEB, j'ai fini par identifier deux solutions raisonnables. Celles basées sur le convertisseur ADC Texas Instruments ADS1115. Il en existe plusieurs sur le marché à des prix inférieurs à 20$. Les spécifications succinctes sont les suivantes :
- 2 entrées différentielles ou 4 entrées référencées à la masse,
- Tension maximale de mesure : 6,144V bipolaire,
- Pas de protection contre les surtensions,
- Courant maximal admissible en continu : 10 mA,
- Gains programmables : 2/3, 1, 2, 4, 8, 16,
- Fréquence d'acquisition maximale : 3 300 Hz.
Le composant ADS115 étant relativement simple, le nombre de registres restant limité, se développer un pilote logiciel en C/C++ devrait rester assez rapide.
Un exemple : Joy It KY053
Dernière solution. De loin la meilleure selon moi. La carte AI418S de ERE. Elle, au moins, dispose d'un vrai ampli mesure devant les entrées analogiques. Elle utilise un convertisseur MCP3424 avec 18 bit de résolution, et luxe ultime, ils ont même mis une résistance 249 Ohms en paralèlle des entrées. Cela permet des mesures de courant en 0-20mA ou 0-4OmA. A ces niveaux de courant, les cartes basées sur des ADS1115 ont déjà cramées. Les spécifications succinctes sont les suivantes :
- 4 entrées différentielles,
- Tension maximale de mesure : 11,17V unipolaire (pas de mesures de tensions négatives),
- Courant maximal de mesure : 40 mA,
- Résolution programmable : 12, 14, 16, 18 bit,
- Gains programmables : 1, 2, (4), (8),
- Fréquence d'acquisition maximale : Selon la résolution, De 3,75 Hz en 18 bit à 240 Hz en 12 bit.
C'est une solution un peu plus onèreuse que les solution à base de ADS1115 : Environ 38$. Cela s'explique. Comme le montre l'image ci-dessous, il y a un peu plus de monde sur la carte, elle dispose de borniers à vis, de connecteurs JST pour le bus I2C, et de jumpers pour définir son adresse I2C et la mise en place des résistances de terminaison I2C :

Ou la trouver : ERE AI418S
Et pour ceux qui utilise la librairie cpp2835, le composant MCP3424 dispose d'une classe dédiée : classe CMCP3424
Pour faire bonne mesure...
Faire des mesures analogiques en tension de relativement bonne précision impose de suivre quelques recommendations :
- Privilégier, si possible des cables blindés et/ou torsadés. Surtout pour des acquisitions à fréquence élevées. Ca vous évitera de mesurer la porteuse de France Inter, ou autres. Et cela vous
isolera un minimum du 50 Hz qui règne en maître dans nos maisons.
- Limiter la longueur des cables, autant que possible. Cela afin d'éviter des chutes de tension possibles dues à la résistance jamais nulle des cables.
Pour les mesures en courant 0-20mA ou 0-40 mA, ces deux précautions sont moins nécessaires. C'est la raison pour laquelle les mesures en courant sont privilégiées dans le monde industriel.
Méfier vous des problèmes d'impédance de source. C'est un cas assez rare, mais complexe à solutionner. Si l'impédance de ce que vous mesurez est supérieure à l'impédance d'entrée de votre carte d'acquisition analogique, vous allez écrouler le signal. Cela s'appelle un défaut d'adaptation d'impédances.
Le truc absolument nécessaire : Strapper les entrées non utilisées. Le problème est lié au composant, donc à la carte d'acquisition, lui-même. Pour proposer plus d'une voie de mesure, ces composants utilisent un multiplexeur, souvent en technologie CMOS. Le pépin est que les entrées analogiques présentent alors toutes une capacité électrique non nulle. Que se passe-t-il ? Si vous laissez une entrée analogique non cablée, c'est à dire qu'elle "voit" une résistance infinie, la capacité d'entrée va se charger. Comme elle est sur une résistance infinie, cette capa ne peut pas se décharger. Elle se déchargera dès qu'une voie de mesure sera cablée et que l'on demandera à mesurer cette voie. Résultat : La capa se décharge sur votre signal et celui-ci devient faux. J'ai déjà vu des erreurs de plusieurs dizaines de pourcent à cause de ce phénomène.
Pour éviter ce problème, la régle à suivre est simple : En entrées différentielles, reliez par un fil le + et le - des voies non utilisées. En entrées référencées à la masse, reliez le + de chaque voie non utilisée à la masse.
Conversions des mesures en tension ou courant
J'ai vu, sur les forums, revenir assez souvent la question suivante : Comment faire pour convertir ce que je lis en sortie de mon convertisseur analogique en tension ?
Pour faire cette conversion, ce que l'on a besoin de trouver c'est la résolution en tension du convertisseur (ou de la carte prise dans son ensemble).
Le plus simple est de prendre un exemple courant. Une carte avec une gamme d'entrée en tension de 10V bipolaire (C'est à dire, pouvant mesurer des tension de -10V à 10V) dispose donc d'une étendue totale de 20V. Supposons que cette carte dispose d'un convertisseur de 16 bit de résolution. Cela veut dire qu'elle peut mesurer un signal en entrée uniquement sur 216 = 65 536 valeurs discrètes. On divise 20V / 65 536 = 0,000305 V (305 µV). La résolution en tension de la carte est donc de 305 µV. Si, à titre d'exmple, je lis 50 000 sur mon convertisseur, cela veut dire que ma mesure de tension est : -10V + (50 000 X 305 µV) = 5,285789 V. On prend la borne minimale de la gamme (-10 V) à laquelle on ajoute la multiplication de la valeur lue sur le convertisseur par la résolution.
Cela se complique légèrement si notre carte dispose d'un gain programmable. Prenons comme exemple une carte basée sur le composant ADS1115. Ce composant dispose d'une pleine échalle de 4.096V bipolaire au gain de 1. Il peut donc mesurer à ce gain des tensions comprises entre -4.096V et +4.096V. Ce composant dispose de 5 gains possibles. Lorsque ce gain est supérieur à 1, il divise la gamme, lorsqu'il est inférieur à 1, il mulitplie la gamme. La résoluton étant toujours la gamme divisée par le nombre de pas du convertisseur, ici 16 bit, c'est à dire 65 536 pas, alors dans le cas du ADS1115 on obtient :
- Gain 1 : Gamme -4.096V à +4.096V - Gamme de 8.192 V - Résolution : 125 µV.
- Gain 3/2 : Gamme -6.144V à +6.144 V - Gamme de 12,288V - Résolution : 187 µV.
- Gain 2 : Gamme -2.048V à +2.048 V - Gamme de 4,096V - Résolution : 62.5 µV.
- Gain 4 : Gamme -1.024V à +1.024 V - Gamme de 2.048V - Résolution : 31.25 µV.
- Gain 8 : Gamme -0.512V à +0.512 V - Gamme de 1.024V - Résolution : 15.625 µV.
Si notre carte est unipolaire (elle ne mesure pas de tensions négatives), C'est encore plus simple. La borne minimale étant 0V, la mesure de tension est donc directement la valeur lue sur le convertisseur multipliée par la résolution.
Mais, il y a des exceptions. Ce serait trop beau... Certains convertisseurs utilisent le bit de poids le plus fort comme bit de signe. Bien sur, cela ne s'applique qu'aux cartes bipolaires. Un bit de signe étant inutile sur une carte unipolaire. Sur une carte équipée de ce genre de convertisseur, sur les 16 bit, il n'y en a alors que 15 pour définir la résolution, soit 215 pas de conversion = 32 768 pas. Sur une gamme de 0-10V en gain de 1, cela donne toujours une résolution de 305µv mais on doit exploiter la valeur lue sur le convertisseur de manière différente. On masque le bit de poids fort, on multiplie la résultat par la résolution. Ensuite, si le bit de poids fort est à 1, la valeur sera négative, si il est à 0, la valeur est positive. En C/C++, cela se traduit pas :
// dRange est la gamme unipolaire au gain de 1
// dGain est le gain programmable appliqué
// 327667 pour un covnertisseur 16 bit
Voltage = (ADRaw & Ox7F) * (dRange / dGain / 32767) * ((ADRaw & 0x80) ? -1.0 : 1.0);
A titre d'exemple, si la valeur retournée par le convertisseur est 45 000 sur une gamme en gain de 1 à 10V et un gain appliqué de 2. Le bit de signe est donc à 1, la mesure est négative. Le résultat sera :
- 45000 & 0x7F = 12 232
- 12 232 * 10 / 2 / 32767 = 1.8665
- 45000 & 0x80 = 1 donc : 1.8665 * -1.0 = -1.8665 V
Et comme la vie serait trop simple, il y a des exceptions aux exceptions. Certains composants comme le MCP3424 utilisé par la carte AI418S, non seulement, utilise un bit de signe, mais en plus, code les valeurs négatives en complément à 2. Ci-dessous le code issue de la classe CMCP3424 pour convertir les données reçues du convertisseur en tension :
{
// nRawValue : Valeur lue sur le convertisseur
// m_dADSteps : Nombre de pas du convertisseur
// m_unMask : Masque du bit de signe
// m_dGain : Gain programmable appliqué
int32_t Raw = nRawValue & m_unMask ? ~nRawValue + 1 : nRawValue;
return Raw * 2.048 / m_dADSteps / m_dGain;;
}
A titre d'exemple, si la valeur retournée par le convertisseur configuré en 16 bit est 45 000 sur une gamme en gain de 1 à 2.048V et un gain appliqué de 2. Le bit de signe est donc à 1, la mesure est négative. Le résultat sera :
- 16 bit : m_dADSteps = 32767
- 16 bit : m_unMask = 0x8000
- Gain 2 : m_dGain = 2
- nRawValue & m_unMask = 1 donc complément à 2 : ~nRawValue + 1. Donc Raw = 0x5037 : -45001
- Résultat : -45001 * 2.048 / 32767 / 2 = -1.4063 V