In diesem Beitrag wird die die Temperaturmessung mit dem Temperatursensor SMT 160-30 vorgestellt.
Wie bei allen Sensoren geht es darum, eine Temperatur in ein verwertbares elektrisches Signal umzusetzen. In der Technik sind verschiedene Möglichkeiten vorhanden. Passive Bauteile wie NTC- ode PTC-Widerstände benötigen noch zusätzliche Beschaltung und Kalibrierung. Desweiteren gibt es Sensoren wie den DHT-22, der Temperatur und Feuchtigkeit misst. Der SMT160 funktioniert als reiner Temperatursensor. Es handelt sich um einen smarten Sensor mit drei Anschlüssen, das Ausgangssignal ist fertig aufbereitet. Es kann dann ohne weitere Bearbeitung von einem Raspberry PI oder einem Microcontroller verarbeitet werden.
Übersicht
Der Smartec-Temperatursensor ist ein hochentwickelter Vollsilizium-Temperatursensor mit digitalem Ausgang.
Der Eindrahtausgang (Duty-Cycle-moduliert) kann ohne A/D-Wandlung direkt an alle Arten von Mikrocontrollern angeschlossen werden. Der Temperaturbereich liegt zwischen –45 °C und 150 °C. Durch die hohe Auflösung ist der Sensor auch für hochpräzise Anwendungen einsetzbar. Der Sensor ist in verschiedenen Gehäusen erhältlich. Die absolute Genauigkeit ist besser als 1,2 ° C. Im Bereich von -30 bis +100 °C ist die absolute Genauigkeit besser als 0,7 °C, während die Linearität des Modells im TO18-Gehäuse besser als 0,2 ° C ist. (nach Informationen des Herstellers)
Der Sensor
Die Arbeitsweise
Die Spannung am Output P1 des Sensors beträgt 5 Volt. Um den Eingang GPIO22 des RasPi zu schützen, wurde ein Spannungsteiler vorgeschaltet, der die Eingangsspannung auf ca. 3 Volt reduziert. Die Messung mit dem DSO138 zeigt das Ergebnis. Die PWM-modulierte Ausgangsspannung hat eine Grundfrequenz von ca. 3,5 kHz. Je nach Temperartur verbreitert oder verschmälert sich der DC. Bequemerweise zeigt uns das Oszilloskop den Duty-Cycle von 42,9 % direkt an.
Die Größe des Duty-Cycle (DC) ist ein Maß für die Temperatur und hat nach Datenblatt folgenden mathematischen Zusammenhang
DC = 0.320 + 0.0047 * t, t in [°C]
Bei Null Grad (t=0°C) würde DC = 0.32 oder 32% sein. Um die Temperatur aus dem gemessenen DC zu errechnen, müssen wir die Formel ein wenig umstellen.
t = (dc - 0.32) / 0.0047
Die auf dem Scope angezeigten Werte wurden also bei 23,2°C ermittelt. [= (0.429 - 0.32) / 0.0047]
Die Software-Umsetzung
PWM-Signale auszuwerten ist nicht ganz ohne! Meistens geschieht das über den Umweg der Analogumwandlung. Um zusätzlichen Schaltungsaufwand zu vermeiden, wird bei mir das Problem mit Software gelöst.
Dazu wird der Eingangspin in einer Schleife 100.000 mal abgefragt. Die Zeitdauer hierfür wird mit dem time()-Befehl ermittelt. Sie beträgt ca. 100-130 Millisekunden. Sie variert, da die CPU durch interne Threads unterschiedlich ausgelastet ist. In diesem Abfragezeitraum wird die Dauer des HIGH-Pegel = DutyCyle gezählt. Jeder breiter der DutyCyle, desto mehr Einsen werden gezählt.
Der Sensor liefert eine Duty-Cyle-modulierte Reckeckausgangsspannung von ca. 3,5 kHz. Nach t = 1/f dauert jede Periode ca. 29 Millisekunden. Die Zählung findet also über drei Sensor-Perioden statt. Setzt man die Anzahl der gezählten Einsen ins Verhältnis zum Gesamtzählzyklus, ergibt sich der DutyCyle.
Fazit
Das Verfahren ist relativ einfach, ist aber systembedingt immer fehlerhaftet. Zum einen werden für die 100000 Schleifendurchläufe immer unterschiedliche Zeiten benötigt. Zum anderen müsste die Anzahl der Schleifendurchläufe auf die Sensorfrequenz abgestimmt werden, um die Fehlerquote zu reduzieren.
Für Messungen vom Umgebungstemperaturen erzielt man aber brauchbare Lösungen, da sich bei meinen Tests die Fehler in Zehntelgrad-Bereich bewegen.
Das Programm
# Der SMART TEMPERATURE SENSOR SMT-160.
# ACHTUNG! der Signalausgang beträgt 5 Volt und muss für den RASPI
# über einen Spannungsteiler 1k/1,5K oder Level-Shifter angepasst werden.
# A. Neumann, 2012-05-27
import RPi.GPIO as GPIO
import time
# es werden Raspberry Pi Board Pin Nummern verwendet
GPIO.setmode(GPIO.BOARD)
# Pin festlegen
pin=15 # Pin Nummer 15 entspricht GPIO22
# SetUp des GPIO Kanals
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
#-- Temperatur ermitteln ----
#-- Rückgabewert: Temperatur in °C
#-- die Codezeile mit Zeitmessung und Print abschließend
#-- löschen oder auskommentieren
def readSMT(cycles=100000):
count=0
start = time.time() # Überwachungszeit starten
for i in range(cycles):
if (GPIO.input(pin)):
count+=1
else:
count+=0
end = time.time()
print("[INFO] Messdauer: {:.5f} Sekunden".format(end - start))
print("[INFO] Anzahl Zählzyklen: %8d, davon Einsen; %8d" % (cycles, count))
dc=count/float(cycles) # Pulszeit
temperatur=round( ((dc-0.32)/0.0047), 3)
return temperatur
#++++++++++++++++++++++++++++++++++
print("[INFO] Versuchsreihe mit verschiedenen Zählintervallen")
# --- DutyCyle empirisch ermitteln
# --- Temperatur berechnen nach Datenblatt
# D.C. = 0.320 + 0.00470*t D.C. = duty cycle, t = Temperatur in °C
# bei 0 °C ist D.C.= 0.320 or 32.0%
#
temp = readSMT(90000)
print("akt. Temperatur: %6.1f" % temp)
temp = readSMT(100000)
print("akt. Temperatur: %6.1f" % temp)
temp = readSMT(200000)
print("akt. Temperatur: %6.1f" % temp)