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
Du kannst doch den Meßwert im Programm mit einem Faktor multiplizieren, um eine "reale" Anzeige zu bekommen. Black Fist
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.)
der umrechnungsfaktor war auf referenzspannung 5v bezogen und sollte natürlich geteilt durch heißen! => spannung=getadc(0) / 204
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?
nee, das stimmt so: spannungswert=5V*ACDregister/1023 gruss michael
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.
Hallo! Falls es sich um einen AVR µC handelt, warum nuzt Du nicht die interne Referenzspannnung, die ist eigentlich genau genug. mfg, Bjoern
@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.
Wenns um die Auswahl des Sensors geht, dann kann man auch gleich nen DS18S20 nehmen. Der liefert den Wert über 1-Wire direkt...
@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.
ach verdammt hast ja recht... schäm der typische fehler... ;) habe die 0 als möglichen zustand missachtet...
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.