ADS1115 et ASC712

Hello tous

Bon premièrement je tiens un préciser que ne suis pas du tout spécialiste en électronique.

Je tente de réaliser un montage avec un ADS1115 et un ASC712 en entrée A0 me permettant de définir assez précisément ce qui est consommé sur un courant alternatif EDF (j'imagine que c'est un cas d'école)

PARTIE 1 - ADS
Concernant l'ADS on a donc une résolution 15bits et j'ai lu ici ou là qu'il utilisait une tension de référence de 6.144 V..

Question 1 : Un arduino fonctionne en 5V > doit-on tenir compte de ça en créant une transformation quelconque... Je ne suis pas expert des datasheet mais je n'ai rien trouvé par rapport à ça... peut être ais-je mal interprété?

Question 2 : Si non quel est le principe : il y a-t-il un dispositif permettant de remonter cette tension au niveau de l'ADS ou est-ce seulement une échelle de valeur?

(En cherchant sur internet j'ai trouvé des exemple en courant continue sans ADS où il semble que la tension de l'arduino VCC est utilisée pour réajuster l'echelle mais ça n'est peut être pas la même chose avec l'ADS)

PARTIE 2 - ASC
Concrètement voilà ce que je constate...
Sur l'ADS en échantillonnant à 100 mesures toute les ms théoriquement je devrais avoir 5 périodes (5 valeur Max et 5 valeur min) or chacune des 100 mesures se retrouvent être des crêtes :

Image

Question 3 : Auriez-vous une explication?

Je me suis dit que sans module RTC le delayMicroseconde(1000) ou delay(1) ne fonctionnait peut-etre pas et qu'on était sur beaucoup plus de période en réalité mais ça me parait étrange...

Quoi qu'il en soit j'ai pris le MIN et MAX de l'ensemble valeur pour trouver le zero et l'amplitude moyenne (en absolu grace au zero)..
Ensuite j'ai divisé par Racinecarré de 2 pour obtenir une valeur efficace...
Détail :
MAX : 12778
MIN : 12395
Amplitude moyenne : 191.5 (en absolue)
Valeur efficace : 135.41094859722384

La valeur efficace mesurée correspond à une ampoule censée consommer 42W :
Donc 0.02538955286197947 Volt (en me basant sur l’échelle 6.144V)
Soit 0.13724082628097012 Ampère (ACS sensible à 185mv / Ampère)
Soit 30.192981781813426 Watt (X 220V)

Même si on a des tolérances ici et là cela me parait assez imprécis... (passer sur la VCC mesurée par l'arduino augmente encore plus l’écart)

Question 4 : L'ASC aurait-il un problème également en étant alimenté en dessous de 5V (vcc à ~4.872V par exemple)?

Si je débranche tout j'obtiens des choses de l'ordre de 1.7343227133156538W
Si mes calculs sont bon on devrait être précis à

Il doit forcément avoir une erreur quelque part pouvez-vous me donner une piste?

Bonjour

Concernant l'ADS on a donc une résolution 15bits et j'ai lu ici ou là qu'il utilisait une tension de référence de 6.144 V..

Le fabricant n'est pas très loquace concernant la valeur de la tension de référence interne -(probablement 2,048V) et le gain (en fait le coefficient d'amplification du PGA)

Par contre il donne plusieurs valeurs possibles pour la 'pleine échelle' selon la configuration du PGA (Coefficient d' amplification programmable). Cela suffit, le FSR (pleine échelle) est la résultante de la tension de réference et du 'gain'.
Capture d’écran du 2018-11-11 12-49-26.png

+/- 6,144V est l'une des valeurs possibles pour la 'pleine échelle' mais il ne faudra pas l'atteindre car la tension d'entrée ne doit dépasser la tension d'alimentation de plus 0,3V ni descendre plus de 0,3V en dessous de la masse.
Cette valeur 6,144V est donc une valeur permettant de définir, dans l'un des cas de configuration du PGA, le coefficient de conversion A/N. (sans doute ce à quoi tu penses en ecrivant 'échelle de valeur')

Voici les 8 valeurs possibles de la pleine échelle

(En cherchant sur internet j'ai trouvé des exemple en courant continue sans ADS où il semble que la tension de l'arduino VCC est utilisée pour réajuster l'echelle mais ça n'est peut être pas la même chose avec l'ADS)

Tu dois confondre avec la mesure analogique (ACS712). En effet j'ai déjà lu des codes qui corrigent la valeur lue en fonction de VCC : ACS712/ACS712.ino at master · MajicDesigns/ACS712 · GitHub

Mais l'ADS1115 est un composant I2C.

@+

Merci à vous pour ces débuts d'éclaircissement

Alors oui quand je parle d'échelle de valeur je veux parler du coefficient de conversion ADS 0 à 6.144V
Soit 1 vaut 0.1875mV
Si je suis bien je peux donc rester sur ce coefficient même si l'ADS est alimenté par l'arduino à 4.9V

Après pour la prise en compte du VCC c'était un peu l'interrogation que j'avais..
Si on trouve des codes qui prennent en compte pour réevaluer le coefficient de conversion...
Cela semble vouloir indiquer que le VCC joue sur le coefficient pour l'arduino..

Par contre je ne comprend pas bien le rapport avec le protocol de communication I2C.. Peut être que je ne comprend pas tout à fait..

Je part du principe qu'il faut que je trouve en A0 la tension en mV (fournie par l'ASC)
Une fois que j'ai cette tension il faut que je convertisse cette tension en intensité (l'ASC il a une précision de 1A pour 185mv).
Si dans les codes sur internet on trouve des modification du coefficient 5V de l'ASC par la VCC il va surement falloir le prendre en compte aussi à l'inverse de ce qui semble être fait au niveau de l'ADS

L'autre truc que je vois sur l'implémentation que tu m'as envoyé c'est qu'ils utilisent la fonction millis... je vais essayer cette implémentation peut être que ça résoudra mes problèmes de crêtes..

Je me suis dit que sans module RTC le delayMicroseconde(1000) ou delay(1) ne fonctionnait peut-etre pas et qu'on était sur beaucoup plus de période en réalité mais ça me parait étrange...

Certainement pas. delay() est basé sur l'horloge processeur, plus ou moins précise, mais tu peux essayer avec un delay(30000) et un chrono pour vérifier les 30s.

Pour le reste sans code, difficile de dire quoi que ce soit.

L'ACS712 n'est pas un instrument de mesure. Il envoie une tension analogique en sortie, qui vaut VCC / 2 au repos.
Pour un écart de mesure analogique faible en entrée de l'ARDUINO, le calcul du courant te donnera des écarts importants.
L'ACS712 est bien pour mesurer des courants proches de la pleine échelle, ou vérifier la présence ou l'absence d'un courant, pas grand chose de plus.

Cela semble vouloir indiquer que le VCC joue sur le coefficient pour l'arduino..

Bien évidemment, le 5V est sa tension de référence ADC par défaut.
Il est possible de mesurer le 5V grâce à une astuce:
On mesurer la tension de la ref interne 1.1V et on en déduit la valeur du 5V.

Si dans les codes sur internet on trouve des modification du coefficient 5V de l'ASC par la VCC il va surement falloir le prendre en compte aussi à l'inverse de ce qui semble être fait au niveau de l'ADS

L'ADS1115 possède sa propre référence interne, bien plus précise que le 5V de l'ARDUINO.
Tu lui demande une valeur de tension par le bus I2C et il te renvoie la réponse par le même bus.

Tu veux mesurer la tension de sortie de l'ACS712 avec l'ADS115 ou la tension secteur ?
Dans les deux cas, sa rapidité n'est pas fameuse : 860 samples/s.

Sur l'ADS en échantillonnant à 100 mesures toute les ms

Là tu rêves. Pas possible avec 860 SPS.

@+

Ah oui ok je n'avais pas pensé au taux d'échantillonnage lié a l' i2C..
Cependant si je prends cette contrainte j'ai toujours quelque chose de bizarre c'est qu'au pire des cas dans la boucle j'attends 1ms et la lecture prendrait max 2ms du coup? je suis a une mesure toute les 3ms je ne devrai pas me retrouver avec ce type de sortie sur 50Hz..

Pour le programme c'est simple je lis juste sur A0 de l'ads avec un délai.. je balance ensuite toutes les valeurs brutes que j'exploite hors Arduino

Pour revenir a l'ACS ok pour le décalage lié au VCC mais la question c'est est ce que ça joue sur la sensibilité..?

Tu n'as pas répondu :
Que mesures-tu sur l'entrée A0 de l'ADS1115 ? la tension de sortie de l'ACS712 ?

Pour revenir a l'ACS ok pour le décalage lié au VCC mais la question c'est est ce que ça joue sur la sensibilité..?

Cela permet de corriger la mesure de l'ADC de l'ARDUINO, car le 5V lui sert de référence. Si le 5V n'est pas précis ou stable, la mesure s'en ressent.

@+

Oui tout a fait sur A0 j'ai mis loutput de l'ASC j'aurai pas du?
La mesure c'est sur EDF et en haut j'explique comment je redresse pour trouver une tension efficace..
Concrètement le zéro a 2.5V ou 2.4V en fct du VCC ne devrait pas véritablement jouer si la sensibilité reste la même non? (Vu que je redetermine le zéro grâce a l'amplitude des valeurs numériques..)

Un ADS1115 sera toujours plus précis que l'ADC de l'ARDUINO.

Mais l'ADC de l'ARDUINO sera sans doute 10 fois plus rapide.

Concrètement le zéro a 2.5V ou 2.4V en fct du VCC ne devrait pas véritablement jouer si la sensibilité reste la même non? (Vu que je redetermine le zéro grâce a l'amplitude des valeurs numériques..)

Le fait de connaître la tension de référence VCC est un gage de précision, mais je doute que l'ACS712 soit suffisamment précis pour que cela joue.

Le souvenir que j'en ai pour avoir essayé un module 5A, est que les 185mV / ampère s’avéraient plus que douteux. Pour obtenir une mesure fiable comparativement à mon multimètre, j'ai du modifier cette valeur pour finir à 135mV / ampère.
De plus j'ai été obligé de faire une moyenne sur 100 mesures pour obtenir un résultat précis à quelques %.

@+

Merci de tes retours d'expérience Hbachetti
Concrètement c'est ce que je fais.. 100 mesures pour avoir plusieurs périodes.
Je vois pas d'autre moyen (simple) de mesurer une puissance que lasc.. j'ai lu pas mal d'articles où le gens indiquait trouver assez précisément l'intensité c'est pour ça que je suis parti sur ça mais si il y a une autre solution simple ça serait génial de la connaître :slight_smile:

Après au delà de la précision de l'ASC les phénomènes observés ici semblent incohérents malgré tout.. la courbe relevée sur l'ads est très bizarre.. l'absence d'appareil faisant apparaître un 1,5W peut être incriminée a l'ASC mais quand même c'est surprenant..
J'ai tenté avec un 20A et j'ai les mêmes résultats en passant a 100ms de sensibilité

Arff..

Essaie avec l'ARDUINO seul, sans l'ADS1115.
analogRead() sera certainement plus rapide.

Conserve ton travail tel qu'il est, et pars sur un deuxième sketch.
Tu pourras facilement comparer.

@+

J'avais réussi a le faire sans l'ads le problème étant que la précision a 3/4w en résolution absolue a 512 n'est pas envisageable..
Je me disais qu'avec une résolution CAN supérieure j'arriverai a descendre en dessous de 1W.. dans les fait j'ai pas l'impression que ça soit possible avec lasc même en calibrant..
Si on prend un cas d'utilisation simple il y a pas mal d'appareil qui consomme quelques watt donc sans précision pas de résultats :frowning:

Si on prend un cas d'utilisation simple il y a pas mal d'appareil qui consomme quelques watt donc sans précision pas de résultats :frowning:

J'ai bien peur que l'ACS712 ne soit pas la solution. 1W -> 4mA : ils seront noyés dans le bruit.

Tout dépend de ce que tu cherches à faire.

Personnellement j'utilise les TELEINFOs du compteur. OK pour le relevé d'énergie, pas très bon pour un relevé de courant et puissance instantanés.

Si tu cherches à faire des mesures sur une partie de ton circuit, TELEINFO ne convient évidemment pas.

Peut-être PZEM-004T ? Mais ils ne donnent pas d'infos à part que le module mesure de 0 à 100A.

On en parle ICI :
https://easydomoticz.com/forum/viewtopic.php?f=20&t=4780
https://easydomoticz.com/forum/viewtopic.php?t=4687

Le problème est qu'à part afficher quelques courbes dans un navigateur, il n'y a aucune info. Personne n'a pensé à comparer avec un ampèremètre, ou mieux : un wattmètre.

Pourquoi cherchez-tu une telle précision ?

Ah je vais me poser sur cette solution dont tu me parles meme je n'abandonne pas ma quête de compréhension sur ce que j'ai obtenu..

Le but est très simple je cherche juste à connaître l'état de consommation de différentes ligne électrique. Si j'ai des lignes avec des ampoules led derriere il me faut un peu de précision et une ligne sans rien de brancher a 1,5W n'est pas possible

Je regarde ce que tu m'expose rapidement merci

Un code que j'ai piqué ICI : Speeding up the ADC on an Arduino ATMega 328P – Please note, free wordpress.com sites do not allow the less than or greater than signs to be put in code. This will substantially change the code shown here.

ADC en free running mode, avec clock = 500KHz au lieu de 125KHz

Légèrement modifié pour afficher les résultats :

#include "wiring_private.h"

#define TEST  10000L

uint32_t sensorValue;

void testDefaultADC(int pin)
{
  uint32_t start = millis();
  for (int x = 0 ; x < TEST ; x++) {
    sensorValue += analogRead(pin);
  }
  uint32_t elapsed = millis() - start;
  Serial.print("ADC value ");
  Serial.println(sensorValue / TEST);
  Serial.print("elapsed time ");
  Serial.print(elapsed);
  Serial.println(" ms");
  Serial.print("samples ");
  Serial.println(TEST);
  Serial.print("ADC speed: ");
  Serial.print(TEST * 1000L / elapsed);
  Serial.println(" SPS");
}

void startFreeRunningADC(uint8_t pin)
{
  ADMUX = (1 << REFS0) | ((pin - 14) & 0x07); //select AVCC as reference and set MUX to pin
  ADCSRB = 0; //set free running mode
  ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADPS2) | (1 << ADPS0); //set adc clock to 500Khz, enable, free running mode
  //ADCSRA=(1<<ADEN)|(1<< ADATE)|(1<<ADPS2)|(1<<ADPS1); //set adc clock to 250Khz, enable, free running mode
  sbi(ADCSRA, ADSC); //start the ADC
}

inline uint8_t sampleDone()
{
  // ADIF is set when the conversion finishes
  return bit_is_set(ADCSRA, ADIF);
}

inline uint16_t getSampleResult()
{
  uint8_t low, high;
  low = ADCL; //make sure to read L value first
  high = ADCH;
  sbi(ADCSRA, ADIF); //clear conversion complete flag
  return (high << 8) | low;
}

#define ADCport A0

void setup()
{
  Serial.begin(115200);
  testDefaultADC(ADCport);
  startFreeRunningADC(ADCport); //free running mode, only needs to start once.
}

#define ELAPSE    1000L

uint32_t start;
uint32_t count;

void loop()
{
  if (start == 0) {
    start = millis();
    sensorValue = 0;
  }
  while (!sampleDone());
  sensorValue += getSampleResult();
  count++;
  if (millis() - start >= ELAPSE) {
    Serial.print("ADC value ");
    Serial.println(sensorValue / count);
    Serial.print("elapsed time ");
    Serial.print(ELAPSE);
    Serial.println(" ms");
    Serial.print("samples ");
    Serial.println(count);
    Serial.print("ADC speed: ");
    Serial.print(count * 1000L / ELAPSE);
    Serial.println(" SPS");
    while(1);
  }
}

Dans testDefaultADC j'affiche le nombre de SPS, sans toucher à l'ADC.
Ensuite j'affiche le nombre de SPS avec le code en question :

ADC value 510
elapsed time 1119 ms
samples 10000
ADC speed: 8936 SPS
ADC value 510
elapsed time 1000 ms
samples 38470
ADC speed: 38470 SPS

1 : l'ADC de l'ARDUINO (10 bits) est plus rapide qu'un ADS1115 (16 bits). Normal.
2 : On peut le booster par 4

Plus d'échantillons -> plus de chances de choper le haut de la sinusoïde.

Attention, bien comprendre que tant que sampleDone() ne retourne pas OK, la mesure n'est pas prête. On attend. Mais on peut aussi faire autre chose en attendant.

@+

Yes génial je vais tester ce que tu viens de m'envoyer!

Alors en parallèle j'étais parti sur un truc un peu similaire avec un temps limité à 1 seconde et aucun délai pour connaitre ma vitesse d’échantillonnage :

for (uint32_t timeStart = millis(); millis() - timeStart < timeSampling; )
{
      int16_t adc0 = ads.readADC_SingleEnded(0);
}

Ce que j'ai observé c'est qu'on est à 25/26 lectures soit 35/38ms... Du coup 1 période et quelque ce qui explique le phénomène de l'image que j'ai mis... Même si c'est chiant c'est déjà cool de comprendre :slight_smile:
On est bien loin de 860 samples par secondes :S

readADC_SingleEnded() sert à lire une entrée parmi les quatre.
readADC_Differential_0_1() et readADC_Differential_2_3() servent à lire en différentiel.
La vitesse sera la même.

@+

On est bien loin de 860 samples par secondes

Il faudrait connaître la procédure utilisée par TI pour atteindre cette valeur.

Certainement pas en 'single shot' (lecture unique rythmée par le microcontrolleur)) mais en continu avec un ADS1115 configuré en ce sens et alertant le micro par sa sortie ALERT/RDY dès que la donnée est disponible..... interruption.... récupération de la valeur...

Içi, en fin de page un exemple d'acquisition en continu, déclenchée par l'ADS avec interruption du micro.
Test sous µPython sur ESP8266 avec la valeur de 252 échantillons par seconde.

De toutes façons un convertisseur A/N Sigma Delta reste relativement lent par rapport aux autres méthodes, il permet par contre de faire du 16 bits de manière économique.

Par contre on est bien clair sur le fait que mesurer le courant permettra d'avoir une bonne idée de la consommation sur une charge résistive uniquement ?
Je ne sais pas si une ampoule LED est strictement résistive par exemple ... à voir.

Bonne continuation.

Encore merci pour vos contributions!

Alors comme je le disais je ne suis pas électronicien alors pour moi c'est un peu du chinois le côté résistif d'une led ou pas..?

J'ai modifié mon code en utilisant la méthode que tu m'as exposée qui demande X mesures et non un nombre max pour un délai..
Là je suis passé à 100 lectures en 920ms..
J'en conclu que la méthode millis évaluée à chaque boucle consomme 20ms (énorme!).. Pour le coup j'ai donc des demie période et on est même au delà des 860 lectures théoriques.. (aucune n'est identique)
Le graphique de sortie semble tout à fait cohérent avec le 50 Hz :slight_smile:

Au final j'ai donc un soucis sur le calcul de conversion unité ADS <> mv (asc) <> amp puis amp X tension EDF.
Ca me parait décalé mais je vais acheter un oscilloscope pour savoir exactement de qui de quoi je pense que ça sera un bon début pour connaitre la vérité..

Enfin quoi qu'il en soit j'ai toujours l'oscillation à 10 unités (sur 15bits) lorsque je n'ai rien de connecté.
Ca n'est pas grand chose sur 15 bits c'est sûr mais ramené à la sensibilité du capteur ASC on arrive tout de suite à 15ma ce qui correspond à 3W au final..
Quand j'aurai trouvé le problème sur le calcule je serai de toute façon à plus donc ça ne sera pas exploitable... :frowning:

Je vais regarder l'autre solution que tu m'as présenté.. Il faudra que j'arrive à identifier à +/- 2ma pour avoir un résultat intéressant

Merci encore