Temperaturmessung ohne externe Hardware           

von  Thomas Baum                      
Elektronik-Labor  Projekte   AVR   T13-Contest


Manchmal schaut der ATiny13 etwas neidvoll auf seine größeren Brüder ATtiny 24 oder 25, denn die haben einen internen Temperatursensor. Ach was gäbe es da schöne Spielereien wenn der das auch könnte. Klar man könnte einen Sensor anbauen. Einen externen Sensor anschließen, der dann fast so groß ist wie der Controller? Das hört sich an wie Fahrradfahren mit Stützrädern. Sicher und stabil aber uncool. Da muss doch irgendwas zu machen sein.



Auf der Suche nach einer temperaturabhängigen Eigenschaft des ATtiny wird man im Datenblatt schnell fündig. Der interne Oszillator ist nicht temperaturstabil. Ein Schwachpunkt der jetzt zum Feature werden könnte. Abbildung 19-59 auf Seite 154 zeigt einen fast linearen Verlauf. Mit steigender Temperatur steigt auch die Frequenz des 9,6 MHz Oszillators. Bestens geeignet um Temperaturen zu messen. Einfach über eine bestimmte Zeit CPU_Takte zählen und umrechnen.  



Doch das nützt alles nichts wenn wir zum Zählen keinen festen Bezugspunkt bzw. keine feste Zeitbasis haben. Externe Bauelemente ausgeschlossen! Doch es gibt ja noch einen 2. Oszillator, den  128 kHz Oszi vom Watchdog. Jetzt würde man meinen, dass uns das auch nicht hilft, weil dieser wohl ein ähnliches Verhalten bei Temperaturänderungen zeigt wie der 9,6 MHz Oszi. Doch ein Blick ins Datenblatt bringt die Überraschung. Abbildung 19-66 auf Seite 157 zeigt einen temperaturabhängigen Verlauf mit genau gegensätzlichem Verhalten. Mit steigender Temperatur wird der Oszillator langsamer. Perfekt!

Als Zeitbasis dient also der Watchdog. Damit haben wir ein schönes Delta, das bei steigender Temperatur durch den 128 kHz Oszi noch verstärkt wird.

Das folgende einfache Demo zeigt eine temperaturgesteuerte LED, die bei Zimmertemperatur ausgeschaltet ist. Sobald eine gewisse Schwelltemperatur nach oben oder unten erreicht ist, schaltet sich die LED ein.

Verwendete Hardware:
    * Attiny13a
    * LED + Vorwiderstand

Messeigenschaften:
    * Fuse 6AFF (9,6 MHZ / 8)
    * Watchdogtimer 2048 Zyklen
    * Taktzähler (alle 4 Takte mit 16 Bit Zähler)

Beschaltung Attiny13a:

       ____
      -|  |-  VCC (3Volt)
      -|  |-
      -|  |-        ___
  GND -|__|---|<|--|_R_|--- VCC


Ein Video zum Temperatursensor in Aktion: http://youtu.be/NppARTy1Ga8
     
Download:  Temp.zip

.device ATtiny13A            ;Fuse 6AFF

.equ  LED = 0                      ;Pinbelegung

.org 0x0000
        rjmp    init

.org WDTaddr
     
rjmp watchdog          ;Händler für den Messzyklus

init: sbi   DDRB, LED         ;LED als Output
main:
      rcall get_temperature         ;Messwert r23
      cpi   r23, 0x28
      brlo  led_on
      cpi   r23, 0x30
      brsh  led_on
      sbi   PORTB, LED
      rjmp  main 
led_on:     cbi   PORTB, LED
      rjmp  main

get_temperature:
      ldi   r26, 0x00         ;16 bit für Taktzähler r26+r27
      ldi   r27, 0x00
      ldi   r30, 0x00         ;Indikator Watchdog

     
cli                     ;WatchdogTimer Initialisierung
      wdr
      ldi r16, (1<<WDCE) | (1<<WDE)
     
out WDTCR, r16
      ldi r16, 0x03;    parameter 03
      ori r16, (0<<WDCE) | (0<<WDE) | (1<<WDTIE)
      out WDTCR, r16
      sei
measure:
     
adiw  r26, 0x01         ;Zähler ++
      cpi   r30, 0xFF         ;ist Watchdog abgelaufen?
      breq  normalize         ;wenn ja dann normalisiere
      rjmp  measure           ;sonst weiterzählen
normalize:                    ;Normierung
     
ldi   r16, 0x00         ;Dummy für Carrybit         
      lsl   r26              
      rol   r27              
      adc   r26, r16          ;16-Bit Rotation
      ldi   r16, 0x00         ;Dummy für Carrybit         
      lsl   r26              
      rol   r27              
      adc   r26, r16          ;16-Bit Rotation

     
andi  r27, 0x3F         ;Wertebeschränkung
      mov   r23, r27          ;Messwert in r23 bereitstellen
     
ret

watchdog:                    ;Watchdoghändler
      ldi   r30, 0xFF         ;Indikator
     
cli                     ;Watchdog deaktivieren
      wdr
      in    r16, MCUSR
     
andi  r16, (0xFF - (1<<WDRF))
      out   MCUSR, r16
      in    r16, WDTCR
      ori   r16, (1<<WDCE) | (1<<WDE)
      out   WDTCR, r16
      ldi   r16, (0<<WDE)
      out   WDTCR, r16
     
sei
      reti
 

 



Elektronik-Labor  Projekte   AVR   T13-Contest