Hallo,
ich stehe gerade völlig auf dem Schlauch (obwohl es heute gar nicht so
warm ist): Ich will eine Temperatur über einen Sensor messen. KTY-xx
schien gut, kostet ca. 50 Cent. Ein "fertiger" (Sensor LM35 DZ)
kostet 1 Euro und liefert 10 mV/K. Problem: Der ADC (ATMega8) bezieht
sich immer auf GND und die angelegte Referenzspannung. Also muß ich
eine exakte Referenzspannung erzeugen (oder bei bekannter Temperatur
kalibrieren). Also bei VRef = 5V => ADC=512 bedeutet genau 2,5 V. bei
VRef = 4 V bedeutet ADC=512 => 2 V. Oder mache ich da einen
Gedankenfehler? Kann ich auch irgendwie absolute Spannungen messen?
Danke
Martin
der ad wandler macht eben aus einem ANALOGEN spannungswert einen
DIGITALEN 10bit langen wert mit einer auflösung von 1023(1024 - lsb,
bezogen auf atmega).
und denn machste z.b. in bascom ne abfrage wie
spannung=getadc(0)*204
(bzw. 204,6 oder 2046 da ich ganzzahlige werte bevorzuge.)
Hallo Henning,
irgendwie hab ich anscheinend auch nen Denkfehler.
Angenommen: Uref=5V
wenn ich mal ne kleine Verhältnisgleichung mache:
5V/1023 = spannungswert/ADCregister
wenn ich das umstelle nach spannungswert:
spannungswert=5V*ACDregister/1023
habe ich irgendwo einen denkfehler?
Habe sowas dieser Tage mit bascom gemacht.
Habe externe referenzspannung=5V und nen spannungsteiler 8,2k/1,2k am
Adc port um spannungen zwischen 0 und 30V zu messen.
also reale spannung am port beträgt demnach
adcvoltage = Adcvalue * 0.00488 'adcvalue ist wert vom adc
danach kannst du ja die berechnung in K vornehmen.
ich hab danach den spannungsteiler eingerechnet:
Voltage = adcvoltage / 0.1276 '( 1200/(8200+1200))
der simulator eignet sich prima um mit voher berechneten werten sie
genauigkeit und funktion zu testen... danach wandelst du deinen
berechneten wert mit str() in einen string und mit mid() kannst du
danach die kommastellen kürzen
"Habe externe referenzspannung=5V und nen spannungsteiler 8,2k/1,2k am
Adc port um spannungen zwischen 0 und 30V zu messen."
Das ist ja gerade mein Problem/Frage: Wenn meine Referenzspannung nicht
genau ist, messe ich sehr ungenau. Ich muß also eine sehr hochwertige
(genaue) Referenzspannung haben. Ändert sich meine Referenzspannung auf
Grund von Temperaturschwankungen, dann bedeutet ADC=512 bei -20 Grad
eine ganz andere Spannung als bei 95 Grad.
@Michael:
Ich weiß nicht, wie oft das hier schon diskutiert worden ist, aber es
ist immer noch 1 LSB = Vref / 1024 und nicht 1023! Also im obigen
Beispiel mit Vref = 5 V:
spannungswert = ADCregister * 5 V / 1024
@Bjoern:
> ...die ist eigentlich genau genug
Schau mal ins Datenblatt von nem AVR bei Electrical Characteristics, da
steht, dass Vref zwar typischerweise 2,56 V hat, aber auch minimal 2,3
und maximal 2,7 V haben kann. Das sind nach unten ~10% und nach oben
immerhin >5% Toleranz, die vom Hersteller eingeräumt werden. Und das
ist für gewisse Anwendungen sicher nicht mehr genau genug. Da gibts
externe Möglichkeiten, die signifikant bessere Genauigkeiten erzielen.
Die interne "Referenz" der AVRs ist blanke Verarschung. Wie man so
etwas "Referenz" nennen kann, ist mir ein Rätsel. Atmel hat im
Analog-Bereich echte Probleme. Das sieht man auch an der miesen
Performance des AD-Wandlers oder des Komparators.
Du kannst auch einen SMT160 Temperatursensor einsetzen (erzeugt PWM
Signal).
Dann sparst Du Dir die ganzen Fragen und Probleme.
Und einen Quarz als genauen Takt (= Referenz für PWM Zähler
Interrupt) hat man wohl i.d.R. sowieso am uP dran.
@johnny.m: sorry deine ausführung kann ich jetzt nicht nachvollziehen
mit der auflösung und lsb. wenn du 5v an den avr anlegst und referenz
auch 5v dann haste 1023 im ad register?!
in sonem komischen ami atmel forum stand immer durch 1023
Schon.
Aber mit der 0 hast du 1024 mögliche Ergebnisse vom ADC.
Sagen wir mal du hast einen 2 bit ADC
und 4V als Referenz (dann rechnet es sich leichter).
Mit 2 bit kannst du bis 3 zählen, hast aber 4 mögliche
Ergebnisse:
00
01
10
11
d.h. der Apsnnungsbereich 0 bis 4V teilt sich in 4
Bereiche auf:
00 0V - 1V
01 1V - 2V
10 2V - 3V
11 3V - 4V
ob du mit dem letzten Ergebnis (11) genau 4V hattest
oder nicht, kann niemand sagen. Das Ergebnis liegt
irgendwo im Bereich 3 bis 4 Volt. Und genau darum gehts:
Ein ADC kann dir nicht die exakte Spannung geben. Ein ADC
kann dir immer nur sagen: Die Spannung war in diesem
und jenem Bereich. Wo in diesem Bereich, mehr an der Unterkante
des Intervalls oder mehr an der Oberkante, entzieht sich unserer
Kenntnis. D.h. wenn du konsequent bist und bei einem ADC
Wert von 00 eine 0 ausgibst, dann musst du auch bei einem
ADC Wert von 11 eine 3 ausgeben, obwohl die Referenzspannung
4V beträgt und der ADC den grösstmöglichen Wert liefert.
Hallo,
meine lösung mit dem LM35:
interne Referenzspannung, macht bei 2,56V und 1024 Schritten
2,5mV/Schritt. Die oberen 8 Bit sind also 10mV -> 1 Grad-Schritte.
Ich lese mit gesetztem ADLAR-Bit, damit ist das High-Byte direkt die
Temperatur in Grad. Bit 7 ist 0,5 Grad, werte ich als Flag aus und
schreibe direkt 0 oder 5 in die Anzeige. Genauer ist der Kram sowieso
nicht.
Die Referenzspannung kann exemplarabhängig ziemlich abweichen,
2,4x..2,6xV (steht im Datenblatt). Ich habe kurzerhand eine
Korrekturrechnung eungebaut: Ref ausmessen und als 10mV-Faktor
interpretieren. 2,56V wäre dann 256, 2,63V eben 263.
In mul_16_3...mul_16_0 steht das Ergebnis von TEMP_B/TEMP_A *
TEMP_D/TEMP_C
Sieht dann so aus.
in TEMP_A,ADCL
in TEMP_B,ADCH
ldi TEMP_C,low(REFERENZ)
ldi TEMP_D,high(REFERENZ)
rcall mul_16 ; Korrektur rechnen
mov TEMP_A,mul_16_1 ; durch 256 dividieren
mov TEMP_B,mul_16_2 ; Wert kann nicht größer werden
ldi TEMP_C,0b01000000 ; unterstes ADC-Bit +1
add TEMP_A,TEMP_C
clr TEMP_C
adc TEMP_B,TEMP_C
sts TEMPERATUR,TEMP_B ; High-Byte in TEMPERATUR merken
sts TEMPERATUR+1,TEMP_A ; Low-Byte in TEMPERATUR merken
Die Addition von 1 ist eine Rundung, damit zeigt die Anzeige zwischen
z.B. 20,75 Grad und 21.25 Grad 21.0 Grad an und zwischen 21,25 Grad und
21,75 Grad 21,5 Grad an.
Eine Anzeige erfolgt bei mir nur in 0,5 Grad Schritten.
Gruß aus Berlin
Michael