ATtiny25-Thermometer

Elektronik-Labor   Projekte   AVR 



Der Tiny25 hat nicht nur einen AD-Wandler mit wahlweise externer und interner 1,1-V- oder 2,56-V-Referenz, sondern auch noch ein Thermometer an Board. Deshalb kann man mit diesem Chip ganz allein und ohne zusätzliche Hardware eine Temperaturmessung mit Ausgabe über die serielle Schnittstelle realisieren. Als Basis für den Versuch wurde die Platine zum Lernpaket Mikrocontroller verwendet. Ohne Änderungen kann das Programm LPmikroISP.exe zur Programmierung eingesetzt werden - wenn man die Fuses in Ruhe lässt! Der originale Chip arbeitet dann mit einem Takt von 1,0 MHz.

$regfile = "attiny25.dat"
$crystal = 1000000

Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
Start Adc

Ddrb.0 = 1 'Referenz-Pin low!
Portb.0 = 0

Bei den ersten Vorversuchen hatte ich Probleme, den AD-Wandler mit der internen Referenz von 1,1 V zu betreiben. Alle Messungen deuteten darauf hin, dass mit 5 V Referenz gearbeitet wurde. Als Lösung des Problems stellt sich heraus, dass der Referenz-Pin B.0 nicht auf einer Spannung liegen darf, die höher als 1,1 V ist. Das war aber im verwendeten Aufbau mit DTR =1 zur Stromversorgung gegeben. Also musste Port B.0 low geschaltet werden. Ich bin mit aber sicher, dass es da auch noch eine elegantere Lösung geben muss. Jedenfalls, so funktioniert es schon mal. Man hat damit eine Auflösung von ca. 1 mV, was etwa einem Grad des Temperatursensors entspricht.



Der Temperatursensor liegt am scheinbaren Kanal 15, den das Datenblatt als ADC4 bezeichnet. Die Auflösung ist mit etwa einem Grad relativ grob. Deshalb habe ich eine Mittelung durchgeführt. Es werden nun genau 91 Messungen aufaddiert. Genau 91, weil damit dann gerade 100 Schritte einem Grad entsprechen. Dann noch durch 10 geteilt und ein Offset abgezogen, fertig ist das Messergebnis mit einer Auflösung von 0,1 Grad. Der Kalibrierwert 2442 muss allerdings für jeden Chip individuell durch Vergleich mit einem genauen Thermometer bestimmt werden. Wenn der Tiny ein Grad zu viel zeigt, muss dieser Wert um 10 vergrößert werden. (Dank an Frank Steinberg für seine Korrektur der Umrechnung! Siehe auch: www.FrankSteinberg.de/4TAP.htm )


$regfile = "attiny25.dat"
$crystal = 1000000

Dim D As Word
Dim T As Word
Dim N As Byte
Dim S As String * 10

Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
Start Adc

Ddrb.0 = 1 'Referenz-Pin low!
Portb.0 = 0

Open "comb.1:9600,8,n,1,INVERTED" For Output As #1

Print #1 , "Temperatur"

Do
T = 0
For N = 1 To 91 ' oder besser 100? s.u. ...
D = Getadc(15)
T = T + D
Next N
T = T / 10
T = T - 2442 'Kalibrieren
S = Str(t)
S = Format(s , "00.0")
Print #1 , S
Waitms 1000
Loop

End

 Das fertige Messergebnis erscheint nun im Terminal. Man muss übrigens DTR und RTS einschalten, um den Controller mit Spannung zu versorgen.




Bei der Programmierung des ATtiny25 gab es zuerst vereinzelte Probleme. Ich bin daher einem Vorschlag von Ralf Beesner und dem Ansatz beim Pingpong-ISP-Programmer gefolgt und habe die 100-k-Widerstände zu MISO und SCL auf 10 k verkleinert. Die kleineren Widerstände liegen jetzt probeweise auf der Unterseite parallel. Anscheinend klappt es jetzt besser mit dem Tiny25.




Nachtrag von Rafl Beesner

Du hattest dich und die Leser gefragt, ob man den Workaround mit dem Pin PB0 umgehen kann. Kann man, wenn man das Register ADMUX direkt befummelt (siehe angehängten Quelltext für ATtiny 45). Ist in meiner ATtiny45- Datenblatt- Version unter Abschnitt 19.7.4 "ADC Multiplexer Selection Register" abgehandelt.

$regfile = "attiny45.dat"
$crystal = 1000000

Dim D As Word
Dim T As Word
Dim N As Byte
Dim S As String * 10

Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1

Admux.refs0 = 0
Admux.refs1 = 1
Admux.refs2 = 0

Start Adc

Ddrb = &B00000000
Portb = &B00011111


Open "comb.1:9600,8,n,1,INVERTED" For Output As #1

Print #1 , "Temperatur"

Do
T = 0
For N = 1 To 91
D = Getadc(15)
T = T + D
Next N
T = T / 10
T = T - 2442 'Kalibrieren
S = Str(t)
S = Format(s , "00.0")
Print #1 , S
Waitms 1000
Loop

End


Korrigierte Umrechnung, von Thomas Frey
Sie benutzen einen Umrechnungsfaktor 0.91, um die Temperatur in °C zu erhalten. Ich glaube, das beruht auf einer Fehlinterpretation des Datenblatts. Das Datenblatt von Atmel zum ATtiny25 ist im Bezug auf den Temperatursensor sehr knapp gehalten. Es gibt aber eine AppsNote (AVR122: Calibration of the tinyAVR internal temperature reference), die das Ganze etwas ausführlicher erklärt.
Dort steht gleich im allerersten Absatz: "The voltage has a linear relationship to temperature and the result has approximately a 1 LSB/°C correlation to temperature." Ein LSB entspricht also einem Grad Celsius.
Die Verwirrung stammt wahrscheinlich aus einer älteren Version des Datenblatts. Dort stand dass der Korrekturfakor k für die Offset-Kalibrierung sich errechnet aus: (1024*1,07mV/°C)/1.1V~1.0/°C. Es konnte der Eindruck entstehen, dass sich der ADC-Wert pro Grad um 1 Volt, nicht um 1 LSB ändert. Damit hätte dann der Faktor 0.91 (= 1/1.1) Sinn gehabt, weil die Referenz für den ADC nämlich 1,1 Volt ist.
Tatsächlich ergibt sich aber pro °C eine Änderung von 1,1 mV, somit ein LSB/°C.
Ich bin auf Ihre Seite gestossen, weil ich selber ein Aussenthermometer mit einem ATtiny gebaut habe. Kalibriert habe ich es bei Raumtemperatur (einfach nur den Offset eingestellt) und selbst bei den kürzlich aufgetretenen ~20°C war die Anzeige ziemlich genau.




Elektronik-Labor   Projekte   AVR