Hängt die ADC-Umwandlung in eine Spannung vom tatsächlichen Wert des +5 V-Pins ab?


13

Fragen:

  1. Hängt die Umwandlung des ADC-Zählers in Spannung von der tatsächlichen Spannung des +5 V-Pins ab?
  2. Wenn ja, wie wird diese Spannung von der Platine abgerufen?

Hintergrund / Detail:

Ich habe eine Schaltung, in der ein Arduino Nano (Klon) von einem USB-Anschluss (von einem Hub) ausgeführt wird. Die Aufgabe des Arduino ist es, die Spannung an einer Batterie zu messen, die einen zweiten Stromkreis antreibt, der vom Nano ein- und ausgeschaltet wird. Als Referenz dient ein Batterietester.

Testschaltung

Es gibt einen Nokia 5110-Bildschirm, auf dem die Spannung anhand der folgenden sehr einfachen Skizze angezeigt wird.

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);
}
  • Ich habe die Spannung der Batterie mit einem DVM gemessen und sie beträgt 4,13 V, der Nano meldet jedoch 4,35 V.
  • Ich habe eine Gemeinsamkeit zwischen der Batterie und Arduino.
  • Da der Anschluss zum Testen der Spannung schweben kann, habe ich einen Pulldown-Widerstand, um wilde Schwankungen (> 10 kΩ) zu stoppen

Nach einigen Nachforschungen stellte ich fest, dass die +5 V tatsächlich 4,75 V ausgaben, und änderte meine Skizze von

float v = (rawVIN*5.0)/1024.0;

zu

float v = (rawVIN*4.75)/1024.0;

und der Spannungswert auf dem Arduino war jetzt korrekt. Ich habe dies nicht getan, weil ich verstehe, was ich getan habe. Ich habe es getan, weil ich eine Ahnung hatte, dass es den Wert in den richtigen ändern könnte.


3
Als Seite nicht sollten Sie durch 1024 teilen, nicht durch 1023. Dies ist ein Fehler, der immer wieder wiederholt wird, vermutlich aufgrund des Fehlers in den Arduino-Beispielen. Quelle? Das Datenblatt für den AVR.
Tom Carpenter

@TomCarpenter Ich denke, das liegt daran, dass ich nach einer langen Zeit, in der ich den Kopf gegen den Schreibtisch geschlagen habe, an der Berechnung herumgefummelt und etwas gelesen habe. Ich habe mit 1024 angefangen, aber wie Sie sehen, endete es mit 1023. Ich werde meine Frage korrigieren .
Caribou

Antworten:


16

Der ADC innerhalb des Arduino misst keine Spannung, sondern ein Spannungsverhältnis . Das Verhältnis von der Spannung am Analogeingang zur Spannung am Vref-Pin.

In der Standardkonfiguration ist der Vref-Pin intern mit der +5 V-Leitung verbunden. Sie können stattdessen eine interne Referenz als Vref verwenden :

analogReference(INTERNAL);

Diese Referenz liegt bei ungefähr 1,1 V und ist gegen Schwankungen der +5 V ziemlich unempfindlich. Das Problem ist, dass Sie keine höheren Spannungen als die Referenz messen können.

Wenn Sie für Ihren Batterietester eine Art „absolute“ Messung wünschen, können Sie die interne Referenz und einen Spannungsteiler verwenden, um sicherzustellen, dass die gemessene Spannung unter 1,1 V liegt.

Bearbeiten : Eine weitere Option, für die kein Spannungsteiler erforderlich ist, ist die Verwendung von Vcc als Referenz, um sowohl den Analogeingang als auch die interne 1,1-V-Bandlückenreferenz zu messen . Das Messen von 1,1 V gegen Vcc ist eine indirekte Methode zum Messen von Vcc. Dies wird von der Arduino-Kernbibliothek nicht unterstützt, aber Sie können dies tun, indem Sie die Steuerregister des ADC direkt programmieren:

// 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;
}

Beachten Sie, dass die allererste Lesung nach dem Start falsch sein kann.


Danke für die prompte Antwort :) Das macht jetzt vollkommen Sinn und erklärt, warum ich durch meine Code (Fudge) -Anpassung die richtige Antwort bekomme. Dies in Kombination mit der Antwort von Enrics gibt mir alles, was ich brauche, um fortzufahren.
Caribou

9

Ein Arduino Nano mit USB-Stromversorgung verfügt über eine ADC-Spannungsreferenz, auf die sich aufgrund der +/- 5% Toleranz der eingehenden USB-Spannung nicht verlassen kann. Darüber hinaus verfügt der Nano über eine MBR0520-Schottky-Diode (D1), die je nach Herstellungstoleranzen, Temperatur und Stromaufnahme Ihres Boards zwischen 0,1 und 0,5 V abfällt.

Was können Sie dagegen tun?

Die MCU an Bord des Arduino Nano ist ein ATmega328P. Der ADC des Nano kann seine analogen Spannungswerte anhand mehrerer verfügbarer Referenzen skalieren (und Sie können diejenige auswählen, die besser zu Ihnen passt). Sie können dies über die analogReference (type)Funktion tun und zwischen den folgenden Referenzen typewählen:

  • STANDARD: Die analoge Standardreferenz von 5 Volt (auf 5 V Arduino-Platinen) oder 3,3 Volt (auf 3,3 V Arduino-Platinen)
  • INTERN: Eine eingebaute Referenz, die beim ATmega168 oder ATmega328 1,1 Volt und beim ATmega8 2,56 Volt entspricht (beim Arduino Mega nicht verfügbar) [...]
  • EXTERN: Die an den AREF-Pin angelegte Spannung (nur 0 bis 5 V) wird als Referenz verwendet.

Quelle: analogReferenz

Dies ist das ADC-Schema für den Inhalt des ATmega328, damit Sie sehen können, was dort vor sich geht:

ATmega328P ADC-Block

Quelle: Datenblatt ATmega328

Die einfache Lösung besteht also darin, einen schwachen Spannungsteiler zu erstellen, um die zu messende Spannung unter der INTERNEN 1,1-V-Referenz zu erhalten, und diese dann entsprechend zu konfigurieren analogReference.

Der Spannungsteiler muss schwach sein (hohe R-Werte), damit Sie nicht zu viel Strom aus der Batterie ziehen, aber nicht zu schwach, um von der ADC-Eingangsimpedanz belastet zu werden.

Bonus

Wenn Sie jedoch eine Spannungsreferenz benötigen, die über der internen 1,1-V-Bandlückenreferenz des ATmega328 liegt, haben Sie immer noch Pech. Eine Option wäre die Verwendung des 3,3-V-LDO-Reglerausgangs des integrierten FT232RL, der Ihnen an Pin 14 des Headers zur Verfügung steht, aber ich glaube auch nicht, dass er zuverlässig ist. Das FT232RL-Datenblatt gibt es bei 3,0 - 3,6 V (nominal 3,3 V) an.

Eine universelle Lösung wäre daher, eine externe Spannungsreferenz auf der Basis eines billigen TL431 aufzubauen . Das könnte Ihnen eine zuverlässige Referenz von bis zu 4,0 - 4,25 V mit einer Genauigkeit von +/- 1% liefern.

Der externe Spannungsreferenzkreis wäre so einfach (und der TL431 ist im brettfreundlichen TO-92-Paket erhältlich!):

Shunt-Spannungsregler auf TL431-Basis


Vielen Dank für diese umfassende Antwort und alle Alternativen, die ich aufgreifen könnte - ich werde wahrscheinlich einfach vorgehen und einen Spannungsteiler erstellen, um meinen Eingang zwischen 0 und 1,1 zu skalieren. Der Hinweis auf Widerstandswerte war für mich wertvoll - danke
Caribou

3

Ich habe eine Seite über den ADC-Wandler auf dem Atmega328P . Etwas weiter unten beschreibe ich Spannungsreferenzen. Sie können den TL431-Chip verwenden, um verschiedene Referenzspannungen bereitzustellen, z. B. 4 V:

4V Spannungsreferenz

Durch Ändern der Widerstände können Sie andere Spannungen erhalten (es sieht so aus, als wollten Sie ungefähr 4,2 V).

Die Ausgangsspannung wird nicht von der Eingangsspannung beeinflusst (in diesem Fall 5V).

Die verknüpfte Seite beschreibt, wie Sie Widerstandswerte auswählen können.


2

Hängt die Umwandlung von ADC in Spannung von der tatsächlichen Spannung des + 5V-Pins ab?

yes and no: Das ADC-Modul kümmert sich um Vref, das intern oder extern über Vdd versorgt werden kann.

Wenn ja, welche Methode wird zum Abrufen dieser Spannung von der Platine akzeptiert?

durch Konfigurieren des ADC-Moduls. Das Gerätedatenblatt sollte Register / Bits enthalten, die dafür eingerichtet werden müssen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.