AD-Wandler, Vermeidung von Messfehlern

Elektronik-Labor   Projekte   AVR 

 

Wie hochohmig sind die ADC-Eingänge eines ATmega-Controllers? Im Datenblatt des Mega32 kann man im Kapitel zum AD-Wandler lesen, dass der Innenwiderstand eines Messobjekts nicht größer als 10 kΩ sein sollte. Tatsächlich hat ein AD-Eingang zwar einen fast unendlichen Innenwiderstand. Man muss aber bedenken, dass beim Sampeln eines Messwerts ein kleiner Kondensator von einigen Picofarad geladen wird. Wenn immer wieder derselbe AD-Eingang gemessen wird und die Spannung sich kaum ändert, gibt es keine Probleme mit einer größeren Impedanz der Signalquelle. Anders sieht es aber aus, wenn mehrere Kanäle mit unterschiedlichen Spannungen gemessen werden sollen. Der Sampel-Kondensator muss dann jedesmal neu geladen werden, was nur an niederohmigen Quellen vollständig gelingt.



Eine typische Anwendung ist die Verwendung von Spannungsteilern. An den AD-Eingängen könnten mehrere hochohmige Spannungsteiler liegen. Die Software kann dann eine Bereichsumschaltung vornehmen.




Hochohmige Messquelle

Welcher Messfehler kann an einer zu hochohmigen Quelle entstehen? Dazu wurde ein Testaufbau mit dem ES-M32 verwendet. ADC0 liegt über einen Jumper an einem Poti auf dem Board. An ADC1 wurde ein hochohmiger Spannungsteiler mit zweimal 1 MOhm angeschlossen. Die Spannung an ADC1 ist also 2,5 V, die an AC0 ist einstellbar.



Das Testprogramm untersucht den Extremfall, dass beide Kanäle abwechselnd in schneller Folge gemessen werden. Es kommt dann zu einem Ladungstransport zwischen den Eingängen.  Der Eingang ADC0 mit seinem 10-kΩ-Poti kat kein Problem damit, aber ADC1 mit dem Innenwiderstand 500 kΩ des Spannungsteilers kann eine Spannungsänderung erfahren.


'ATmega32, AD-Wandler

$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 16
$swstack = 32
$framesize = 32
Baud = 9600


Dim N As Integer
Dim U1 As Integer
Dim U2 As Integer


Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcd = 16 * 2

Initlcd
Cls
Locate 1 , 1
Lcd "AD"
Config Adc = Single , Prescaler = 64 , Reference = Off
Start Adc

Waitms 1000

Do
For N = 1 To 1000
U1 = Getadc(0)
U2 = Getadc(1)
Next N
Cls
Locate 1 , 1
Lcd "ADC0"
Locate 1 , 8
Lcd "ADC1"
Locate 2 , 1
Lcd U1
Locate 2 , 8
Lcd U2
Waitms 1000
Loop

End

Messergebnisse:

1. Der Jumper an ADC0 wird geöffnet. ADC1 zeigt konstant den Messwert 509. Der offene Eingang ADC0 wird mitgezogen und zeigt einen Messwert von 505. Der Unterschied 509 zu theoretischen 512 ist auf die Toleranz der Widerstände zurückzuführen. Das zeigt ein Vertauschen der beiden Widerstände mit dem neuen Messwert 513.

2. Der Jumper wird geschlossen, an ADC0 liegt also das 10-kΩ-Poti. Stellt man 0 V ein, sinkt der Messwert an ADC1 auf 495. Bei 5 V an ADC0 wird ADC1 auf 524 gezogen. Der Messfehler beträgt bis zu 2,5 %.

3. Der AD-Wandler wird mit einem Vorteiler von 128  langsamer betrieben. Der Sample-Kondensator hat damit mehr Zeit, sich auf die volle Spannung aufzuladen. ADC1 zeigt zwischen 506 und 512.  Der Messfehler ist nur noch 0,6 %.
Config Adc = Single , Prescaler = 128 , Reference = Off
 
4. Jeder Kanal wird zweimal hintereinander gemessen. Der Messwert an ADC1 wird nun nur noch zwischen 508 und 509 verändert. Der Messfehler sinkt auf unter 0,1 %.
  For N = 1 To 1000
U1 = Getadc(0)
U1 = Getadc(0)
U2 = Getadc(1)
U2 = Getadc(1)
Next N

Strom über die Schutzdioden

Bei älteren AD-Wandlern musste man unbedingt vermeiden, dass einer der nicht benutzten Nachbarkanäle außerhalb der erlaubten Messspannung lag. Wenn eine der Eingangs-Schutzdioden in den leitenden Zustand ging, kam es zu einer Ladungsübertragung auf den Messkanal und damit zu einer starken Verfälschung. Trifft dieses Verhalten auch auf den AD-Wandler im Mega32 zu? Dazu wurde der Kanal ADC2 gequält.




Ergebnis: Es tritt keine Beeinflussung durch den Nachbarkanal auf. Der Fehlerstrom wurde bis auf 50 mA erhöht, ohne dass sich der Messwer am hochohmigen Spannungsteiler änderte.

Siehe auch: Tipps zum AD-Wandler in ELEXS


Hinweise zum AD-Wandler von Andre Bryx

Es ist für die effiziente Berechnung der AD-Ergebnisse nicht sehr vorteilhaft, diese direkt in einer Single-Variable zu berechnen. Fließkommaoperationen behindern die Ausführungsgeschwindigkeit und verbrauchen zu viele Ressourcen.

Ich persönlich rechne immer in Milllivolt und NUR wen ich auch wirklich Bildschirm oder Display-Ausgaben benutze, kann ich den Wert noch in eine entsprechende Variable übergeben. Die korrekte Berechnungsformel lautet

WERT = AD * VREF / 2^10

Wenn VREF angenommen 2,56 Volt sind, erhält man einen Fixwert von VREF/1024 (eine Fließkomma-Rechenoperation gespart) = 0,0025. Da ich in mV rechnen will, nehme ich als als VREF Fixwert 2,5mV, woraus sich dann eine ganz einfache Operation in Ganzzahlen ergibt:

WERT = AD*250

um den Wert in mV zu erhalten.

Der Code wird verschlankt, die Ressourcen geschont und das Programm wird sich bedanken.

Genauer wird die Ausgabe, wenn man den AD-Wandler im Free-Mode betreibt, welchen BASCOM aber nicht unterstützt (Außer bei Config ADC)!! Hierzu muss man den ADC-Interrupt einsetzen und die AD-Ergebnisse direkt aus den Registern lesen.

Zu den Ausführungen zur VREF-Quelle muss ich noch  sagen, das die interne Bandgap-Referenz zwar nicht immer hypergenau ist, dafür aber extrem stabil und rauschfrei ist (wenn man an AREF einen Keramik-C gegen Masse und ein L in die Versorgung AVCC legt).  Die Versorgung von VREF über einen 7805 bringt viel zu viel Rauschen ins System, dann lieber einen LTC 1021 als Superreferenz.  Aber das ist eine ganz andere Geschichte :-)



Elektronik-Labor   Projekte   AVR