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