Liebes Forum,
ich habe aus Interesse einmal den internen Temperatursensor im
ATmega168A ausprobiert. Ihn frage ich mit unten stehendem Code ab. Die
Routine startet den ADC, verwirft die erste Messung, misst dann 16 Mal
und mittelt das Ergebnis. Dann wird die Spannung umgerechnet in Grad
Celsius entsprechend dem Application Note von ATMEL.
Da auf meiner Platine der Pin AREF fest mit +3V3 verbunden ist, kann ich
leider nicht die interne 1,1V Referenz nehmen sondern muss die externen
3V3 nehmen. Das ist aber ok denke ich, denn die Genauigkeit ist ohnehin
nur mit +/- 10 Grad angegeben im Datenblatt, da kann ich auf gute
Auflösung verzichten. Nachgemessen habe ich Vref mit einem sehr guten
Multimeter: es sind schöne 3,303 Volt bei mir.
Jetzt messe ich aber einen Temperatur-Wert von etwa 57 Grad Celsius,
obwohl die Raumtemperatur nur 23 Grad beträgt. Eigenerwärmung kann
ausgeschlossen werden, denn auch wenn man sofort nach dem Einschalten
misst, werden 52...58 Grad ausgegeben (MCU konnte sich vorher lange auf
die Raumtemperatur einstellen).
Mit Eisspray kann ich vorsichtig auf bis zu -19 Grad abkühlen, mehr habe
ich noch nicht probiert da ich nichts kaputt machen will. Also
prinzipiell scheint der Sensor zu messen, nur halt extrem ungenau.
Ist der Temperatursensor wirklich so schlecht (= fast unbrauchbar?) oder
habe ich noch einen dusseligen Fehler in meinem Quellcode?
Welche Erfahrungen habt Ihr mit dem Sensor gemacht?
vielen Dank für alle Antworten!
Tobi
1
//configure ADC
2
ADMUX=0b00001000;//Vref=AREF=3.3V, select internal Temperature Sensor (= channel ADC8)
3
ADCSRA=0b10000101;//Switch ADC on, set prescaler to /32 (3,68 MHz/32 = 115 kHz)
4
ADCSRB=0b00000000;//no autotriggering used
5
6
//measure first time and discard result (see datasheet)
7
ADCSRA|=(1<<ADSC);//start single ADC conversion
8
while((ADCSRA&(1<<ADSC))!=0){};//wait until conversion is completed
9
10
11
//measure 16 times and average result
12
temperature=0;//temperature is a signed 16bit variable
13
for(temp_byte=0;temp_byte<16;temp_byte++)
14
{
15
ADCSRA|=(1<<ADSC);//start single ADC conversion
16
while((ADCSRA&(1<<ADSC))!=0){};//wait until conversion is completed
17
temperature+=ADC;//read 10 bit ADC result
18
}//for
19
temperature=(temperature>>4);//div16
20
temperature*=3;//weil 3,3V statt 1,1 Volt als Referenzspannung genommen werden muss (AREF ist im Layout an 3V3 angeschlossen)
21
temperature-=273;//Geradengleichung: Umrechnung von ADC-Counts in Temperatur [Celsius] , see ATMEL Application Notes
22
23
ADCSRA=0b00000101;//Switch ADC off --> reduces power consumption a little bit
> Jetzt messe ich aber einen Temperatur-Wert von etwa 57 Grad Celsius,> obwohl die Raumtemperatur nur 23 Grad beträgt.
Der Chip erwärmt sich nach meiner Erfahrung sehr schnell. Schreibe ein
Programm, das alle 30 s kurz misst, den Wert ausgibt und dann den Chip
sofort schlafen legt.
Guten Abend Achim,
vielen Dank für deine 3 Posts...
Ich habe jetzt folgenden Test gemacht:
Die Platine komplett spannungsfrei geschaltet, also somit gar keine
Eigenerwärmung möglich. Dann nach 30 Minuten manuell eingeschaltet. Der
MCU war so programmiert, dass er sofort eine Messung macht und ausgibt,
also binnen der ersten Sekunde nach Einschalten.
Ergebnis: 49 Grad Celsius.
Dann habe ich manuell per Terminalprogramm weiter abgefragt, nach
einigen Sekunden (etwa 10 Sekunden schätze ich) war dann keine Änderung
mehr sichtbar und der Endwert von 55 bis 58 Grad war erreicht.
Daraus schließe ich: der interne Sensor ist offensichtlich extrem
schlecht und ungenau und nicht wirklich brauchbar. Er zeigt also auch
nicht die Chiptemperatur vernünftig an.
Ich habe das Application Note von ATMEL gelesen und dort ist mir noch
etwas aufgefallen: die schreiben ja, dass man -273 Grad als Offset
abziehen muss bei der Umrechnung von ADC counts in Grad Celsius. Nimmt
man aber die Tabellenwerte des Temperatursensors aus dem Datenblatt und
rechnet manuell die Geradengleichung aus, so kommen da nur -267 Grad als
Offset heraus. Das bedeutet, dass die Formel im Application Note nicht
ganz zu der Kennlinie im Datenblatt passt. Schlimmer noch: dann würde
ich nochmal 6 Grad mehr messen als es ohnehin schon sind!
Fazit: eine nette Spielerei, aber für praktische Anwendungen
offensichtlich unbrauchbar.
viele Grüße,
Tobi
Tobias Krieger schrieb:> Fazit: eine nette Spielerei, aber für praktische Anwendungen> offensichtlich unbrauchbar.
nicht ganz, die 10 Grad Abweichung habe ich jetzt nicht nachgeschaut,
die läßt sich aber durch Kalibrieren beseitigen.
Durch deine Messung mit 3,3V verschlechterst du die Messgenauigkeit noch
mal deutlich, damit entspricht 1 Digit Abweichung schon Mal 3 Grad
Walter
Ich kann mich täuschen, aber in meiner Erinnerung steht im Datenblatt,
dass man 10 Grad Genauigkeit erreichen kann, wenn man Offset und
Steigung z.B. als Teil des Funktionstests bestimmt. Das heißt, du musst
jeden Chip einzeln kalibrieren. Zweipunktkalibrierung. Klar, das ist
ziemlich viel Aufwand für so eine bescheidene Genauigkeit. Ist halt eher
eine Spielerei...
Die individuelle Kalibrierung erfordert einen Temperaturschrank. Das ist
zeitaufwendig und somit teuer. Das lohnt vermutlich niemals. Da gibt es
so viele billige und gute Temperatursensoren (analoge und auch
digitale), teilweise für unter 50 Cent mit sehr guten Eigenschaften...
Ich hatte den internen Sensor eher zum Spaß einmal getestet und mich nur
gewundert über das schlechte Ergebnis. Ich würde so einem Teil auch
niemals so richtig trauen, wenn ich aufwendig kalibrieren muss....
@Walter: ja, Du hast Recht mit den 3 Grad Schritten bei 3V3 Referenz.
Das hatte ich ja oben schon angemerkt dass das nicht optimal ist, aber
bei +/- 10 Grad Genauigkeit ist es ja ziemlich sinnlos auf 1 Grad
aufzulösen, wenn man den Absolutwert haben will. An der Genauigkeit
ändert/verschlechtert die gröbere Auflösung aber nichts!