Différence de 0.3V entre la valeur réelle est celle renvoyée par l'arduino nano

Bonjour,

Afin d'avoir accès a des valeurs de tensions sur une carte électronique afin de faire des contrôles d'entrée j'utilise un arduino nano pour utiliser son convertisseur analogique-numérique afin d'automatiser ce contrôle d'entrée.

Malheureusement, quand j’exécute mon programme arduino j'ai un décalage de 0.3V entre la valeur calculée à l'aide d'un multimètre (3.3V par exemple) et celle affichée par le moniteur série (3.6V pour cet exemple).

J'aimerai donc comprendre, s'il vous plaît, d'où vient cette si grande différence et comment la régler.

J'utilise donc ce code :

const float COEFF_PONT_DIVISEUR = 2.0;
// Fonction setup(), appelée au démarrage de la carte Arduino
void setup() {

  // Initialise la communication avec le PC
  Serial.begin(9600);

}

// Fonction loop(), appelée continuellement en boucle tant que la carte Arduino est alimentée
void loop() {
  
  // Mesure la tension sur la broche A0
  int valeur0 = analogRead(A0);
  
  // Transforme la mesure (nombre entier) en tension via un produit en croix
  float tension0 = valeur0 * (5.0 / 1023.0) * COEFF_PONT_DIVISEUR ;
  
  // Envoi la mesure au PC pour affichage et attends 250ms
  Serial.print("La valeur de la tension 5V est : ");
  Serial.println(tension0);
  delay(250);

   int valeur1 = analogRead(A4);
  
  // Transforme la mesure (nombre entier) en tension via un produit en croix
  float tension1 = valeur1 * (5.0 / 1023.0);
  
  // Envoi la mesure au PC pour affichage et attends 250ms
  Serial.print("La valeur de la tension 3.3V est : ");
  Serial.println(tension1);
  delay(250);

  int valeur2 = analogRead(A7);
  
  // Transforme la mesure (nombre entier) en tension via un produit en croix
  float tension2 = valeur2 * (5.0 / 1023.0);
  
  // Envoi la mesure au PC pour affichage et attends 250ms
  Serial.print("La valeur de la tension 4.5V est : ");
  Serial.println(tension2);
  delay(5000);
}

Merci d'avance

Bonjour et Binvenue !!

En arrivant sur ce forum il est indispensable de consulter son 'mode d'emploi' , en particulier la partie expliquant comment bien poster son code.

Deux remarques sur la conversion:

-la conversion analogique numérique semble prendre ici la tension d'alimentation comme référence.
Cette tension ne vaut sans doute pas exactement 5V (5 dans le code), en particulier si l'alimentation se fait par par le port USB

-les résistances du pont diviseur ont probablement une tolérance de 5%, le rapport de division ne vaut probabalementt pas exactement 2 comme dans le code

Effectivement, je connecte l'arduino par le port USB et en mesurant avec un multimètre le point 5V de l'arduino j’obtiens 4.79V.
J'ai donc remplacé dans mon code les valeurs 5 par 4.79 et j'obtiens les bons résultats.

Je ne sais pas si il y a de meilleures solutions pour régler ce problème?

Merci beaucoup

Tu ne dis pas comment est alimenté la carte nano !
Si c'est par l'USB c'est encore pire que ce qu" @al1fch t'a dit.

Dans la partie alimentation de la nano par l'USB il y a une diode schottky pour protéger la partie USB du PC en cas d'alimentation de la nano par Vin.

Cela fonctionne bien sauf que quand tu alimentes par l'USB la diode apporte une chute de tension variable selon le courant qui la traverse, entre 0,3 et 0,6 V.
Donc dans ce cas il est normal que le calcul soit faux.
A ta décharge ce n'est indiqué nulle part dans la doc arduino, il faut regarder le schéma électrique pour s'en rendre compte.

L'ADC a trois modes de fonctionnement en fonction du choix de la référence de tension :
. le mode par defaut avec la référence à Vcc
. le mode en référence externe : tension appliquée sur la broche Aref
. le mode en référence interne 1,1 V

Pour avoir des mesures correctes au choix tu peux faire :

  1. Alimenter la carte par Vin (ou raw). Le Vcc sera celui du régulateur interne de la carte qui est très précis.
  2. En alim USB, mesurer la tension exacte sur le 5 V de la carte et utiliser cette valeur dans ton programme.
  3. faire fonctionner l'ADC en référence externe en reliant la tension 3,3 V du régulateur secondaire de la carte sur la borne Aref.
  4. utiliser l'ADC avec la référence interne qui vaut 1,1 V +/- 0,1 V selon les lots de fabrication. Il faut donc mesurer cette valeur. Elle est présente sur la broche Aref quand on sélectionne la référence interne,
    Attention en cas d'usage de la référence interne il est interdit d'appliquer une tension externe sur Aref sinon tu tues le micro.

Point de détail de langage : on ne calcule pas une tension avec un voltmètre : on fait une mesure avec un voltmètre.

bonjour
déjà dans le code la conversion est calculée sur Vref/1023
lire çà
alors qu'il y a 1024 intervalles

mettre une ref de tension externe stable

Merci à tous pour vos réponses j'ai pu résoudre les différents problèmes que je rencontrais!

Il est rare qu'un projet reste alimenté par un cordon USB. A terme il faudra bien utiliser une alimentation, y compris bloc secteur USB, et la valeur de la tension sera forcément différente, et même elle variera dans le temps, tout comme la tension 5VUSB d'un PC.
Solutions :
Utiliser la référence 1.1V interne :
analogReference(INTERNAL);
Si une grande précision est requise, utiliser une référence externe :
analogReference(EXTERNAL);
Avec un pont diviseur adapté bien sûr.

mais vous n'avez pas corrigé votre premier post pour rajouter les balises de code...

merci de le faire ASAP...