On pourrait se dire : « Pourquoi prendre un convertisseur analogique numérique externe (cet ADS1115), alors que l’Arduino possède déjà des entrées analogiques pour ce faire ? ». Et c’est une très bonne question, d’ailleurs !
Mais vous vous en doutez : si on fait appel à un petit module extérieur tel que celui-ci, c’est certainement qu’il y a une bonne raison ! C’est d’ailleurs ce que nous allons voir ici. Toutefois, afin que les choses soient le plus compréhensible possible, je les ai simplifiées au maximum.
Ici, nous allons aborder aussi bien la partie théorique, que la mise en pratique (bien plus fun !). Nous verrons donc ensemble le fonctionnement détaillé de l’ADS1115, ainsi que son pilotage via Arduino. Vous verrez d’ailleurs qu’il existe bien des façons d’utiliser ce petit module, suivant ses besoins. On en profitera bien sûr pour survoler tous les paramétrages de base de cette carte (vitesse d’échantillonnage, ajustement du gain, sélection d’adresse i2c), et découvrir toutes les différentes méthodes de mesure possibles.
Alors sans plus attendre, commençons par découvrir les caractéristiques principales de ce convertisseur analogique numérique (CAN, ou ADC en anglais) modèle ADS1115, afin de pouvoir s’en servir de manière optimale !
Nota : si jamais vous avez des questions, ou si vous relevez des coquilles, n’hésitez pas à m’en faire part en commentaire, afin d’améliorer le présent article, et les suivants ! Merci à vous !
Module | Description | Lien |
---|---|---|
Module ADS1115 "tout équipé" (pour pilotage I²C facilité, via Arduino ou autre) |
Caractéristiques et fonctionnement de l’ADS1115
Tout d’abord : qu’est-ce qu’un ADS1115 ? En fait, il s’agit simplement d’une puce électronique de chez TEXAS INSTRUMENT (datasheet ADS1115), permettant de faire de la conversion analogique numérique. Ainsi, par exemple, il est courant de s’en servir pour faire de la mesure de tension à intervalle régulier, et transmettre ces infos à un microcontrôleur.
Les avantages à utiliser une telle puce sont multiples : grande résolution, rapidité, amplification au besoin, et surtout, optimisation des entrées sorties. Car en effet, seuls deux fils suffisent pour contrôler cette mini plaquette ADC, et relever jusqu’à 4 tensions différentes (ça économise donc bien des entrées sur un microcontrôleur !). Mais trêve de compliments, et voyons tout cela plus en détail 😉
Résolution de 16 bits (supérieure à l’Arduino)
Voilà bien ce qui justifie l’utilisation d’un convertisseur analogique ADS1115, plutôt que les entrées analogiques de l’Arduino. Car la résolution de mesure est sans appel :
- Avec l’arduino, la résolution n’est que de 10 bits (puisque la valeur retournée se situe entre 0 et 1023). Du coup, pour bien se représenter la chose, dites vous que, si vous alimentez un Arduino en 5 volts, alors la résolution d’un bit vaudra 5/1024 volts, soit environ 4,8 mV
- Avec l’ADS1115, la résolution est de 15 bits (allant de 0 à 32767) : ainsi, si on travaille en 5 volts, la résolution de chaque bit équivaudra à 5/32768 volts, soit environ 0,15 mV
Soit un rapport de 32 entre ces deux valeurs, signifiant que la mesure faite avec l’ADS1115 sera 32 fois plus fin que celle faite avec l’arduino. Et croyez-moi, on a plus souvent besoin qu’on croit d’une telle résolution. C’est par exemple le cas, lorsqu’on cherche à mesurer la très faible chute de tension aux bornes d’une résistance de shunt, afin de déterminer le courant qui alimente une charge !
Remarque : si vous êtes attentif, vous avez sûrement dû vous dire que j’ai commis une erreur un peu plus haut. Car je vous ai parlé d’une résolution de 15 bits dans l’exemple ci-dessus, alors que cette puce est donnée pour une résolution de 16 bits (dans le datasheet, dans les descriptifs produits, …). Mais vous verrez qu’en fait, ces fameux « 16 bits » ne sont en fait qu’un tour de passe-passe marketing, justifié par la possibilité de lecture de tensions différentielles. Sceptique ? Ne vous inquiétez pas, car vous pourrez vérifier tout cela au moment des essais !
Tension d’alimentation, et tensions maximales sur les entrées de mesure (A0, A1, A2, et A3)
Pour commencer, un mot sur la tension d’alimentation de l’ADS1115 :
- Valeur recommandée : de 2 à 5,5 volts
- Valeur maximale (à ne pas maintenir longtemps) : jusqu’à 7 volts
En bref, ce convertisseur analogique numérique peut s’alimenter jusqu’à 7 volts pendant une courte durée, mais en temps normal, il faut se limiter à 5V maximum.
Si je vous parle de cette tension d’alimentation, ce n’est pas pour rien. Car celle-ci conditionne la tension maximale qu’on peut appliquer sur les entrées de mesures. Et s’il y a une première chose à retenir, c’est celle-ci :
La tension d’entrée à mesurer devra toujours être inférieure à la tension d’alimentation de l’ADS1115 + 0.3 volts, sous peine de détruire ce convertisseur analogique numérique !
Par exemple, dans l’absolu :
- Si vous êtes alimenté en +5V, la tension à mesurer ne doit pas dépasser 5,3 volts
- Si vous êtes alimenté en +3,3V, la tension à mesurer ne doit pas excéder 3,6 volts
Bien sûr, pour ne pas risquer d’endommager l’ADC, il vaut mieux rester dans la fourchette de valeurs recommandées par le fabricant, c’est à dire ici, de ne jamais dépasser la tension d’alimentation, tout simplement.
À noter que les autres entrées du convertisseur analogique numérique ADS1115, que sont SDA, SCL, ADDR, et ALERT/RDY, peuvent quant à elles être alimentées jusqu’à 5,5 volts (quelque soit la tension d’alimentation).
Gain, plages de mesure, résolution, et précision
Là où l’ADS1115 devient plus intéressant qu’un simple convertisseur analogique numérique basique, c’est qu’il intègre un PGA (Programmable Gain Amplifier), permettant d’amplifier un signal, pour faire des lectures plus précises encore.
Voici d’ailleurs le tableau spécifiant les valeurs mesurables avec cet ADC, en fonction du gain sélectionné :
Gain sélectionné | Plage de mesure théorique « constructeur » | Résolution, pour chaque bit |
---|---|---|
Gain de 2/3 (par défaut) | +/- 6.144V | 0.1875mV |
Gain de 1 | +/- 4.096V | 0.125mV |
Gain de 2 | +/- 2.048V | 0.0625mV |
Gain de 4 | +/- 1.024V | 0.03125mV |
Gain de 8 | +/- 0.512V | 0.015625mV |
Gain de 16 | +/- 0.256V | 0.0078125mV |
Donc grâce au PGA interne, il est possible d’amplifier le signal analogique jusqu’à 16 fois.
Deux remarques TRÈS IMPORTANTES :
- Vous avez certainement remarqué que certaines de ces plages de mesure (par exemple +/- 6.144 volts) dépasseront forcément la tension d’alimentation. Certaines de ces valeurs ne seront donc bien entendu absolument pas atteignables en pratique, car comme vu dans le paragraphe précédent, il ne faudra jamais dépasser la tension d’alimentation (au risque de griller l’ADC, à plus ou moins long terme)
- Vous avez certainement dû aussi remarquer la présence du signe « +/- ». Mais autant vous le dire tout de suite : l’ADS1115 ne permet absolument pas de lire des tensions négatives sur ses entrées, par rapport à la masse, malgré ce qu’on pourrait croire, et il ne les supporterait pas du tout d’ailleurs ! Ce signe est en fait un autre « tour de passe-passe » du fabricant, et atteignable seulement à l’occasion de lectures différentielles de tensions positives. Par exemple, si vous mesurez deux tensions sur cet ADC, avec « +1V » sur la première entrée analogique, et « +3V » sur la seconde, la tension différentielle sera de « +1V » – « +3V », soit -2 volts. On obtient donc une tension négative, à partir de la mesure de 2 tensions positives. Je pense que vous comprenez à présent qu’il ne s’agit juste d’une « façon de voir les choses », car il n’y a aucune tension négative en entrée !
Ainsi, les « vraies » plages de mesures possibles, en pratique, lorsqu’on mesure des tensions simples sur cet ADC par rapport à la masse, sont :
Gain sélectionné | Plage de mesure théorique | Tension d’alimentation | Tension réellement mesurable, en pratique | Résolution (pour 1 bit) |
---|---|---|---|---|
Gain = 2/3 (par défaut) | +/- 6.144 V | Si 5V Si 3,3V | Alors de 0V à +5V Alors de 0V à +3,3V | 0.1875 mV |
Gain = 1 | +/- 4.096 V | Si 5V Si 3,3V | Alors de 0V à +4.096V Alors de 0V à +3,3V | 0.125 mV |
Gain = 2 | +/- 2.048 V | Si 5V Si 3,3V | Alors de 0V à +2.048V | 0.0625 mV |
Gain = 4 | +/- 1.024 V | Si 5V Si 3,3V | Alors de 0V à +1.024V | 0.03125 mV |
Gain = 8 | +/- 0.512V | Si 5V Si 3,3V | Alors de 0V à +0.512V | 0.015625 mV |
Gain = 16 | +/- 0.256V | Si 5V Si 3,3V | Alors de 0V à +0.256V | 0.0078125 mV |
Comme vous le voyez, il ne faut pas mal interpréter les chiffres présentés dans les datasheets 😉
Pour autant, il ne s’agit pas là d’une publication mensongère du fabricant. Car dans l’absolu, on pourrait alimenter l’ADS1115 jusqu’à 7 volts pendant un court instant, et donc pouvoir faire des mesures jusqu’à 6.144 volts. Par ailleurs, les tensions négatives sont effectivement mesurables en mode différentielle (soustraction de mesures de tensions simples), tout en gardant bien à l’esprit qu’il ne s’agit que là d’une manière de présenter les choses. Car encore une fois, aucune tension négative de doit être appliquée aux entrées de ce convertisseur analogique numérique !
Par contre, je vous l’accorde : on ne retrouve pas forcément ce qu’on aurait pu espérer en lisant les premières lignes descriptives de l’ADS1115 ! Car si la résolution avait été de 16 bits sous 5 volts, on obtiendrait une valeur correspondant à 5/2^16 pour chaque bit, soit 0,0763 mV. Or ici, en réalité, on a environ 2 fois moins de « finesse », avec la gamme +/- 6.144V !).
Enfin, au niveau de la précision de l’ADS1115 en lui-même, il faut considérer une marge d’erreur potentielle, d’environ +/- 3 fois la résolution d’un bit. Par exemple, si on utilise l’ADC avec un gain égal à 1, on aura une marge d’erreur plus ou moins égale à environ 0.375 mV (soit 3 x 0,125mV unitaire, comme présenté dans le tableau ci-dessus).
Important : le datasheet du fabricant n’indique pas clairement quelle est la plage réelle de précision de ce convertisseur analogique-numérique (le % d’erreur de mesure, si vous préférez). Certes la résolution est grande (16 bits nous donne 1/65000ème), mais cela nous garantie pas « l’exactitude » de la mesure, d’autant plus qu’on n’a pas d’infos précises, ni retour externe, sur la référence de tension interne de cette puce (est-elle bien stable ? bien calibrée ?).
Mesures et pilotage : 4 canaux de lecture de tension, consultables via 2 fils seulement !
Autre atout du convertisseur analogique numérique ADS1115 : il permet des mesures de tensions à 4 endroits à la fois, par rapport à la masse, tout en ne prenant que 2 fils pour interagir avec un Arduino. C’est d’ailleurs toute la beauté de ce genre de puce électronique, sans parler des autres avantages (rapidité, « grande » résolution, …).
En effet, l’ADS1115 dispose de 4 entrées distinctes : A0, A1, A2, et A3. Et pour le pilotage de cet ADC, seuls 2 fils suffisent : SDA et SCL (l’interface i2c de l’arduino, donc).
Mais on peut aller bien au-delà de 4 mesures de tensions simples ! Car l’adresse i2c de l’ads1115 peut quant à elle prendre 4 valeurs différentes (selon comment est branchée la broche ADDR). Ainsi, si on utilise 4 modules ADS1115, on peut donc lire 16 tensions différentes, et piloter tout ça avec un seul arduino, sur 2 fils seulement ! Difficile de faire mieux, pour économiser au maximum les entrées/sorties de son microcontrôleur (qui sont assez limitées !).
Et pour s’adresser à un ADS1115 plutôt qu’un autre, tout se passe au niveau logiciel. Car comme chaque plaquette ADC aura une adresse i2c qui lui est propre, l’arduino pourra interroger qui il veut, quand il veut, et comme il veut !
Nota : l’ADS1115 n’a pas d’entrée type « Vref » pour avoir une tension de référence extérieure, à la fois stable et précise. En fait, il y a déjà tout ce qu’il faut dans sa puce, et donc, pas besoin de composants additionnels, à ce niveau !
Vitesse de lecture et d’échantillonnage (mesure de tension)
Sur l’ads1115, on peut sélectionner l’une des 8 vitesses d’échantillonnage possibles, notées DR (pour « Data Rate »), selon ses besoins :
- DR=0 : 8 SPS. Ici l’ADC aura un « data rate » égal à 8 lectures par seconde, ou 8 « échantillons par seconde », si vous préférez (aussi appelé « SPS » en anglais, pour « Samples per second »)
- DR=1 : 16 SPS
- DR=2 : 32 SPS
- DR=3 : 64 SPS
- DR=4 : 128 SPS. C’est la VALEUR PAR DÉFAUT (soit 128 échantillons mesurés par seconde)
- DR=5 : 250 SPS
- DR=6 : 475 SPS
- DR=7 : 860 SPS. Soit 860 lectures de tension par seconde !
Ainsi, le délai de conversion est fonction du DR choisi. Par exemple, si DR = 7 (soit 860 SPS), alors la mesure sera faite en près de 1/860 secondes, soit environ 1,16 ms.
À noter que cette vitesse d’échantillonnage a une influence sur la consommation du convertisseur analogique numérique (bien que celle-ci soit franchement ridicule, car 300 µA au maximum !), et sur le niveau de bruit (bien supérieur à 860 SPS, comparativement à 8 SPS).
À noter que la séquence de lecture d’une tension devra toujours se faire de la sorte :
- L’arduino doit demander à l’ADS1115 de lire de la tension sur telle ou telle entrée (A0 à A3)
- Puis l’arduino devra attendre que l’ADS1115 lui envoi un signal de confirmation en retour, lui disant que la tension a été mesurée, et que cette valeur est « prête à lire »
- Et enfin, l’arduino pourra récupérer cette valeur, stockée en attente dans l’ADS1115
La temps de lecture d’une tension est donc la somme de toutes ces étapes : échantillonnage + délais d’émission, d’attente, et de réception. Et ce temps définit la vitesse maximale réelle de mesures de tensions par seconde.
Module | Description | Lien |
---|---|---|
Module ADS1115 "tout équipé" (pour pilotage I²C facilité, via Arduino ou autre) |
Comment raccorder l’ADS1115 à l’Arduino ? (alimentation, adresse I2C, …)
Le convertisseur analogique numérique ADS1115 est clairement l’ADC de rêve, pour faire des mesures précises, et rapides. Et l’Arduino est sans conteste l’un des moyens les plus simples pour le piloter. Bien sûr, vous pourriez parfaitement vous servir d’un Raspberry Pi, ou d’un ESP32 pour ce faire. Mais je trouve qu’avec l’arduino, c’est plus simple à comprendre, et à mettre en œuvre, surtout lorsqu’on est débutant.
D’autant plus que cette mini plaquette est super facile à raccorder ! En effet, il n’y a que 10 pins présentes sur un module ADS1115 :
- Vdd : la tension d’alimentation (de 2 à 5,5 volts)
- Vss : la masse (0 volt)
- SCL et SDA : les lignes d’horloge et de données séries (i2c)
- ADDR : une pin servant à définir physiquement l’adresse i2c du module (4 adresses différentes possibles)
- ALRT : une sortie « d’alerte » (permettant par exemple à l’ADS1115 d’indiquer à un microcontrôleur qu’une tension a été mesurée, et que cette valeur est prête pour être lue)
- A0, A1, A2, et A3 : les quatre entrées analogiques, sur lesquelles pourront être lues des tensions (simples ou différentielles)
Adresse i2c : 4 choix possibles
Comme je vous disais précédemment, 2 fils suffisent pour piloter ce module : il s’agit des lignes SDA et SCL, de l’interface i2c Arduino. Mais comme tout appareil utilisant ce type de connexion, il faut que chaque carte i2c ait une adresse précise, pour pouvoir communiquer avec elle, sans erreur d’aiguillage ! Ce qui est le cas ici.
Avec ce module ADC, on peut choisir parmi 4 adresses différentes possibles, suivant où l’on raccorde la broche ADDR. Et pour être plus clair, rien de tel qu’un bon petit tableau !
Si branchement de la broche ADDR sur … | Alors l’adresse i2c sera : |
---|---|
GND | 0x48 => adresse par défaut |
VDD | 0x49 |
SDA | 0x4A |
SCL | 0x4B |
À noter que ce branchement est à faire physiquement sur le module, avant de le mettre sous tension. Autre remarque : vous pouvez parfaitement utiliser 4 x ADS1115 en même temps, branchés sur les 2 fils I2C d’un Arduino. Aussi, deux fils suffisent pour piloter jusqu’à 4 modules ADS1115 à la fois, et donc, lire jusqu’à 16 tensions différentes (puisque chaque ADC possède 4 canaux !). D’ailleurs, voici le branchement que vous pourriez faire :
Raccordement à l’Arduino UNO
Une fois qu’on a compris comment raccorder la partie i2c (SDA, SCL, et ADDR), il n’est pas compliqué de faire le reste ! Voici d’ailleurs un exemple de branchement, sur une carte Arduino Uno :
Notez que le branchement de la broche ALRT est « optionnel », en ce sens où on peut gérer le signalement d’une tension « prête à lire » de manière logicielle. Toutefois, l’alerte physique, plutôt que logicielle, est l’idéal si l’on veut par exemple déclencher une interruption sur un Arduino, chaque fois qu’une mesure est prête à lire. Cela permet de lui donner la pleine priorité, lors de l’exécution d’un programme, à n’importe quel moment.
Notion de mesure de tension simple, ou différentielle
Concernant les mesures de tension en elles-mêmes, celles-ci peuvent se faire de 2 manières différentes :
- Lecture absolue : ici, on mesure une tension fixe, dans les limites de l’ADC, et par rapport à la masse (0 volts).
- Lecture différentielle : ici, on mesure la différence de potentiel entre 2 points distincts (par exemple, aux bornes d’une pile). Dans ce cas, c’est comme si on faisait une lecture « flottante » de tension, entre deux points donnés.
Dans le premier cas, on est limité à une résolution de 15 bits, pour la lecture d’une tension positive, par rapport au référentiel commun (zéro volt). Ici, les tensions mesurables sont au nombre de 4, via les broches A0, A1, A2, et A3. La mesure de tension se fera par rapport à la masse (GND).
Dans le deuxième cas, on a une résolution égale à 16 bits (en fait de 15 bits et un bit de signe +/-), pour la lecture de tensions flottantes, sans référentiel commun. Une des applications classiques de ce mode, est la mesure de chute de tension aux bornes d’une résistance de shunt. Ainsi, on peut calculer le courant traversant quelque chose, au travers de la différence de potentiel mesurée aux bornes de cette résistance.
Dans le cas d’une lecture différentielle (2ème cas), les mesures se feront entre 2 entrées. Par exemple : entre A0 et A1, ou A2 et A3 (on peut faire bien d’autres combinaisons, dans les limites de ce que propose la librairie arduino utilisée).
Et pour rappel, aucune tension négative ou supérieure à la tension d’alimentation ne devra être appliquée sur les bornes d’entrées de l’ADS1115. Si l’on peut effectivement lire des « tensions négatives », c’est seulement en faisant des soustractions de tensions positives entre elles. Par exemple : « +0V » – « +5V » = – 5 volts. On voit donc bien qu’on peut mesurer une tension négative de manière différentielle, en soustrayant deux tensions positives mesurées.
Librairie pour ADS1115, avec paramètres de démarrage
Il existe bon nombre de librairies Arduino, pour communiquer avec un ADS1115. Mais celle qui me semble la plus appropriée, et la plus complète, au moment où je rédige cet article, est celle qu’on retrouve dans le gestionnaire de bibliothèques de librairie, dans l’IDE arduino. Il s’agit de la librairie « ADS1X15 » de RobTillaart (https://github.com/RobTillaart/ADS1X15), prévue pour les ADC ads1015 et ads1115 (donc parfaite pour nous !). Qui plus est, celle-ci dispose de tout un tas de réglages possibles, que d’autres n’ont pas la possibilité de faire.
Nous allons d’ailleurs voir ici tous les principaux paramètres, permettant d’interagir de manière optimale avec un ADS1115 !
Initialisation, avec définition de l’adresse i2c choisie
Comme toute librairie dont on souhaite se servir dans un projet arduino, il faut l’inclure dans le code, dès les premières lignes. Ensuite, il faut appeler cette librairie, en créant une instance de celle-ci, pour s’en servir. C’est ici d’ailleurs qu’on renseignera l’adresse i2c de la petite carte ADS1115 qu’on a raccordé à son arduino, sachant que les valeurs possibles sont : 0x48, 0x49, 0x4A, ou 0x4B (se sont des valeurs hexadécimales, oui !). Puis, il ne reste plus qu’à démarrer le tout, avec la fonction « begin » ! Au niveau du code, cela donne ceci :
#include "ADS1X15.h"
ADS1115 ADS(0x48); // ADS1115 physiquement défini à l'adresse 0x48
void setup() {
Wire.begin();
ADS.begin();
// Paramètres suivants ici
}
Nota : si vous ne renseignez aucune adresse i2c, le programme considérera que votre module ADS1115 se trouve à l’adresse « 0x48 », c’est à dire avec la broche ADDR branchée sur GND.
Paramétrage du Gain souhaité
Parmi les autres paramètres principaux, que l’on peut définir juste après l’appel de la fonction « begin », on retrouve celle permettant de définir le gain (comme vu dans le paragraphe 1.3). Là, vous aurez donc le choix entre 6 valeurs possibles.
Valeur du PGA (index) | Échelle de mesure théorique |
---|---|
0 (gain = 2/3) | ± 6.144 volts (valeur par défaut) |
1 (gain = 1) | ± 4.096 volts |
2 (gain = 2) | ± 2.048 volts |
4 (gain = 4) | ± 1.024 volts |
8 (gain = 8) | ± 0.512 volts |
16 (gain = 16) | ± 0.256 volts |
Au niveau de la programmation, cela se traduit de la manière suivante (il suffira de commenter/décommenter les lignes, en fonction de vos besoins)
ADS.setGain(0); // ± 6.144 volt (par défaut). À noter que le gain réel ici sera de « 2/3 », et non zéro, comme le laisse croire ce paramètre !
//ADS.setGain(1); // ± 4.096 volt
//ADS.setGain(2); // ± 2.048 volt
//ADS.setGain(4); // ± 1.024 volt
//ADS.setGain(8); // ± 0.512 volt
//ADS.setGain(16); // ± 0.256 volt
Nota : si vous ne mettez aucune valeur, ou toute autre valeur d’ailleurs, cela reviendra par défaut à exécuter la commande ADS.setGain(0).
Les 2 modes de lecture de tension : à la demande (single shot) ou en automatique (continuous)
Par ailleurs, il existe 2 façons de lire des tensions : de manière manuelle (à la demande), ou en automatique (de manière perpétuelle). Avec cette librairie, cela se définit avec la fonction « setMode », qu’il faut mettre à 1 pour faire des lectures ponctuelles, ou à 0, pour faire des lectures cycliques permanentes.
ADS.setMode(1); // 0 = CONTINUOUS, 1 = SINGLE (default)
À noter que par défaut, si aucune valeur n’est renseignée, ou si cette valeur est différente de 0 ou 1, cela revient à choisir le mode « single », soit la mesure de tension « à la demande ». Petite parenthèse : ne pensez pas que le mode continu serait la meilleure façon de procéder. Car dans ce mode, la consommation sera évidemment plus élevée qu’à la normale (même si ça reste faible, je vous l’accorde !), et le niveau de bruit sera plus important (donc mesures moins précises), attention.
Réglage de la vitesse de lecture
L’ADS1115 a une vitesse de lecture paramétrable. Cette vitesse, aussi appelée « vitesse d’échantillonnage » (SPS en anglais, pour « Samples per second »), ou encore « débit de données » (« datarate », en anglais), peut prendre 8 valeurs différentes.
Datarate (index de vitesse) | SPS (nombre de mesures faisables par seconde) | Remarques |
---|---|---|
0 | 8 | Le plus lent … |
1 | 16 | |
2 | 32 | |
3 | 64 | |
4 | 128 | Valeur par défaut |
5 | 250 | |
6 | 475 | |
7 | 860 | Le plus rapide ! |
Au niveau du code de programmation, sous l’IDE arduino, cela se traduira de la manière suivante :
ADS.setDataRate(7); // avec vitesse de mesure, allant de 0 à 7 (7 étant le max, soit 860 échantillons par seconde)
Nota : si vous ne définissez aucune vitesse, celle-ci sera par défaut mise à 4, lors de l’instanciation de la librairie. Cela correspond donc à une vitesse d’échantillonnage de 128 mesures de tension par seconde, que vous pouvez bien évidemment accélérer ou ralentir, avec la fonction « setDataRate », suivant vos besoins.
Demande de lecture de tension simple (par rapport à la masse)
Ici, on arrive enfin à la méthode permettant de lire des tensions simples, c’est-à-dire par rapport à la masse (0 volts). L’appel de cette fonction est vraiment facile à faire, d’ailleurs, puisqu’il suffit d’écrire qu’une seule ligne pour ce faire. Du coup, lorsqu’on veut lire les tensions des entrées A0, A1, A2, et A3, de l’ADS1115, on pourra écrire les lignes suivantes :
int16_t mesure_A0 = ADS.readADC(0); // Valeur entre -32768 et +32767
int16_t mesure_A1 = ADS.readADC(1);
int16_t mesure_A2 = ADS.readADC(2);
int16_t mesure_A3 = ADS.readADC(3);
À noter que le résultat de cette lecture de tension sera au format « int16_t », c’est-à-dire une valeur entière située entre -32768 et +32767. Et comme on ne peut lire que des tensions strictement positives sur l’ADC, le résultat de cette fonction sera par définition un nombre compris entre 0 et 32767. On s’aperçoit là qu’on a bien une résolution de 15 bits, et non de 16, comme le fabricant le laisse entendre 😉
Autre remarque : cette fonction est en faite la somme de 3 fonctions en 1. Car elle réalise les trois opérations suivantes, en arrière plan :
- readADC demande à l’ADC de lire une tension sur la broche souhaitée
- puis readADC attend que cette valeur soit prête (puisqu’il faut un certain temps pour qu’un ADC puisse convertir une valeur analogique présente sur l’une de ses broches, en valeur numérique)
- et enfin, readADC récupère cette valeur, pour pouvoir nous la communiquer
Cela veut donc dire que lorsqu’on appelle la fonction « readADC », on est « sûr » de lire la dernière valeur de tension présente sur l’entrée souhaitée (car on aura « attendu » que celle-ci soit lue ET « prêt à lire »).
Enfin, à noter que cette librairie met à disposition une fonction « toVoltage », permettant de convertir la valeur retournée par readADC, en tension exprimée en volts. Ainsi :
float tension_A0 = ADS.toVoltage(mesure _0); // Valeur exprimée en volts (dont l’amplitude sera automatiquement calculée en fonction du gain préalablement choisi
float tension_A1 = ADS.toVoltage(mesure _1);
float tension_A2 = ADS.toVoltage(mesure _2);
float tension_A3 = ADS.toVoltage(mesure _3);
Demande de lecture de tension différentielle (entre 2 des entrées analogiques, parmi les broches A0, A1, A2, ou A3 de l’ADS1115)
À l’image de la fonction précédente, il s’agit là aussi de lire une tension sur l’ADC. Mais cette fois-ci, cette mesure ne se fera pas par rapport à la masse, mais entre 2 des 4 entrées analogiques de l’ADS1115. Par exemple, si on veut lire la différence de potentiel entre les entrées A0 et A1, on appellera la fonction suivante :
int16_t difference_potentiel_A0_A1 = ADS.readADC_Differential_0_1();
Petite note : la différence de potentielle sera égale à A0 moins A1, et non l’inverse (A1-A0). Et bien sûr, en se rappelant qu’aucune tension négative ne peut être appliquée sur ces entrées. Ainsi, si vous avez par exemple 1 volt sur A0, et 4 volts sur A1, la tension différentielle sera égale à : (+1V) – (+4V), ce qui donne – 3 volts. On peut donc obtenir une mesure de tension négative, à partir de ces deux tensions positives (à l’image d’un voltmètre qu’on brancherait à l’envers).
Le résultat de cette fonction sera un entier signé à 16 bits, dont situé entre -32768 et +32767.
Au niveau des combinaisons de broches d’entrées, sur lesquelles on peut faire des lectures de tensions différentielles, on a le choix entre ces 4 possibilités :
- requestADC_Differential_0_1() // donne la tension A0 – A1 (valeur entre -32768 et +32767)
- requestADC_Differential_0_3() // donne la tension A0 – A3
- requestADC_Differential_1_3() // donne la tension A1 – A3
- requestADC_Differential_2_3() // donne la tension A2 – A3
Et là aussi, on peut facilement convertir ces valeurs en volts, avec la fonction « toVoltage », fourni avec cette librairie. Par exemple, pour connaitre la tension différentielle entre A0 et A1, il suffira d’écrire :
float tension_A0_A1 = ADS.toVoltage(difference_potentiel_A0_A1); // Valeur exprimée en volts, fonction de la valeur mesurée par l’ADC, et du gain sélectionné.
Module | Description | Lien |
---|---|---|
Module ADS1115 "tout équipé" (pour pilotage I²C facilité, via Arduino ou autre) |
Tuto ADS1115 : code arduino pour mesure de tension simple
Maintenant que nous avons vu la partie « théorique », passons à la pratique ! Pour ce faire, nous allons partir du schéma suivant. Dans les grandes lignes, ce montage permettra de lire la tension présente sur les 2 potentiomètres branchés en entrée, et de faire varier l’intensité lumineuse de 2 LED en conséquence. Ainsi, si le curseur d’un potentiomètre est complètement à gauche, alors la LED correspondante sera éteinte. À l’inverse, si le curseur est tourné complètement à droite, alors la LED sera pleinement allumée. Et enfin, si le curseur est quelque part entre ces deux positions extrêmes, alors on allumera la lumière de manière plus moins atténuée, suivant la position (en la pilotant en PWM, comme vous verrez !).
Donc, pour commencer, voici le montage à réaliser :
Et au niveau du code arduino, cela se traduit avec les lignes suivantes :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier: ads1115_mesure_simple.ino
Description: fichier test de mesure de tensions simples
Page projet : https://passionelectronique.fr/
Auteur: Jérôme TOMSKI
Créé le 21.12.2020
*/
#include "ADS1X15.h"
const byte pinLED1 = 5;
const byte pinLED2 = 6;
ADS1115 ADS(0x48); // ADS1115 physiquement défini à l'adresse 0x48, avec sa broche ADDR reliée à la masse
void setup() {
// On définit D5 et D6 en sortie, et on les mets à l'état bas
pinMode(pinLED1, OUTPUT);
pinMode(pinLED2, OUTPUT);
digitalWrite(pinLED1,LOW);
digitalWrite(pinLED2,LOW);
// ADS1115
Wire.begin();
ADS.begin(); // Initialisation du module ADS1115
ADS.setGain(0); // On prend le gain le plus bas (index 0), pour avoir la plus grande plage de mesure (6.144 volt)
ADS.setMode(1); // On indique à l'ADC qu'on fera des mesures à la demande, et non en continu (0 = CONTINUOUS, 1 = SINGLE)
ADS.setDataRate(7); // On spécifie la vitesse de mesure de tension qu'on souhaite, allant de 0 à 7 (7 étant le plus rapide, soit 860 échantillons par seconde)
ADS.readADC(0); // Et on fait une lecture à vide, pour envoyer tous ces paramètres
}
void loop() {
// Demande de mesure de tensions à l'ADC (résultats entre -32768 et +32767)
int16_t tension_A0 = ADS.readADC(0); // Mesure de tension de la broche A0, par rapport à la masse
int16_t tension_A1 = ADS.readADC(1); // Mesure de tension de la broche A1, par rapport à la masse
// Nota1 : ces valeurs seront en fait comprises entre 0 et +32767, car aucune tension négative ne peut être appliquée sur ces broches
// Nota2 : on peut convertir ces valeurs en Volts, si besoin, avec la commande "float tension_volts_A0 = ADS.toVoltage(tension_A0);"
// Conversion 15 bits -> 8 bits (utile pour la suite)
byte val0 = map(tension_A0, 0, 32767, 0, 255);
byte val1 = map(tension_A1, 0, 32767, 0, 255);
// Puis on ajuste le rapport cyclique de l'alimentation de chaque LED, afin de les faire briller plus ou moins, en fonction des tensions mesurées précédentes
analogWrite(pinLED1, val0); // PWM de rapport cyclique "val0" pour la LED1
analogWrite(pinLED2, val1); // PWM de rapport cyclique "val1" pour la LED1
// Nota : quelques exemples, pour mieux comprendre :
// - si "tension_A0" = 0, alors val0 = 0, d'où un rapport cyclique à 0% sur la LED1 (celle-ci sera donc éteint)
// - si "tension_A0" = 32767, alors val0 = 255, d'où un rapport cyclique à 100% sur la LED1 (celle-ci sera donc pleinement allumée)
// - si "tension_A0" est entre ces deux valeurs, alors le rapport cyclique sera fonction de celle-ci (et donc, l'éclairement de la LED aussi en fonction)
// Puis on boucle !
}
Comme vous le voyez, le code est au final assez simple ! J’en ai toutefois profité pour rajouter un maximum de commentaires, afin que la compréhension soit la plus facile possible. Mais dans tous les cas, au besoin, n’hésitez pas à poser vos questions, en zone commentaires !
Tutorial ADS1115 : code arduino pour mesure de tension différentielle
Ici, il s’agit de faire des mesures flottantes, donc sans que celles-ci ne soient reliées à la masse. Je vous propose le montage suivant, pour l’illustrer. Cela met en œuvre une simple pile (vous pouvez prendre une pile AA 1,5 volts, une piles lithium 18650 de 3.7 volts, ou ce que vous voulez, afin de faire vos essais !). La mesure de tension sera quant à elle affichée sur le moniteur série de l’interface Arduino, tout simplement.
Mais tout d’abord, voici le montage à réaliser :
Au niveau du code arduino de ce programme, voici ce qu’il contient :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier: ads1115_mesure_differentielle.ino
Description: fichier test de mesure de tensions différentielles
Page projet : https://passionelectronique.fr/
Auteur: Jérôme TOMSKI
Créé le 21.12.2020
*/
#include "ADS1X15.h"
ADS1115 ADS(0x48); // ADS1115 physiquement défini à l'adresse 0x48, avec sa broche ADDR reliée à la masse
void setup() {
// Initialisation de port série
Serial.begin(9600);
Serial.println("Lecture de tensions différentielles / ADS1115");
Serial.println("---------------------------------------------");
Serial.println("Mesure de différence de potentiel entre les entrées A0 et A1 de l'ADC");
Serial.println("Nota : ADC Range: +/- 6.144V (soit 1 bit = 0.1875 mV)");
Serial.println("");
// ADS1115
Wire.begin();
ADS.begin(); // Initialisation du module ADS1115
ADS.setGain(0); // On prend le gain le plus bas (index 0), pour avoir la plus grande plage de mesure (6.144 volt)
ADS.setMode(1); // On indique à l'ADC qu'on fera des mesures à la demande, et non en continu (0 = CONTINUOUS, 1 = SINGLE)
ADS.setDataRate(7); // On spécifie la vitesse de mesure de tension qu'on souhaite, allant de 0 à 7 (7 étant le plus rapide, soit 860 échantillons par seconde)
ADS.readADC(0); // Et on fait une lecture à vide, pour envoyer tous ces paramètres
}
void loop() {
// Mesure de la tension différentielle entre A0 et A1 (le résultat se situera entre -32768 et +32767, comme nous sommes sur 16 bits)
int16_t difference_potentiel_A0_A1 = ADS.readADC_Differential_0_1();
Serial.print("Lecture de l'ADC (A0-A1) : ");
Serial.println(difference_potentiel_A0_A1);
// Conversion de cette valeur en volts (le résultat sera fonction de la plage sélectionnée, fonction du gain ; ici, le résultat sera entre -6.144 et +6.144 volts)
float tension_volts_A0_A1 = ADS.toVoltage(difference_potentiel_A0_A1);
Serial.print("Tension différentielle = ");
Serial.print(tension_volts_A0_A1,3); // On limite l'affichage à 3 chiffres après la virgule
Serial.println(" volts");
// Puis on boucle, après une pause de 2 secondes !
Serial.println("");
delay(2000);
}
Et au niveau du moniteur série de votre IDE Arduino, vous devriez avoir quelque chose comme ce qui suit (là j’ai mesuré un accus li-ion 18650, que j’avais sous la main !) :
Module | Description | Lien |
---|---|---|
Module ADS1115 "tout équipé" (pour pilotage I²C facilité, via Arduino ou autre) |
Conclusion
Voilà ! Je pense que nous avons survolé toutes les fonctionnalités principales de l’ADS1115 ! Bien sûr, il y a bien des choses que j’ai laissé de côté, à l’image de la fonction comparateur. Mais comme le but premier de cet article était avant de tout de vous familiariser avec ce convertisseur analogique numérique, je préfère me limiter à l’essentiel, sans vous noyer d’infos techniques, ou trop pointues. J’espère d’ailleurs que vous aurez pu découvrir ou apprendre un maximum de choses ici, afin de pouvoir les intégrer à vos futurs projets !
J’en profite pour vous glisser des liens vers les principaux composants utilisés ici, dans le cadre de ce tutorial, si vous ne savez pas où les trouver :
- Carte Arduino Uno R3 (microcontrôleur ATmega328P)
- Module plaquette ADS1115 (convertisseur analogique numérique 16 bits, à 4 canaux)
À bientôt.
Jérôme.
À découvrir : l’ensemble des articles portant sur les modules Arduino
(*) Mis à jour le 03/08/2024
Bonjour,
Merci pour ce tutoriel très complet ! J’ai voulu refaire le montage pour une mesure de tension différentielle mais je n’arrive pas à obtenir des resultats… il m’affiche une valeur de -257 et donc une tension différentielle de -0.048 V peut importe que je mesure aux bornes d’une pile. Avez-vous une idée de ma source d’erreur ?
Merci d’avance
Bonjour Audrey !
Dans un cas comme le vôtre, je vérifie toujours mes branchements en premier. Car lorsqu’on mesure une tension quasi toujours identique, proche de 0 volt, et ce, quelque chose l’élément branché dessus, c’est qu’il y a fort à parier que :
– soit une entrée n’est pas raccordée correctement (un fil est peut-être branché jusqu’à côté de la bonne borne d’entrée)
– soit il y a un faux contact sur votre platine d’essai (ce qui arrive parfois, avec certaines breadboard) ; dans ce cas, il faut bouger ou déplacer les fils, pour voir l’incidence sur la tension mesurée
Une fois cette vérification faite, et s’il n’y a aucun changement, c’est du côté du code qu’il faudra ensuite chercher. Car peut-être une petite erreur s’est glissée à un endroit particulier, faisant apparaître une valeur erronée.
À voir !
Bon courage à vous 😉
Jérôme.
Bonjour Jérôme,
Je suis passionné d’électronique également et je trouve votre article bien construit, synthétique et pédagogique.
J’ai réalisé un montage avec 3 x ads1115 pour mesurer les tensions d’une batterie de 12 accumulateurs LifePo4 en série (application vélo électrique).
Merci pour votre partage.
Et bonne continuation
Merci beaucoup Pascal, pour ce retour !
Bonjour Jérôme,
Merci pour cet article très intéressant et bien construit ! Bravo pour le travail !
J’ai juste une petite question.
En fait, j’ai fait un code pour mesurer des tensions en utilisant l’ADS1115. J’ai réussi à obtenir de bons résultats avec un seul ADC. Ma question est de savoir comment faire lorsqu’on met plusieurs ADC en parallèle ? Par exemple 4 ADC pour mesurer 16 tensions en même temps ? Comment il faut s’y prendre dans le code ? Voilà ci-dessous mon code pour un seul ADC. J’utilise l’arduino uno.
Merci d’avance pour votre réponse
Bien cordialement
Sisco
Salut Sisco,
En fait, c’est tout simple ! Car il te suffit de déclarer 4 variables visant tes 4 modules ADS1115.
Dans le programme, voici ce que tu pourrais écrire :
et dans ton code, tu vises ADS1, ADS2, ADS3, ou ADS4, de la même manière que tu le faisais avec un seul ADS (mais au lieu de noter « ADS », tu note l’ADS de ton choix, et tu les appelles les uns à la suite des autres).
Nota : attention à une chose. Comme tu l’auras compris, on peut faire jusqu’à 16 mesures de tensions, avec 4 modules ADS1115. Par contre, dans ton code à toi, tu fais une lecture de tension différentielle, et non des mesures de tensions « simples ». Tu n’utilises donc pas 1 entrée de mesure, mais 2 à la fois (mode différentiel). Si tu procèdes ainsi, tu ne pourras lire que 8 tensions différentielles au maximum, avec tes 4 modules ADS1115, et non 16.
Voilà ! Espérant que ça répond bien à ta question 😉
Jérôme.
Je te remercie pour ta réponse !
Je vais essayer de faire comme tu l’as dit, en espérant que ça va marcher.
Salutations !
Sisco
Salut Jérôme,
J’alimente mes ADS1115 avec du 5V et je dois mesurer des tensions pouvant aller jusqu’à 5.20V. Dans votre article, vous avez indiqué qu’on peut mesurer des tensions jusqu’à 5.30V. Pouvez-vous me dire dans quelle partie de la datasheet se trouve cette information s’il vous plaît? Ou bien comment vous avez eu cette information ?
Je vous remercie d’avance pour votre réponse.
Sisco
Salut !
Tu trouveras ça en page 6 du datasheet (https://www.ti.com/lit/ds/symlink/ads1115.pdf), dans la section « Absolute Maximum Ratings ».
Dans ce bloc, tu pourras lire sur la ligne « Analog input voltage » (soit la tension applicable sur les entrées de mesures analogiques), les valeurs min (GND-0.3V) et max (VDD+0.3V).
Par contre, garde bien à l’esprit que ce sont des valeurs extrêmes ET ponctuelles, sous peine d’endommager la puce à la longue (les valeurs recommandées étant une tension allant de GND à VDD).
Voilà !
Jérôme.
D’accord je vois mieux, merci !
Pour éviter tout endommagement, on peut avoir recourt à un pont diviseur de tension !
J’ai une dernière question concernant l’arduino : est ce que vous savez comment réaliser plusieurs mesures de la même tension, faire une moyenne, un RMS et un pic to pic, puis sauvegarder ces trois valeurs dans un fichier Excel par exemple ?
Il paraît qu’il est possible de le faire avec une fonction mais je sais pas trop comment cela se passe…
Merci pour le temps que vous m’accordez !
Sisco
Bonsoir Sisco !
Voilà, ta solution de pont diviseur est excellente ! Par contre, mesure bien la valeur de tes résistances à l’ohmmètre, afin d’avoir leur valeur « réelle » (et non théorique). Ensuite, fait tes calculs mathématiques sous Arduino, en fonction de ces valeurs réelles. Sinon, tes résultats risquent être quelque peu faussés.
Du reste, je n’ai malheureusement pas de réponse à te donner, concernant une fonction permettant de faire tous ces calculs. Perso, je fais tout ça « en dur », dans le code, au besoin ! Par exemple, si je veux faire la moyenne RMS de 3 valeurs notées Vmesure1, Vmesure2, et Vmesure3, j’écris une ligne de code du style :
Espérant que cela peut t’aider, et désolé de ne pouvoir t’en dire plus à ce sujet.
Jérôme.
Bonjour Jérôme,
J’ai fait un test en suivant votre méthode concernant la mesure différentielle mais le résultat me semble pas correct. La précision est trop faible.
En effet, j’ai testé mon code en mesurant la différence de tension entre le 5V de l’arduino (relié au pin A0 de l’ADS1115) et le 3.3V (relié au pin A3 de l’ADS1115). J’ai obtenu une différence de tension de 1.77V au lieu de 1.7V. La précision est donc de +70mV, ce qui me semble trop importante ! La partie configuration de mon code est donnée ci-dessous. Avez-vous une idée d’où peut venir le problème ? J’ai vu qu’avec un gain de 0 on est sensé obtenir une précision de 0.1875 mV (pour 1 bit). Je ne sais c’est quoi le problème chez moi…
Je vous remercie d’avance pour votre réponse !
Salut Sisco,
En fait, il y a plein d’explications possibles. Mais la plus évidente, selon moi, est le fait que les tensions d’alimentation ne sont pas exactement égales à +5V ou +3,3V, malgré ce que l’on pourrait croire. En fait, les régulateurs de tensions embarqués ont eux aussi leurs propres tolérances, en fonction de leur qualité de conception, et de fabrication. Et leur précision est également fonction de la température ambiante, de la charge appliquée, des interférences, … et de bien d’autres choses encore.
Du coup, le +5V ne fera jamais précisément 5 volts en permanence, et idem pour le +3V3. Ce n’est donc pas étonnant de constater un tel écart entre ces deux tensions, ni même le fait de voir cet écart « bouger » dans le temps (car les paramètres évoluent eux aussi en permanence, ne serait-ce qu’avec la température ambiante).
Au final, dans ton cas, je pense que l’écart ne vient pas de la marge d’erreur de l’ADS1115 (même si elle est forcément présente, aussi infime soit-elle), mais plutôt des tensions d’alimentations, qui ne doivent pas être exactement à leur valeur nominale. Donc pas de soucis, d’après moi, car tes mesures sont parfaitement plausibles 😉
Voilà !
Jérôme.
Salut Jérôme !
Y a-t-il pas un soucis dans votre tableau au niveau de la valeur de gain sélectionné ? Parce que moi je vois dans la datasheet (page 28/table 8) que les valeurs du gain peuvent être 0, 1, 2, 3, 4, 5, 6 et 7 mais non 0, 1, 2, 4, 8 et 16 comme vous l’avez fait. A moins qu’il y a quelque chose qui m’échappe.
Salutations,
Sisco
Salut Sisco,
Non, il n’y a pas d’erreur ! En fait, il ne faut pas confondre les bits du registre de sélection du gain, et les valeurs de gain correspondant. Car oui, ce registre à 3 bits va bien de 0 à 7, mais les valeurs correspondantes vont quant à elles de ±6.144 V à ±0.256 V (le fameux FSR du tableau 8 page 28). Et si tu fais le rapport entre 6.144 et 0.256, tu verras que le coefficient de multiplication est de 24, et non de 7. Et ces 24 correspondent bien au gain max (16) divisé par le gain le plus faible (2/3), à savoir : 16 / (2/3), qui font bien un rapport de 24 !
Par ailleurs (d’où peut-être la confusion), les valeurs 0/1/2/4/8/16 sont des valeurs « imposées » par la librairie Arduino utilisée, concernant le PGA. En fait, en arrière plan, ces valeurs correspondent bien à une valeur 0,1,2,3,4,5 pour le registre de sélection du gain (6 et 7 étant identiques à 5), et à un gain réel effectif de 2/3,1,2,4,8,16.
La petite erreur que tu as commis est, en fait, de mélanger « contenant » et « contenu », si je puis dire (ou plus exactement la valeur donnée dans une fonction Arduino, et imposée par celui qui a créé cette librairie, avec sa valeur réellement correspondante). En tout cas, je vois que tu bosses bien, et que tu creuses les choses à fond, et ça, c’est super !
Voili voilou 😉
Jérôme.
C’est très bien, merci beaucoup pour cette explication bien détaillée !
Juste pour savoir, ces valeurs de gain réel effectif (2/3,1,2,4,8,16) sont-elles indiquées dans la datasheet ? Sinon comment les déterminer ?
Re,
Non, ces gains n’apparaissent pas de manière directe et claire, dans le datasheet du fabricant.
Par contre, ceux-ci apparaissent dans la librairie Arduino que j’ai utilisé. Ces gains ne sont donc juste qu’une manière de présenter les choses.
Du reste, de manière indirecte, on peut facilement vérifier ces propos, en prenant comme référentiel la seconde ligne de la Table 3 de la page 17 (celle à ±4.096 V). Car si on fait le rapport de chaque tension par rapport à 4,096 volts, alors on obtient :
– 4.096 / 6,144 = 2/3
– 4.096 / 4.096 = 1
– 4.096 / 2.048 = 2
– 4.096 / 1.024 = 4
– 4.096 / 0.512 = 8
– 4.096 / 0.256 = 16
D’où les gains 2/3,1,2,4,8,16 qui apparaissent dans la bibliothèque arduino ! Tout simplement 😉
a+
Jérôme.
Bonjour,
Merci pour votre travail !
Je viens de tester ce composant dans le cadre d’une application qui demande des mesures fréquentes (tous les 10ms) et RAPIDES, car pendant les relevés le process mesuré est « débranché ». Les tensions à mesurer sont faibles. Aussi la possibilité de leur appliquer un gain aurait été très appréciée.
Mais la déception est grande aussi, rapport à sa vitesse d’échantillonnage. Car pas possible de retrouver les 1.16 millisecondes annoncées au taux DR7 : de mon côté je relève 2,7ms.
Or avec un Nano, dont les lectures analogiques ne sont pas réputées pour leur rapidité, j’obtiens un temps de 112 MICROsecondes par lecture. On peut même améliorer grandement cette valeur : https://forum.arduino.cc/t/faster-analog-read/6604/6. Au maximum exploitable (prescaler sur 16), je relève un temps de 15µs.
Un ADS1115 trouve certainement son intérêt dans des cas précis, mais attention à la limite que sa lenteur posera.
(A noter aussi qu’il est très cher, quand pour 3,5 euros on trouve un ESP32 à 240MHz qui écrase le Nano en performances et offre 14 pins analogiques et des fonctions avancées d’échantillonnage implantées nativement !)
C’est entre passionnés que je me suis autorisé ce complément, ça n’est nullement une critique de votre analyse, très complète et très bien exposée.
Cordialement
Philippe
Bonjour Simon !
Merci infiniment pour ce retour précis, et très intéressant ! Car cela permet de compléter nos connaissances mutuelles, et intéressera certainement pas mal de personnes, qui cherchent à faire des mesures efficaces et rapides (que ce soit avec un Arduino ou autre !). Donc merci à toi, encore une fois !
Jérôme.
Hello,
Très bon article !!!
Je mets en œuvre ce CAN en ce moment en utilisant la pin alert comme interruption en mode automatique (indiquant la dispo d’une conversion) et j’ai aussi constaté une lenteur dans les conversions. En creusant un peu je constate que dans la librairie il est appliqué un délai qui me semble totalement inutile. Ce délai provient de la constante « ADS1115_CONVERSION_DELAY », et en mettant 0 à la place de 8 tout revient dans l’ordre.
D’ailleurs le dev indique sur cette ligne :
Merci encore pour toutes ces infos !
Salut !
Merci à toi également, pour ce retour ! Ça sera bien utile pour ceux qui rencontreraient des problèmes de lenteur de conversion.
Encore merci.
Jérôme.
Bonjour Jérôme
D’abord un grand merci et félicitations pour ton site.
Une petite question : peut-on sélectionner le gain juste avant la mesure sur une entrée ? Je dois lire sur deux entrées, l’une sur tension maxi de 5 volts issue d’un pont diviseur et l’autre sur un shunt de 100mV.
→ sur la première mesure je choisirai un gain de 0
→ sur la deuxième mesure un gain de 16
Je n’ai pas encore reçu mon ADS1115 pour faire mes essais.
Bonsoir Jean-Paul !
Sauf erreur de ma part, oui tu peux, sans aucun soucis.
En fait, pour cela, il suffit d’appeler la commande « setGain » avant chaque « readAdc », pour ajuster la valeur du gain avant chaque lecture.
Par contre, il faudra bien veiller à lui envoyer une tension qui soit dans les limites de ce qu’il peut lire, en fonction du gain sélectionné !
Bonne soirée à toi 😉
Jérôme.
Merci pour ce bon tuto.
Pour l’améliorer il est bien d’enlever « Comme vu précédemment ».
À quoi sert mode continu ?
Salut Polo !
C’est bon, c’est corrigé. Merci à toi 😉
Concernant le mode continu, l’ADS1115 effectue des mesures répétées perpétuellement, dans le temps. Cela permet de ne pas avoir interroger la puce « sans arrêt », et d’en attendre le résultat. En effet, dans ce mode, l’ADS1115 envoie une impulsion sur sa broche ALRT, à chaque fois qu’une mesure est prête (préalablement lue, donc). Ainsi, on peut capturer cette alerte, et pourquoi pas, déclencher une interruption matérielle, à chaque fois qu’une mesure est prête à lire.
Maintenant, cela a des avantages et des inconvénients, suivant ce que l’on veut faire, son programme arduino, et la librairie utilisée. Mais perso, j’ai préféré me limiter à des choses simples, c’est pourquoi j’ai mis l’accent sur le mode « single shot » (mesures ponctuelles, donc), dans ce tuto.
Voilà !
Bonne journée à toi.
Jérôme.
Excellent article Jérôme, très bien détaillé.
Bravo, on apprend beaucoup de choses. Tuto très clair, très pédagogique (et là c’est un compliment) très bien construit.
Merci
Merci, merci !!
Il ne faut pas confondre résolution et précision, 2 notions qui sont sans rapport. L’ADS1115 a une résolution de 16 bits mais sa précision est bien inférieure. La data sheet de ce composant indique par exemple une incertitude maximum de 0,15% rien que sur le gain programmable dont est doté ce composant. Les informations très marketing du data sheet ne permettent d’ailleurs pas à un bricoleur de calculer la précision finale d’une mesure. Un simple Arduino UNO ou NANO avec son CAN 10 bit qui utiliserait une référence de tension externe de précision (par exemple une VREF-01 0,01% elle-même calibrée sur multimètre Agilent de labo) donnera une bien meilleure mesure que ce CAN 16 bit qui affichent plein de chiffres. Trop de gens oublient que la calibration est une étape incontournable en métrologie.
Salut Michel !
Merci infiniment pour ton retour, très constructif. J’en ai d’ailleurs profité pour corriger certaines erreurs que j’avais fait ici et là, dans cet article.
Encore merci à toi 😉
Jérôme.
Ce tuto est fort bien réalisé, et je crois qu’il s’applique directement à mon besoin.
En effet, je souhaite suivre dans le temps l’intensité d’un courant circulant dans une boucle incluant une batterie 12V, et un dispositif pouvant être successivement consommateur ou producteur. J’ai rajouté dans le circuit un troisième élément, sous forme d’un shunt qui délivre à ses bornes une différence de potentiel allant de -50mV à +50mV, en fonction de l’intensité du courant et de son sens, qui pourront alors être calculés.
J’ai le sentiment que le montage n°2 du chapitre 5 devrait convenir, en remplaçant la pile par le shunt.
Là où j’ai un doute, c’est au niveau de l’alimentation de l’arduino si je prévois un convertisseur 12V → 5,5V, le négatif batterie va être relié à la masse du montage arduino+ads1115, est ce que cela pourrait poser un problème ? Sinon, je peux toujours alimenter le montage indépendamment de la batterie.
Qu’en pensez-vous?
Jean
Salut Jean !
Normalement, tu ne devrais avoir aucun soucis à relier le « – » de ta batterie sur ton montage Arduino + Ads1115. Car l’ADS 1115 effectue une mesure différentielle, et ce, « indépendamment » de son alimentation.
Voilà ! Bon courage à toi 😉
Jérôme.
Merci Jérôme pour ton retour, qui me rassure sur le montage envisagé.
Jean
Bonjour.
Merci pour ce tuto qui me sert de référence … depuis un moment déjà …
En matière de définition du « bon gain », je m’interroge dans le cas d’une mesure différentielle : je prends pour hypothèse un shunt 100mV de mesure de courant alimenté en amont par un +bat à 12V. Le -bat sert de masse au montage électronique.
Mon objectif : mesurer la tension absolue « +bat » et le courant dans le circuit d’utilisation via la tension différentielle relevée sur le shunt.
Je relie la borne amont du shunt à A0 et la borne aval à A1 … sans omettre (évidemment) 2 ponts diviseurs (identiques) de manière que la tension absolue de l’entrée amont soit de 4V. Pour la mesure de la tension absolue sur A0 … pas de difficulté, je prends un gain 1 … (étendue de mesure + ou – 4,096V). Pour la tension différentielle par contre quel gain ? Faut-il que je garde obligatoirement un gain 1 puisque, en valeurs absolues, les tensions en A0 et A1 sont à environ 4V, ou puis-je prendre un gain 16 (étendue de mesure + ou – 256mV) puisque la tension différentielle maximum est de 100mV ?
Merci.
Salut Pascal !
C’est une excellent question que voilà 😉
Mais en fait, je pense que la réponse est déjà dans la question que tu te poses ; et que tout se joue au niveau logiciel. En effet, tu pourrais très bien lire une tension, puis l’autre, en sélectionnant le gain correspondant juste avant. Du coup, au niveau logiciel, tu te retrouverais par exemple avec un script suivant cela :
– fixer le gain à 1
– lire la tension A0 (ton +Vbatt abaissé, donc)
– fixer le gain à 16
– lire la tension différentielle A0-A1
– et reboucler
Tu vois ?
Enfin … en vérifiant que je ne te dise pas de bêtise, ou que quelque chose ne m’échappe !
Bon courage à toi,
Jérôme.
Avec la librairie « RobTillaart / ADS1X15 » version 0.4.5
Il faut mettre un Wire.begin(); avant le ADS.begin();
pour initialiser la communication I2C en tant que controleur.
Entendu, merci !
Afin de filtrer au maximum les messages de type "spam" ou "inappropriés", chaque commentaire est soumis à modération, et validé manuellement. Du coup, il se peut que certains commentaires ne soient pas publiés, ou sinon, avec un peu de retard. Par ailleurs, j'ai malheureusement plus de messages à traiter que de temps pour y répondre ; c'est pourquoi je ne pourrais pas répondre à tout le monde. Désolé …