Utilisation d'une fonction dans l'arduino

Bonjour, je suis nouveau sur ce forum et j'espère que je vais beaucoup apprendre avec vous !

J'ai une question: Au fait je fais des mesures de tensions avec un arduino M0 (c'est l'équivalent d'un arduino uno avec quelques petites différences) et j'utilise un ADC (ADS1115) pour avoir plus de précision. Je fais des mesures différentielles et mon code est donné ci-dessous. Ce programme me permet d'obtenir une tension différentielle entre le pin A0 et A3 du convertisseur. Je voudrais réaliser une fonction qui permet de:

  • réaliser 100 mesures de la même tension
  • faire une valeur moyenne
  • faire une valeur éfficace (RMS)
  • mesurer les valeurs pic to pic A la fin du calcul on obtient ces trois valeurs (moyenne, RMS et pic to pic) puis on fait pareil pour une autre tension recueilli sur les pins A0 et A2 de l'ADC.

include "ADS1X15.h"

ADS1115 ADS(0x48); // ADS1115 physiquement défini à l'adresse 0x48 i2c

void setup() { SerialUSB.begin(9600); ADS.begin(); ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion } void loop() { float U1; // Valeur des tension en V int valeurA0_A1; valeurA0_A1 = ADS.readADC_Differential_0_1();

// COnversion en volt U1 =ADS.toVoltage(valeurA0_A1); // Valeur exprimée en volts SerialUSB.println("Lecture de la différence de tension"); SerialUSB.println(U1); delay(1000); }

Quelqu'un pourrait m'aider s'il vous plaît ?

Je vous remercie d'avance pour vos réponses !

bonjour et bienvenue sur le forum

lisez comment utiliser le forum (les posts épinglés en haut du forum comme “Bien éditer son post pour les nuls” , “Faire un Nouveau Sujet ou le corriger avec les Balises…” et “Règles du forum francophone”),

———— SVP ————
corrigez votre post précédent et rajoutez les balises de code autour du code:
[code]`` [color=blue]// votre code ici[/color] ``[/code].

ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l’IDE avant de copier le code pour qu’il soit indenté correctement)

(lisez les messages épinglés en haut du forum)


Pour votre question il nous manque des informations

  • est-ce un projet scolaire ?
  • quelle bibliothèque utilisez vous (lien clickable) ?
  • avez vous étudié les boucles for / while / do ? c’est utile pour répéter 100 fois quelque chose

Il ne s'agit pas d'un travail scolaire, je fais ça pour un projet d'innovation que je me suis fixé moi même... Voici le lien de la bibliothéque de l'ADS1115: addicore/ADS1115: Arduino library for the ADS1115 Analog-to-Digital Converter (github.com)

:
//
#include "ADS1X15.h"
ADS1115 ADS(0x48);  // ADS1115 physiquement défini à l'adresse 0x48 i2c


void setup() {
  SerialUSB.begin(9600);
  ADS.begin();
  ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V
  ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique
  ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion
}
void loop() {
  float U1; // Valeur des tension en V
  int valeurA0_A1;
  valeurA0_A1 = ADS.readADC_Differential_0_1();




  // COnversion en volt
  U1 = ADS.toVoltage(valeurA0_A1); // Valeur exprimée en volts
  SerialUSB.println("Lecture de la différence de tension");
  SerialUSB.println(U1);
  delay(1000);
}

vous êtes sûr ? la méthode readADC_Differential_0_1() ne semble pas en faire partie…

la bibliothèque Adafruit semble offrir ces méthodes

int16_t readADC_Differential_0_1();
int16_t readADC_Differential_2_3();

pour lire 100 fois et faire le cumul dans une variable somme on fait

long somme = 0;
for (byte i=0; i < 100; i++) {
  somme += ADS.readADC_Differential_0_1();
}

Bonjour,
J’ai essayé de créer un tableau pour y mettre les 10 valeurs de tension que je mesure puis faire la somme et enfin faire la moyenne mais mon code ne tourne pas. Le problème se trouve au niveau de la déclaration du tableau.
Des propositions s’il vous plaît ? Voilà le code ci-dessous.

Je vous remercie d’avance !

#include "ADS1X15.h"
ADS1115 ADS(0x48);  // ADS1115 physiquement défini à l'adresse 0x48 i2c


void setup() {
  while (!SerialUSB); //Tried while(!SerialUSB); as well
  SerialUSB.begin(9600);
  ADS.begin();
  ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V
  ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique
  ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion
}
void loop() {
  float U1; // Valeur des tension en V
  int16_t valeurA0_A1;




  float tab[11] = ADS.toVoltage(valeurA0_A1); //remplir le tableau avec 10 valeurs de tension en V


  int somme = 0;


  for (int i = 0 ; i < 11 ; i++)
  {
    somme += tab[11] ; //somme des valeurs de tension du tableau
  }


  float moyenne = somme / 10.0 ; //valeur moyenne
  SerialUSB.print("La moyenne est : "); //affichage dbm
  SerialUSB.println(moyenne);


  delay(1000);
}
}

lisez un tuto sur le langage C ou C++ et les tableaux…

Ce n’est pas comme cela

  float tab[11] = ADS.toVoltage(valeurA0_A1); //remplir le tableau avec 10 valeurs de tension en V

que vous allez remplir un tableau et si vous écrivez somme += tab[11]vous rajoutez à somme le contenu de la case à l’indice 11 (qui n’existe pas, vous avez demandé 11 éléments dans le tableau et les indices vont de 0 à 10 donc)

il faudrait faire

float tab[10]; // 10 éléments dans le tableau, les indices vont de 0 à 9
for (int i = 0 ; i < 10 ; i++) tab[i] = ADS.toVoltage(valeurA0_A1); //remplir le tableau avec 10 valeurs de tension en V

mais si c’est pour calculer uniquement la moyenne, vous n’avez pas besoin de conserver chaque valeur individuellement, la boucle que je vous proposais plus haut calcule la somme

float somme = 0;
for (byte i=0; i < 10; i++) {
  somme += ADS.readADC_Differential_0_1();
}
float moyenne = somme / 10.0;

et donc pour obtenir la moyenne il suffit de diviser somme par 10.

Merci beaucoup pour votre réponse !
J’ai modifié mon programme mais le résultat de la moyenne donne 0 en sortie et j’ignore où se situe le problème. Voilà le code ci-dessous. Avez-vous une idée du problème ?

#include "ADS1X15.h"
ADS1115 ADS(0x48);  // ADS1115 physiquement défini à l'adresse 0x48 i2c


void setup() {
  while (!SerialUSB); //Tried while(!SerialUSB); as well
  SerialUSB.begin(9600);
  ADS.begin();
  ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V
  ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique
  ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion
}
void loop() {
  float U1; // Valeur des tension en V
  int16_t valeurA0_A1;
  float somme = 0;
  for (byte i = 0; i < 10; i++) {
    somme += ADS.toVoltage(valeurA0_A1);
  }
  float moyenne = somme / 10.0;


  SerialUSB.print("La moyenne est : "); //afficher la valeur moyenne
  SerialUSB.println(moyenne);


  while (1);
}

êtes vous sûr de l’appel?

 int16_t valeurA0_A1;
somme += ADS.toVoltage(valeurA0_A1);

ça semble louche, c’est quoi le paramètre ?
Quelle bibliothèque ? (prenez celle d’Adafruit)

sinon testez la lecture avec un code tout simple qui lit et affiche la valeur lue puis fait une pause d’une seconde.

C’est bon j’ai réglé le problème !
J’avais pas commencé par calculer la valeur numérique de la tension. Et donc si je lui dit directement de convertir en volt, il va forcement me donner 0 car pas de valeur numérique à convertir.
Voilà le bon code ci-dessous. Je dois maintenant réaliser une fonction qui permet de faire cette même opération (moyenne) pour 4 ADC différents les uns à la suite des autres…

#include "ADS1X15.h"
ADS1115 ADS(0x48);  // ADS1115 physiquement défini à l'adresse 0x48 i2c


void setup() {
  while (!SerialUSB); //Tried while(!SerialUSB); as well
  SerialUSB.begin(9600);
  ADS.begin();
  ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V
  ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique
  ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion
}
void loop() {
  int16_t valeurA0_A1;
  float somme = 0;


  for (byte i = 0; i < 100; i++) {
    valeurA0_A1 = ADS.readADC_Differential_0_1(); // valeur numérique
    somme += ADS.toVoltage(valeurA0_A1); // valeur en volt
  }
  float moyenne = somme / 100.0;
  SerialUSB.print("La moyenne est : "); //afficher la valeur moyenne
  SerialUSB.println(moyenne);


  while (1);
}

OK :slight_smile: (c’est ce que je me disais)

je ne suis toujours pas au clair sur la bibliothèque que vous utilisez…
La bibliothèque Adafruit_ADS1X15 propose la fonction readADC_Differential_0_1() mais pas la addicore/ADS1115… hors vous faites

#include "ADS1X15.h"

alors que pour utiliser celle d’Adafruit il faut faire
#include <Adafruit_ADS1X15.h>=> je ne comprends donc pas si vous faites vraiment tourner ce code ou sur quelle bibliothèque vous êtes.

Je dois maintenant réaliser une fonction qui permet de faire cette même opération (moyenne) pour 4 ADC différents les uns à la suite des autres

La puce ADS1115 peut être configurée soit en 4 simples entrées analogiques (4 canaux) ou en 2 canaux différentiels. Si vous faites du différentiel, vous n’avez que 2 ADC. Avez vous un second ADS1115 où ce n’est pas du différentiel que vous voulez faire ?

La fonction  [color=#222222]readADC_Differential_0_1()
représente la valeur numérique de la tension. Pour convertir cette valeur en volt il faut mettre  

[color=#222222]ADS.toVoltage(valeurA0_A1)

.
La bibliothéque  

[color=#222222]#include <Adafruit_ADS1X15.h>

ne marche pas chez moi c’est pourquoi j’utilise l’autre.
Le convertisseur que j’utilise a effectivement 4 pin analogiques. Je souhaite faire des mesures différentielles ce qui réduit le nombre de pins de mesure disponibles, c’est la raison pour laquelle j’aimerais utiliser 4 convertisseurs en parallèles.

Désolé mon message est mal fait !

La fonction ADS.readADC_Differential_0_1() représente la valeur numérique de la tension. Pour convertir cette valeur en volt il faut mettre ADS.toVoltage(valeurA0_A1).
La bibliothéque #include <Adafruit_ADS1X15.h> ne marche pas chez moi c’est pourquoi j’utilise l’autre.

Le convertisseur que j’utilise a effectivement 4 pin analogiques. Je souhaite faire des mesures différentielles ce qui réduit le nombre de pins de mesure disponibles, c’est la raison pour laquelle j’aimerais utiliser 4 convertisseurs en parallèles.

je ne comprends pas votre histoire de bibliothèque. la fonction readADC_Differential_0_1() n’existe pas dans celle que vous indiquez, donc je ne vois pas comment vous pouvez l’appeler… les fonctions proposées sont les suivantes:

       // Differential
        int16_t getConversionP0N1();
        int16_t getConversionP0N3();
        int16_t getConversionP1N3();
        int16_t getConversionP2N3();

        // Single-ended
        int16_t getConversionP0GND();
        int16_t getConversionP1GND();
        int16_t getConversionP2GND();
        int16_t getConversionP3GND();

La bibliothèque Adafruit a bien la fonction readADC_Differential_0_1()et propose aussi la différence sur 2/3

 int16_t readADC_Differential_0_1();
  int16_t readADC_Differential_2_3();

donc c’est louche votre truc…

Le convertisseur que j’utilise a effectivement 4 pin analogiques. Je souhaite faire des mesures différentielles ce qui réduit le nombre de pins de mesure disponibles, c’est la raison pour laquelle j’aimerais utiliser 4 convertisseurs en parallèles.

Quelles mesures différentielles devez vous effectuer ?

Ah je suis désolé ! je vous avais pas envoyé le bon lien.

Il s’agit de la librairie « ADS1X15 » de RobTillaart (https://github.com/RobTillaart/ADS1X15), prévue pour les ADC ads1015 et ads1115.

J’attends ma carte électronique pour faire des mesures. Pour le moment je fais des codes et teste avec ce que j’ai (carte arduino et un module ADS1115). Je suis entrainde faire la mesure différentielle entre le 5V et le 3.3V de l’arduino: faire cette mesure 100 fois puis faire la valeur moyenne puis la valeur pic to pic et en fin la valeur efficace.

OK - c’est plus clair :wink:

la bibliothèque sait faire du différentiel sur 0/1 0/3 1/3 et 2/3

// returns the difference between 2 ADC pins.
readADC_Differential_0_1() 
readADC_Differential_0_3() 
readADC_Differential_1_3() 
readADC_Differential_2_3()

elle sait aussi gérer de l’asynchrone, par exemple vous démarrez requestADC_Differential_0_1(); l’analyse et ensuite vous appelez isBusy() pour savoir si la conversion est encore en cours et une fois qu’il n’est plus busy vous appelez getValue() pour obtenir la valeur

c’est assez bien documenté dans son GitHub et il a un exemple qui lit les 4 options différentielles

#include <ADS1X15.h>

ADS1115 ADS(0x48);

void setup() {
  Serial.begin(115200);
  Serial.print("ADS1X15_LIB_VERSION: ");
  Serial.println(ADS1X15_LIB_VERSION);
  ADS.begin();
  ADS.setGain(0);
}

void loop()  {
  int16_t val_01 = ADS.readADC_Differential_0_1();  
  int16_t val_03 = ADS.readADC_Differential_0_3();  
  int16_t val_13 = ADS.readADC_Differential_1_3();  
  int16_t val_23 = ADS.readADC_Differential_2_3(); 
  float volts_01 = ADS.toVoltage(val_01); 
  float volts_03 = ADS.toVoltage(val_03); 
  float volts_13 = ADS.toVoltage(val_13); 
  float volts_23 = ADS.toVoltage(val_23); 

  Serial.print("\tval_01: "); Serial.print(val_01); Serial.print("\t"); Serial.println(volts_01, 3);
  Serial.print("\tval_03: "); Serial.print(val_03); Serial.print("\t"); Serial.println(volts_03, 3);
  Serial.print("\tval_13: "); Serial.print(val_13); Serial.print("\t"); Serial.println(volts_13, 3);
  Serial.print("\tval_23: "); Serial.print(val_23); Serial.print("\t"); Serial.println(volts_23, 3);
  Serial.println();

  delay(1000);
}

OK !
Est ce que vous saurez me dire comment faire la valeur crête à crête et la valeur efficace de ma tension ? Ou me donner juste un exemple s’il vous plaît ? J’ai cherché mais pas trouvé d’exemples concrets sur internet :slight_smile:

Je vous remercie d’avance !

Pas de bol, j’avais répondu en détail hier juste au moment où ils ont coupé le forum

en gros il faut juste rajouter une variable pour faire la somme des carrés ainsi que deux variables pour capturer le min et le max dans la boucle for ainsi vous aurez en sortie de boucle les éléments nécessaires

Salut ! Eh oui il y avait eu un bug hier et comme vous le dites j’ai pas eu de chance :slight_smile:

J’ai essayé tout seul pour arriver à obtenir la valeur pic to pic de ma tension mais je n’arrive pas vraiment :slight_smile:
Voilà mon code ci-dessous. A la place du nom des pins de l’ADC j’ai mis “channel” parce que je sais pas trop quoi mettre à ce niveau. Je voudrais que vous m’aidiez un peu s’il vous plaît pour aboutir à ce que je cherche…

Je vous remercie d’avance pour le temps que vous m’accordez !

#include "ADS1X15.h"  // bibliothéque du convertisseur
ADS1115 ADS(0x48);  // ADS1115 physiquement défini à l'adresse 0x48 i2c

void setup() {
  while (!SerialUSB); //Tried while(!SerialUSB); as well
  SerialUSB.begin(9600);
  ADS.begin();    // Fonction de démaraage du convertisseur
  ADS.setGain(1); // Gain de 2/3 et on peut faire une mesure de tension jusqu'à 6.144V
  ADS.setMode(1); // Faire des lectures de tension à la demande et non de manière automatique
  ADS.setDataRate(7); // Réglage de la vitesse de lecture qui est ici au maximun soit 860 échantillons par seconde et 1.16ms de temps de conversion
}
void loop() {
  float somme = 0;  // Initialisation de la variable somme

  for (int n = 0; n < 1000; n++) { // boucle for pour réaliser 1000 mesures
    int16_t valeurA0_A1 = ADS.readADC_Differential_0_1(); // valeur numérique de la différence de tension entre chanal A0 et A1
    somme += ADS.toVoltage(valeurA0_A1); // valeur en volt
    double Amp;   // amplitude pic to pic
    for (int i = 0; i < 3; i++) // Le nombre de canal comprise entre 0 et 3 et Rcherche de la valeur min et max
    {
      if (Channel[i] < min)
      {
        min = Channel[i];
      }
      else if (Channel[i] > max)
      {
        max = Channel[i];
      }
    }
    Amp = max - min; // Calcul de l'amplitude pic to pic
  }
  float moyenne = somme / 1000.0;  // Faire la moyenne
  SerialUSB.print("La moyenne est : "); //afficher la valeur moyenne
  SerialUSB.println(moyenne); // Valeu moyenne

  while (1); // Forcer le programme à s'arrêter
}

pour calculer le min et le max dans une boucle on initialise le min à quelque chose de très grand, le max à quelque chose de très petit et on fait

float minV = 100000000;
float maxV = -100000000;
float somme=0;
float sommeCarre=0;
float data;
for (int i=0; i<100; i++) {
  data = acquisition(); // la fonction d'acquisition
  somme += data;
  sommeCarre += data * data;
  if (data > maxV) maxV = data;
  if (data < minV) minV = data;
}

donc ensuite

  • la moyenne c’est somme / 100
  • la valeur crête à crête c’est maxV - minV
  • la valeur efficace c’est sqrt(sommeCarre / 100)

Je vous laisse appliquer à votre cas :wink:

Je vous remercie !!

J’ai réussi à faire tourner mon programme et faire les calculs…