La conversion ADC en tension repose-t-elle sur la valeur réelle de la broche +5 V?

13

Des questions:

  1. La conversion du compte ADC en tension dépend-elle de la tension réelle de la broche +5 V?
  2. Si oui, quelle est la méthode acceptée pour obtenir cette tension de la carte?

Contexte / détail:

J'ai un circuit dans lequel j'ai un Arduino Nano (clone) fonctionnant à partir d'un connecteur USB (à partir d'un concentrateur). Le travail de l'Arduino est de mesurer la tension sur une batterie qui entraînera un second circuit allumé / éteint par le Nano. Pour référence, il s'agit d'un testeur de batterie.

Circuit d'essai

Il y a un écran Nokia 5110 qui affiche la tension du croquis très simple ci-dessous.

void setup() {
  Serial.begin(9600);
  display.begin();
  // Init done

  // You can change the contrast around to adapt the display
  // for the best viewing!
  display.setContrast(50);

  // Text display tests
  display.setTextSize(1);
  display.setTextColor(BLACK);
}


void loop() {
  display.clearDisplay();   // Clears the screen and buffer
  display.setCursor(0,0);
  display.print("Vin=");
  int rawVIN = analogRead(VIN);
  float floatVin = (rawVIN*4.75)/1023.0;
  display.println(floatVin);
  Serial.println(rawVIN);
  display.display();
  delay(1000);
}
  • J'ai mesuré la tension de la batterie à l'aide d'un DVM et elle est de 4,13 V, mais le Nano rapporte 4,35 V.
  • J'ai un terrain commun entre la batterie et l'Arduino.
  • Parce que la connexion pour tester la tension peut flotter, j'ai une résistance de pulldown pour arrêter les fluctuations sauvages (> 10 kΩ)

Après une enquête, j'ai trouvé que le +5 V produisait en fait 4,75 V et j'ai changé mon croquis de

float v = (rawVIN*5.0)/1024.0;

à

float v = (rawVIN*4.75)/1024.0;

et la lecture de tension sur l'Arduino était maintenant correcte. Je ne l'ai pas fait parce que je comprends ce que j'ai fait, je l'ai fait parce que j'avais un pressentiment, cela pourrait changer la valeur en la bonne.

Caribou
la source
3
En tant que côté non, vous devriez diviser par 1024, pas 1023. C'est une erreur qui se répète encore et encore, probablement en raison de l'erreur dans les exemples Arduino. La source? La fiche technique de l'AVR.
Tom Carpenter
@TomCarpenter Je pense que c'est le résultat de mes tâtonnements avec le calcul et la lecture de quelque chose après un temps assez long pour me cogner la tête contre le bureau - j'ai commencé avec 1024 mais comme vous le voyez a fini avec 1023 - je vais corriger ma question .
Caribou

Réponses:

16

L'ADC à l'intérieur de l'Arduino ne mesure pas la tension, mais plutôt un rapport de tension . À savoir le rapport de la tension à l'entrée analogique à la tension à la broche Vref.

Dans la configuration par défaut, la broche Vref est liée en interne à la ligne +5 V. Vous pouvez choisir d'utiliser à la place une référence interne comme Vref :

analogReference(INTERNAL);

Cette référence est d'environ 1,1 V, et est tout à fait à l'abri des fluctuations sur le +5 V. Le problème est que vous ne pouvez pas mesurer des tensions supérieures à la référence.

Pour votre testeur de batterie, si vous voulez une sorte de mesure «absolue», vous pouvez utiliser la référence interne et un diviseur de tension pour vous assurer que la tension mesurée est inférieure à 1,1 V.

Edit : Une autre option qui ne nécessite pas de diviseur de tension est d'utiliser Vcc comme référence pour mesurer à la fois l'entrée analogique et la référence interne de "bande interdite" 1,1 V. Mesurer le 1,1 V contre Vcc est une façon indirecte de mesurer Vcc. Ce n'est pas pris en charge par la bibliothèque principale Arduino, mais vous pouvez le faire en programmant directement les registres de contrôle de l'ADC:

// Return the supply voltage in volts.
float read_vcc()
{
    const float V_BAND_GAP = 1.1;     // typical
    ADMUX  = _BV(REFS0)    // ref = Vcc
           | 14;           // channel 14 is the bandgap reference
    ADCSRA |= _BV(ADSC);   // start conversion
    loop_until_bit_is_clear(ADCSRA, ADSC);  // wait until complete
    return V_BAND_GAP * 1024 / ADC;
}

Attention, la toute première lecture après le démarrage peut être fausse.

Edgar Bonet
la source
Merci pour la réponse rapide :) cela est parfaitement logique maintenant et explique pourquoi par mon ajustement de code (fudge) j'obtiens la bonne réponse. Ceci combiné avec la réponse enrics me donne tout ce dont j'ai besoin pour continuer.
Caribou
9

Un Arduino Nano alimenté par USB aura une référence de tension ADC qui ne peut pas être invoquée, en raison de la tolérance de +/- 5% de la tension USB entrante. En plus de cela, le Nano a une diode Schottky MBR0520 (D1) qui chutera entre 0,1 et 0,5 V en fonction de ses propres tolérances de fabrication, de sa température et de la consommation de courant de votre carte.

Que peux-tu y faire?

Le MCU à bord de l'Arduino Nano est un ATmega328P. L'ADC du Nano peut mettre à l'échelle ses lectures de tension analogiques en fonction de plusieurs références disponibles (et vous pouvez choisir celle qui vous convient le mieux). Vous pouvez le faire via la analogReference (type)fonction et choisir parmi les références suivantes type:

  • PAR DÉFAUT: la référence analogique par défaut de 5 volts (sur les cartes Arduino 5 V) ou 3,3 volts (sur les cartes Arduino 3,3 V)
  • INTERNE: Une référence intégrée, égale à 1,1 volts sur l'ATmega168 ou ATmega328 et 2,56 volts sur l'ATmega8 (non disponible sur l'Arduino Mega) [...]
  • EXTERNE: la tension appliquée à la broche AREF (0 à 5 V uniquement) est utilisée comme référence.

Source: analogReference

Voici le schéma ADC de ce qui se trouve à l'intérieur de l'ATmega328 afin que vous puissiez voir ce qui s'y passe:

Bloc ADC ATmega328P

Source: Fiche technique ATmega328

La solution simple consiste donc à créer un diviseur de tension faible pour obtenir la tension que vous souhaitez mesurer en dessous de la référence INTERNAL 1,1 V, puis à configurer en analogReferenceconséquence.

Le diviseur de tension doit être faible (valeurs R élevées) afin de ne pas tirer trop de courant de la batterie, mais pas trop faible pour être chargé par l'impédance d'entrée ADC.

Prime

Cependant, si vous avez besoin d'une référence de tension supérieure à la référence de bande interdite interne de 1,1 V de l'ATmega328, vous n'avez toujours pas de chance. Une option serait d'utiliser la sortie du régulateur LDO 3,3 V du FT232RL embarqué, qui est disponible à la broche 14 de l'en-tête, mais je ne pense pas qu'elle soit fiable non plus. La fiche technique FT232RL le spécifie à 3,0 - 3,6 V (3,3 V nominal)

Une solution universelle serait donc de construire une référence de tension externe basée sur un TL431 bon marché . Cela pourrait vous donner une référence fiable jusqu'à 4,0 - 4,25 V avec une précision de +/- 1%.

Le circuit de référence de tension externe serait aussi simple que cela (et le TL431 est disponible dans le boîtier TO-92 convivial!):

Régulateur de tension shunt basé sur TL431

Enric Blanco
la source
Merci pour cette réponse complète et toutes les alternatives que j'ai pu prendre - je vais probablement aller simple et faire un diviseur de tension pour mettre à l'échelle mon entrée entre 0 et 1,1. L'indice sur les valeurs des résistants m'a été précieux - merci
Caribou
3

J'ai une page sur le convertisseur ADC sur l'Atmega328P . Un peu plus bas, je décris les références de tension. Vous pouvez utiliser la puce TL431 pour fournir des tensions de référence variées, par exemple 4V:

Référence de tension 4V

En changeant les résistances, vous pouvez obtenir d'autres tensions (il semble que vous vouliez environ 4,2 V).

La tension de sortie n'est pas influencée par la tension d'entrée (5 V dans ce cas).

La page liée décrit comment vous pouvez choisir des valeurs de résistance.

Nick Gammon
la source
2

La conversion du nombre d'adc en tension dépend-elle de la tension réelle de la broche + 5v?

oui et non: le module adc se soucie de Vref, qui peut être alimenté via Vdd, en interne ou en externe.

Si oui, quelle est la méthode acceptée pour obtenir cette tension de la carte?

en configurant le module adc. la fiche technique de l'appareil doit avoir des registres / bits qui doivent être configurés pour cela.

dannyf
la source