In Teil1 dieses Projektes haben wir dem Raspberry ein Betriebssystem verpasst und das ein wenig für die Anwendung aufbereitet. Wir wollen ja an den PI mehrere Sensoren anschließen und diese dann zyklisch auslesen und die Daten in einer Datei auf einem USB-Stick speichern. Die Aufzeichnung soll so lange laufen, bis ein Taster gedrückt wird, der den Prozess beendet. Die einzige Anzeige des PI sind zwei Leuchtdioden, die, sowie auch der Taster, an die GPIOs des PI angeschlossen sind. Darum haben wir folgende Punkte bereits erledigt:
- Die PI Platine gemeinsam mit einer USB Powerbank in ein Gehäuse eingebaut
- Anschlüsse wie Ethernet, USB, HDMI durch Ausschnitte im Gehäuse nach außen geführt
- Zwei Leuchtdioden und einen Taster ins Gehäuse eingebaut und auf die GPIOs geschaltet
- Den I²C Bus des PI auf eine Buchse im Gehäuse geführt
- Eine MicroSD Karte mit einem Raspi-Wheezy Image bespielt
- Einen USB-Stick mit FAT32 formatiert
- Das Betriebssystem soweit konfiguriert, dass das Filesystem für den Stick, alle Module für den I²C, sowie Python geladen werden.
Der Pi sieht fertig zusammengebaut nun so aus (siehe Bild rechts). Nun können die Sensoren angeschlossen werden. In diesem Fall handelt es sich um Luftfeuchtigkeits-/Temperatursensoren mit der Bezeichnung HYT939 des Herstellers Hygrochip. Hier ein Auszug der technischen Daten aus dem Datenblatt des Herstellers:
Ausführung: Feuchtesensor im TO39 Gehäuse, druckfest, mit Edelstahl-Sinterfilter
Genauigkeit: Feuchte ±1,8% rF, Temperatur ±0,2 °C
Genauigkeit 0…10% rF (0 … 50°C): ±(0,1% rF + 17% aw)
Messbereich: Feuchte 0 … 100% r.F. (max. dp = +80 °C), Temperatur – 40 … +125 °C
Abmessungen: 5,2 x 9 mm
Anschlüsse: TO 39 Footprint
Auflösung Feuchte: 0,02% rF
Hysterese bei 50% rF: < ±1% rF
Linearitätsfehler: < ±1% rF
Ansprechzeit t63: < 10 sec (Mit Edelstahl-Sinterfilter)
Auflösung Temperatur: 0,015 °C
Digitale Schnittstelle: I2C, Adresse 0x28 oder Alternativadresse
Betriebsspannung: 2,7 … 5,5 V
Stromaufnahme (typ): < 1µA in Bereitschaft < 22µA bei 1Hz Messrate 850 µA maximal
Eine kleine Platine dient als „Sensorboard“. Hier besteht die Möglichkeit, vier HYT´s anzustecken. Natürlich müssen auch die Adressen der Sensoren unterschliedlich sein. Der HYT939 ist per default auf hex 0x28 eingestellt. Will man diese Deviceadresse ändern, so muss der der HYT in den Command-Mode versetzt werden, um dann die Konfigurationsdaten empfangen und in sein EEprom schreiben zu können. Dazu muß der Sensor innerhalb der ersten 10ms nach seinem PowerUp in den Command-Mode gebootet werden. Das lässt sich am einfachsten mit einem ArduinoUno bewerkstelligen… Dabei wird der Powerpin des HYT über einen Digital Out Pin des Arduino versorgt. So ist es möglich, das Timing genau einzuhalten und den Command Mode zu erreichen.
Nachdem der Sensor nun an den Raspberry angeschlossen ist, fehlt nur mehr ein Programm, um ihn oder auch mehrere anzusteuern und auszulesen. Hier verwende ich den Python Interpreter. Damit lassen sich auf einfache Weise die Daten auslesen und auch auf Datenträgern speichern. Das „Programm“ besteht aus zwei Teilen:
- Hauptscript: beinhaltet nur eine Endlosschleife, die die LEDs steuert, den Taster abfragt, die Sensorfunktion aufruft, deren ausgelesene Werte übergibt, aufbereitet und auf den Stick speichert.
- Funktion Sensor auslesen: addressiert den I²C Bus, liest die Sensordaten aus, rechnet sie in lesbare Werte um und übergibt den Output an die Funktion
# /usr/bin/python # License: GPL 2.0 # edited by Ingmar B. Aug.2015 import os from time import * import time import threading import hyt939o import RPi.GPIO as GPIO # Setup LED Ports (pin12 = LED rot, pin18 = LED gruen) GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(12, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(16, GPIO.IN) # LED Gruen einschalten sobald das Script gestartet ist GPIO.output(18, GPIO.HIGH) #gpsd = None #seting the global variable address = [0x2a, 0x29] #hyt939 = [0, 0] hum = [0, 0] temphyt = [0, 0] loopon = True #set variable for loop i=1 #counter for address selection os.system('clear') #clear the terminal (optional) while loopon: # bei beginn des auslesens aller daten die rote Led einschalten GPIO.output(12, GPIO.HIGH) if GPIO.input(16)== GPIO.HIGH: loopon = False os.system('clear') # Variablen fuer Sensor HYT 939 uebergeben for i in range(2): hyt939=hyt939o.ReadMeasurement(address[i]) time.sleep(0.1) hum[i]=hyt939[0] temphyt[i]=hyt939[1] print '--------------------------------------- ' print 'SENSORS reading Sensor Nr.:' , i print print 'humidity hyt939 ' , hum[i] print 'temperature hyt939 ' , temphyt[i] print '--------------------------------------- ' print print 'data to write:' , str(hum[0]), str(temphyt[0]), str(hum[1]), str(temphyt[1]) print ("date :" + time.strftime("%x")) print ("time :" + time.strftime("%X")) print date = time.strftime("%x") zeit = time.strftime("%X") ## write all data to usbstick fileout = open("/media/usbstick/wetterfrosch.txt", "a") time.sleep(0.1) fileout.write(date+";"+zeit+";"+str(hum[0])+";"+str(temphyt[0])+";"+str(hum[1])+";"+str(temphyt[1])+"\n") time.sleep(0.1) fileout.close() time.sleep(0.1) # nach schreiben bzw auslesen der daten rote LED wieder abschalten GPIO.output(12, GPIO.LOW) time.sleep(0.8) #set to whatever GPIO.output(18, GPIO.LOW) # gruene Led ausschalten
print "Ende"
Das folgende Listing liest den Sensor aus:
# Reading mesaurements from HYT 939 humidity and temperature sensor
# First Version by Caerandir May 2014 modified by i.bihlo 2015
import smbus, time
bus = smbus.SMBus(1) # Raspberry Rev. 2
address = 0x28 # Fixed default address of HYT 939
# Initialize sensor to acquire measurements
def MeasurementRequest():
void = bus.write_quick(address)
time.sleep(0.1)
# Read Humidiy and Temperature to 14 bit accuracy
def ReadMeasurement():
void= bus.write_quick(address)
time.sleep(0.1)
# Acquire 4 byte from sensor
#time.sleep(0.1)
Readout = bus.read_i2c_block_data(address,0,4)
# Calculiere die relLF in % aus den vier Bytes in "Readout"
RelHum = Readout[0]<<8 | Readout[1]
RelHum = RelHum & 0x3FFF
RelativeHumidity = 100*RelHum/(2**14)
# Calculiere die Temperatur vom Sensor
Readout[3] = Readout[3] & 0x3F
temp = Readout[2]<<6 | Readout[3]
Temperature = 165.0*temp/(2**14)-40
print "Hrel: ", RelativeHumidity, " %"
print "T: ", Temperature, " C"
return RelativeHumidity, Temperature
MeasurementRequest()
time.sleep(0.2)
ReadMeasurement()
Eine Versuchsmessung über einen Tag und eine Nacht mit drei Sensoren hat folgendes Ergebnis geliefert. Hier sind die Temperaturwerte der Sensoren dargestellt. (Die Daten vom USB-Stick wurden mit Matlab importiert und daraus ein Plot erstellt.)
Hallo Ingmar,
danke für diesen interessanten Artikel – genau so etwas habe ich gesucht.
Waren die 3 Sensoren bei Deiner Versuchsmessung eigentlich am selben Ort angebracht? Die Streuung in dem Plot ist ja schon recht groß …
Gruß,
Matthias
Hallo Matthias,
ja die drei Sensoren waren direkt nebeneinander angeordnet. Die Platine mit den Sensoren lag dabei im Aussenbereich auf einer Fensterbank.
Genau die Streuung wollte ich (zwar sehr provisorisch) wissen. Einer der Sensoren war vorher eingelötet gewesen. Da wollte ich wissen, ob und welchen Einfluß die Lötdämpfe und Reinigungsmittel die evtl. durch das Sensorfenster eingetreten sind, haben. Und ob sich das Sensordielektrikum dann verwändert – und ja – tut es.
Die anderen beiden Sensoren waren neu aus der Verpackung. Aber wie gesagt, das ist nur eine sehr ungenaue Vergleichsmessung ohne Referenzdaten. Zeit Klimaschrank zu mieten, dauert leider immer etwas ….
Gruß Ingmar