Die Auflösung des ADC vom Arduino Uno erhöhen auf 16 Bit mit Oversampling

Der Arduino Uno hat Analog Digital Wandler mit 10-Bit Auflösung eingebaut. Damit kann z. B. die Versorgungsspannung über die USB Schnittstelle ermittelt werden, wie in diesem Artikel beschrieben.

Bei 5V VCC und 10 Bit Auflösung sind das 1023 Messwerte oder ca. 5mV Auflösung eines Bits. Wenn das nicht ausreichend ist, kann die Genauigkeit erhöht werden durch den Trick des Oversampling. Dann sind 12 oder sogar 16 Bit Auflösung mit diesem einfachen AD Wandler möglich.

Das geht wie folgt für z.B. eine gewünschte 11 Bit Auflösung.
Es werden 4 Werte gemessen und addiert. Das Ergebnis wird um ein Bit nach rechts verschoben und wir haben das Messergebnis eines 11 Bit AD Wandlers.

Ein Beispiel für 4 AD-Messwerte:
502 + 504 + 503 +501 = 2010 um ein Bit nach rechts verschoben ergibt 1005
Das ist der Messwert für das 4-fach Oversampling oder den 11 Bit AD Wandler.

Durch das Oversampling wird die AD-Wandlung langsamer. In dem Beispiel wurden 4 Messungen gemacht. Eine weitere Voraussetzung ist, das der Messwert um mindestens 1 Bit der 10Bit AD-Wandlung schwankt, was aber meistens der Fall ist

Bei dem 10 Bit AD Wandler ist die Auflösung ca. 5V / 1023 also ca. 5mV und beim 11 Bit AD Wandler ist die Auflösung dann 5V /2047 also ca. 2,5mV und so weiter.

Die Schaltung ist sehr einfach, es ist nur eine Drahtbrücke von 3,3V zum A0 Eingang.

Für das Beispiel der Versorgungsspannung Messung kann das Programm dann so aussehen.

// Arduino Uno AD Wandler mit höherer Auflösung
//
// Matthias Busse 3.4.2015 Version 1.0

int u3v = 0; // Pin A0
int n=1, plusbit=6; // +6 Bit = 16 Bit Auflösung
double vcc;

void setup() {
  Serial.begin(4800);
}

void loop() {
  Serial.print(n);
  n++;
  Serial.print(" ");

  vcc = 3.30 / analogRead(u3v) * 1023;
  Serial.print(vcc,5);
  Serial.print(" ");

  vcc = 3.30l / oversample(u3v, plusbit) * (1023l << plusbit);
  Serial.println(vcc,5);
}

long oversample(int pin, int pbit) {
// + pbit Bit Auflösung des AD Wandlers
//  
// Matthhias Busse 2.4.2015 Version 1.0
long summe=0;
  for(int i=0; i < pow(4.0,pbit); i++) {
    summe += analogRead(pin);
  }
  return summe >> pbit;
}

Die Ergebnisse werden auf der Konsole ausgegeben.
Die Auswertung sieht dann so aus für 10-Bit (rot) und 16Bit (grün).

oversampling1

Die USB Versorgungsspannung schwankt um ca. 4,64V Volt. Bei der roten Linie für die 10-Bit Wandlung sieht man gut die einzelnen Messstufen. Bei der grünen Linie für die 16-Bit Wandlung sind viel genauere Messungen mit kleineren Schritten möglich und durch das Oversampling findet noch eine Mittlung / Glättung der Messwerte statt. Man sieht aber auch deutlich dass die Spannung um einige 5mV schwankt. Dadurch wird das Oversampling aber auch erst möglich.

Hier sind die benötigten Messungen und die Spannungsdifferenz von 1 Bit angegeben für die Standard 10-Bit AD-Wandlung bis zur 16-Bit AD-Wandlung mit 4096 Messungen.

oversampling2

– Eine einfache Mittelung der Messwerte reduziert das Rauschen der Ergebnisse.
– Oversampling nutzt das Rauschen um die Auflösung der Messwerte zu erhöhen.

Hardware: Arduino Uno Rev 3
Software: Arduino 1.6.1, Open Office Calc

von Matthias Busse

8 Gedanken zu „Die Auflösung des ADC vom Arduino Uno erhöhen auf 16 Bit mit Oversampling

  1. pj

    Hallo,

    das sieht sehr interessant aus, auch von der einfachen Anwendung, nur eine Drahtbrücke von 3,3V auf A0 zu setzen.
    Kannst du mir sagen warum das durch diese Drahtbrückenverbindung funktioniert ?
    Würdest du sowas empfehlen, wenn man im 1-Stelligen Millivolt bereich die Akku spannung messen möchte ?

    Danke

    Antworten
    1. admin Beitragsautor

      Die oben gemessene grüne Linie bei 16 Bit schwankt um knapp 10 mV. Das würde ich ersteinmal als Untergrenze oder Genauigkeit ansetzen. Durch eine lange Mittelung kann mann vielleicht noch knapp die Hälfte erreichen, also 3-5mV, aber darüber hinaus würde ich die Genauigkeit nicht treiben. Dann muss ein extra AD-Wandler mit entsprechender Stabilisierung und Genauigkeit her.

      Antworten
    2. Dr. Sampling

      Die Drahtbrücke, in diesem Falle dient nur dazu um ein Analogen Wert am ADC zu haben. Es wird in dem Beispiel die Spannung des 3,3V PIN genutzt um ohne großen Aufwand ein Analoges Signal zu haben, um den ADC mit Input zu füttern.

      Antworten
  2. Rüdiger

    Erst nach der Gleichsetzung der Baud-Raten im Gerätemanager für den verwendeten COM-Port und auch im seriellen Monitor werden Daten angezeigt.
    Das sollte in Deinem Beispiel Beachtung finden. So easy und schnell die Auswertung eines analogen Signales. Gut erklärt, Danke.

    Antworten
  3. AdamRiese

    Hallo, bist Du dir sicher das deine Formel richtig ist?
    Es sollte doch eigentlich 3,3 V rauskommen.
    3,3 / 2 ^ 10 * 1023=3,2967 V
    3,3 / 2 ^ 10 * 1024=3,3 V
    auch deine Tabelle solltest Du nochmal genau ansehen.

    Antworten
  4. Mr. Sensor

    Hallo,
    Hätte auch mal eine Frage zum oversampling:
    Kann man mit der vorgestellten Methode auch mehrere Pins gleichzeitig auslesen?
    Wollte nämlich damit einen 3 achsigen Beschleunigungssensor auslesen und die werte aller drei Achsen oversampeln.

    Gruß
    Mr. Sensor

    Antworten
  5. ulf

    So ein Unsinn, in den Graphen sieht man schon, dass die Streuung nicht gleichverteilt ist. Kommt also Blödsinn raus. Und die A/D Wandler haben einen Linearitätsfehler, das wird doch alles nicht besser. Ales was besser wird, ist das Gefühl des Programmierers. Ein verdrecktes Signal als Voraussetzung einer Genauigkeitsverbesserung, da lachen doch die Hühner.
    Im Übrigen erhält man genau das gleiche Ergebnis, wenn man die 10bit AD werte über 4 Werte mit double gleitend mittelt, das braucht weniger Ressourcen. Ein verdrecktes Signal sollte aber nie die Voraussetzung einer höheren Genauigkeit sein. Anders wäre das, wenn man einem sauberen Signal ein gaussverteiltes Rauschen zuaddiert. Aber warum einem schlechten AD Wandler noch gute Gedanken hinterherwerfen…

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.