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
|