Allgemeine Informationen zum Basismodell

Inhalt:


Ein Basisartikel gibt einen allgemeinen Ueberblick:
Wetterstation Eigenbau PRIG [8'190 KB]

Literatur: https://pi-buch.info/

 


Benötigte Hardware:

- Raspberry Pi Modell 3
- RFID Starter Kit für den Raspberry Pi (z.B. von Wish für ca. Fr. 13.--)
- 2 Temperatur-/Feuchtigkeits-Sensoren DHT22 (z.B. von Wish für ca. Fr. 6.--)
- 1 Druck-/Temperatur-Sensor BMP280 von Bosch (z.B. vom Pi-Shop für ca. Fr. 15.--)
- 1 Gas-Sensor Figaro TGS2600 (z.B. vom Conrads für ca. Fr. 15.--)

Optionen:
- Touch Screen für den Raspberry Pi (z.B. vom Pi-Shop für ca. Fr. 60.--)
- ESP8266 WiFi-Module
- Lautsprecher für Alarm und Hintergrundmusik

Kontrolle der Version:
Am Terminal mit dem Command: pinout
.

Terminal command: pinout

Minimalkonfiguration

BMP280 und DHT22


Formatter auf Windows

Formatter


Operating System 'Stretch'


Auf einem PC (z,B. Windows) sollte zuerst die Speicherkarte (microSD) von guter Qualität gründlich gelöscht und mit dem neuesten Betriebssystem (zurzeit Stretch/11.2018) beschrieben werden.

Die Version Stretch 2018-11-13-raspbian-stretch bietet beim ersten Aufstarten komfortable Konfiguration inkl. Paketaktualisierung.

Empfohlen:
- Mit SDFormatter einen 32 GB MicroSD mit der Option FULL (OverWrite) löschen.
- Download des gezippten Betriebssystem Stretch 2018-11-13
. mit Win32 DiskImager beschreiben

Nun muss nur noch in der Raspi-Konfiguration VNC, SSH und I2C gesetzt werden

Tipp:
Für raspberripi' einen eigenen Namen (z. Bsp. 'Wetterstation') einsetzen.
Damit ist der Pi im Router leichter auffindbar, falls mehrere Pi's verwendet werden

DiskImager


Allgemeines

Allgemein wird durch einen Thread in der Informatik ein Ausführungsstrang oder eine Ausführungsreihenfolge in der Abarbeitung eines Programmes bezeichnet.

Der Vorteil von Threads gegenüber Prozessen besteht darin, dass sich die Threads eines Prozesses denselben Speicherbereich für globale Variablen teilen. Verändert ein Thread eine globale Variable, ist der neue Wert auch in dieser Variablen sofort für alle anderen Threads des Prozesses sichtbar. Weitere Vorteile sind, dass auf einem System mit mehreren CPU-Kernen, das Programm deutlich schneller ausgeführt werden kann, denn die Threads können von den Prozessen tatsächlich gleichzeitig ausgeführt werden. Zudem kann das Programm sowohl bei Single-Core als auch bei Multi-Core-Systemen immer ansprechbar bleiben. Ein Thread hat aber auch eigene lokale Variablen.

3 quasi-parallele Prozesse


In unserem Projekt verwenden wir in der Basisversion 4 Threads, die unabhängig voneinander unsere Sensoren abfragen. Dies macht neben den oben erwähnten Vorteilen das Programm übersichtlich.

4 Threads - Definition und Startbefehl


Die 4 Threads - mit 'scan1' bis 'scan4' bezeichnet - sind (optional) mit je 3 Variablen definiert:
- name (hier ein beliebiger Text)
- delay (Intervall der Abfrage)
- repeat (hier eine Zahl, die angibt wieviele Male der Prozess neu gestartet werden soll)
Diese Variablen (wie etwa 'name') sind lokal, also nur für den jeweiligen Thread zugewiesen. Sie können also mehrfach auch für die andern Threads verwendet werden.

task1 bis task4 verweisen auf die auszuführenden Programme.

Die Threads werden einzeln gestartet, werden voneinander unabhängig ausgeführt und können z.B. aufeinander warten. Ein einfaches Programm (task3) wird im folgenden weiter erläutert:


Beispiel Task 3

Loop für diverse Funktionen


Der Programmteil besteht aus einer Schlaufe (Loop), der 'repeat' mal im Sekundenbereich ausgeführt wird. Das Intervall 'delay3' wird vom Schieberegler 3 (slider) ausgelesen und bestimmt die Wartezeit 'time.sleep(delay3)'.

In der Basisversion wird lediglich das Display aufgefrischt (Datum/Zeit) und ein Co2-Alarm als Beispiel simuliert. Ausserdem blinkt eine blaue LED, die über den GPIO gesteuert wird.

Später kann beispielsweise eine Aufräumroutine für alte Wetterdaten angestossen werden.



Möglichkeiten des GPIO:
raspi-gpio help

Auslesen der GPIO-Belegung via Terminal:
gpio readall

GPIO readall


Luftfeuchtigkeit und Temperatur messen
Die Installation des von uns verwendeten Sensor DHT22 ist im folgenden Tutorial gut beschrieben:

https://tutorials-raspberrypi.de/raspberry-pi-luftfeuchtigkeit-temperatur-messen-dht11-dht22/

Wichtige Schritte:
Update Paketliste und Installation von weiteren Paketen via Terminal:

- sudo apt-get update
- sudo apt-get install build-essential python-dev python-openssl git

Nun kann die Bibliothek für die Sensoren geladen werden. Wir verwende hierfür eine vorgefertigte Bibliothek von Adafruit, welche verschiedene Sensoren unterstützt:

- git clone https://github.com/adafruit/Adafruit_Python_DHT.git && cd Adafruit_Python_DHT
- sudo python setup.py install

Dadurch wird eine Python Bibliothek angelegt, die wir einfach in unsere Projekte einbinden können.

Hat alles geklappt können wir bereits die Temperatur und Luftfeuchtigkeit auslesen. Am Einfachsten ist das erst einmal mit den Demofiles:

Wechseln in das Verzeichnis 'Adafruit:
cd
cd Adafruit_Python_DHT

- cd examples
- sudo ./AdafruitDHT.py 22 4

Der erste Parameter (11) gibt an, welcher Sensor benutzt wurde (22 für den DHT22) und der zweite, an welchem GPIO er angeschlossen ist (Nicht die Pin Nummer, sondern die GPIO Nummer). Das erzeugt eine Ausgabe wie folgende:

- sudo ./AdafruitDHT.py 22 4
Temp=24.0* Humidity=41.0%

Achtung:
Die Sensoren sind nur alle zwei Sekunden bereit. Achte also darauf nicht direkt jede Sekunde eine Abfrage zu starten.


Das Python-GPIO-Cheat-Sheet zur Information

# *******************************
# * RPi.GPIO Basics cheat sheet *
# *******************************
#
# NICHT als Programm laufen lassen
# es wird nicht funktionieren

# Import des GPIO-Moduls
import RPi.GPIO as GPIO

# Wahl der Nummerierung: BOARD oder BCM
# BCM fuer GPIO-Nummerierung:
GPIO.setmode(GPIO.BCM)
# BOARD fuer Stecherleisten-Pin-Nummerierung:
GPIO.setmode(GPIO.BOARD)

# Set up Port als normalen Input:
GPIO.setup(port_or_pin, GPIO.IN)
# Input mit Pull-Down-Widerstand:
GPIO.setup(port_or_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Input mit Pull-Up-Widerstand:
GPIO.setup(port_or_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Set up Port als normalen Output:
GPIO.setup(port_or_pin, GPIO.OUT)
# Output gleichzeitig initialisieren (1 or 0)
GPIO.setup(port_or_pin, GPIO.OUT, initial=1)

# Output setzen/ruecksetzen
# Output einschalten (1/GPIO.HIGH/True)
GPIO.output(port_or_pin, 1)
# Output ausschalten (0/GPIO.LOW/False)
GPIO.output(port_or_pin, 0)

# Status von Input oder Output lesen
i = GPIO.input(port_or_pin)
if GPIO.input(port_or_pin):

# Cleanup (alle Pins wieder auf Input)
GPIO.cleanup()

# Raspberry Pi Boardversion
GPIO.RPI_REVISION
# 0 = Compute Module, 1 = Rev 1, 2 = Rev 2, 3 = Model B+

# Version des RPi.GPIO-MOduls
GPIO.VERSION

Weitere Dokumentation finden Sie unter

sourceforge.net/p/raspberry-gpio-python/wiki/Home/
https://pypi.python.org/pypi/RPIO
Interrupt-Verarbeitung mit Python

Testen des Sensors DHT22


Einbinden in unseres Projekt:


import Adafruit_DHT
...
sensor = Adafruit_DHT.DHT11
pin = 4
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)

Siehe dazu das Script 'Wetterstation'

GPIO Layout

Mein Brettaufbau


Allgemeines über I2C

Viele RasPi-Projekte nutzen zur Kommunikation mit Aktoren oder Sensoren die GPIO-Schnittstelle. Doch diese ist in ihren Möglichkeiten limitiert. Mit dem I2C-Bus steht als Alternative ein industriell standardisierter Datenbus zur Verfügung, der sich mit den richtigen Tools leicht in eigene Projekte einbinden lässt.

Beim I2C-Bus – man spricht das I-Quadrat-C aus – handelt es sich um einen seriellen Master-Slave-Bus, der sich für die Kommunikation über kurze Distanzen eignet, also hauptsächlich innerhalb von Platinen oder Geräten. Die Technik stammt aus den frühen 1980er-Jahren und wurde ursprünglich von Philips (heute NXP Semiconductors) für den Einsatz in der Unterhaltungselektronik entwickelt.

Die Datenübertragung erfolgt synchron über 2 Leitungen: eine Datenleitung (SDA) und eine Taktleitung (SCL). Beide Leitungen ziehen Pullup-Widerstände auf ein positives Potenzial. Ein Bus-Master gibt Takt und Betriebsmodus vor und initiiert die byteweise erfolgende Kommunikation. Die Übertragungsgeschwindigkeit des Busses beträgt zwischen 100 kbit/s bidirektional im Standard-Mode und bis zu 5 MBit/s unidirektional im Ultra-Fast-Mode.
(unbenannt)

Wir benutzen den I2C-Bus zur Uebertrabung des Sensors BMP280

Installation des Sensors BMP280
Bevor die Stifte an die Platine angelötet werden, sollten sie sauber verzinnt werden.



Software
Installation:
https://tutorials-raspberrypi.de/raspberry-pi-und-i2c-luftdrucksensor-bmp180/
.......

Aktivierung des I2C-Bus
dd- Start - Einstellungen - Raspberry Pi Konfiguration
Unter Schnittstellen I2C aktivieren.

Für unser Projekt verwenden wir einen geeigneten Sensor für 'frische Luft'

FIGARO Gas-Sensor TGS2600
• Halbleiter mit niedrigem Verbrauch
• geeignet für Lüftungskontrolle und Kontrolle der Umgebungsluft
• hohe Empfindlichkeit auf Luftverschmutzung (H2, Co, Alkohol)
• Metallgehäuse
• detektiertes Gas: CO, H
• Heizstrom: 42 mA
• Heizwiderstand: 83 O @ 25°C
• Leistungsverbrauch Heizung: 210 mW

Widerstand in Luft: 10 kΩ ~ 90 kΩ
bei 20 Grad und 85 % rel. Feuchtigkeit

Beachte:
- Der Sensor muss erst einige Minuten aufgeheizt werden, bevor die Werte stimmen
- Der Sensor reagiert auf Deo-Spray (Test)
- Frische Luft (Spiez) ist Level 3


Datenblatt

Gas-Sensor Figaro


Der Gas-Sensor mit seiner Heizung wird bei 3.3 Volt betrieben. Diese Spannung liefert ein kleines Speisegerät, das den Strom über ein freies USB-Port des Pi bezieht. Damit wird das GPIO weniger belastet.

Ein Lautsprecher ertönt bei Gasalarm.
Ein mp3-File wird durch den Mixer im Pi für 30 Sekunden abgespielt.

Brettaufbau

links der Gas-Sensor

'Frische Luft'

Die Resuktate der Gas.Messung sind im Panel integriert

Anschluss des Sensors


Aus der -logarithmischen- Kurve sollen Kriterien für die Luftqualität bestimmt werden.
Dazu benötigen wir einen Analog/Digital-Wandler (ADC). In unserem Projekt wird dieser Wandler vorwiegend mit Software realisiert, indem wir mittels eines Widerstands-Netzwerks den 'Threshold'- Punkt des GPIO-Kanals (GPIO 25) bestimmen.

Zuerst müssen wir den Sensor kalibrieren:
Bei offenem Fenster und 'Spiezer Luft' wird die Kalibrierung bei dem vorgegebenen Widerstands-Netzwerk auf Level 2 oder 3 erfolgen.

Falls die Kalibrierung nicht auf 2 oder 3erfolgen kann, muss der Widerstand TL reduziert werden, z.Bsp. auf ca. 15 kOhm

Kalibriert an gute Luft

3 bei offenem Fenster

Kalibrierung

Variable i gibt den Level an


Für Langzeitmessungen werden die Index-Werte wie gehabt in einen Speicher geschrieben und bei Bedarf 'geplottet'


Anlegen/Löschen eines Ordners auf dem Raspberry Pi

cd
(Gehe in die Ausgangsstellung Verzeichnis)
cd /home (Wechsle in das Verzeichnis „home“)
sudo mkdir PRIG (Anlegen des Ordners „PRIG“)
ls (Kontrolle durch den Befehl „List“ )

anschliessend Berechtigung Schreiben/Lesen erteilen:

sudo chmod 777 /home/PRIG

Damit können wir das Script unseres Projektes in einem eigenen Ordner bearbeiten und starten

Laden des Programms 'Pandas' im Terminal (Plot)
sudo apt-get install python-pandas

Laden von einigen Paketen (via Terminal)
sudo apt-get update
sudo apt-get install build-essential python-dev python-openssl git

Laden von Adafruit (via Terminal)
git clone https://github.com/adafruit/Adafruit_Python_DHT.git && cd Adafruit_Python_DHT
sudo python setup.py install

Optionen für Matplotlib:
https://www.grund-wissen.de/informatik/python/scipy/matplotlib.html


Download des Programms 'Wetterstation'
1 Im Raspberry Pi einen Browser öffnen und diese Website (http://prig.ch/workshops/2019-2020/vorbereitung/index.htm) öffnen.
2 Das Programm 'xxxxx.py' downloaden.
3 Mit Copy/Paste das Programm 'Wetterstation' in den neu erstellten Ordner 'PRIG' kopieren
4 Das Programm 'Wetterstation' mit Geany laden (rechte Maustaste)
6 Das Programm 'Wetterstation' mit F5 starten

Anmerkung:
Im Programm-Ordner kann ein gif-Bild mit dem Namen 'muster.gif' liegen. Im Programm müssen diesbezüglich einige Zeilen geändert werden.





Start der Wetterstation 'wetter1' via Terminal


'Tkinter' ist das Standard Graphical User Interface (GUI) von Python. Daneben gibt es noch weitere Variationen.

Tkinter bietet 3 verschiedene Arten der Darstellung, die nicht vermischt werden dürfen:
.grid
.pack
.place

Wir verwenden die Grid-Methode.
Die einzelnen Elemente wie 'slides', 'buttons', 'labels' (auch 'Widgets' genannt) werden in einem x/y-Gitter dargestellt (row/column). Jedes Element hat diverse Optionen. Beispielsweise definieren 'padx' und 'pady' den Abstand zu den Nachbargitterlinien. 'sticky' positioniert das Widget in 8 Himmelsrichtungen (sticky ="NW" positioniert somit das Element in die linke, obere Ecke).

Das Gitternetz wird als 'Frame' bezeichnet. Ein oder mehrere Frames werden in einem Fenster (window) plaziert. In unserem Fall definieren wir das Fenster in etwa der Grösse eines kleineren Tablets:

root.geometry('850x540+0+0') # size and position

Das Fenster ('window') ist also 850 mal 540 Punkte gross und wird wegen den folgenden Nullern in die linke, obere Ecke des Displays plaziert.

Nun wird das oder die Frames ins Fenster plaziert, in unserem Fall sind dies 2 Hauptframes: links und rechts ein grösseres:

leftFrame = Frame(root, width=200, height = 80)
leftFrame.grid(row=0, column=0, padx=15, pady=3, sticky=W)


Das linke Frame ist also nur 80 Eimheiten bret und wird mit Abstand von 15 nach links plaziert. Der Abstand an den oberen Rand beträgt 3. Das Ganze wird mit 'sticky=NW' an die linke, obere Ecke angeschlossen.

Analog wird das rechte Frame definiert.
Im rechten Frame ist noch ein 'Unterframe'
buttonFrame = Frame(rightFrame)
buttonFrame.grid(row=15, column=0, padx=10, pady=3, sticky=W)
definiert, damit mehrere Buttons in einem Rechteck nebeneinander angeordnet werden können.


Elemente (Widgets)
In unserem Projekt verwenden wir in der Basisversion:
- Labels (für Texte und Bilder)
- Buttons
- Sliders (Schieberegler)
- Eingabefelder

Eine kurze Erläuterung über die Buttons zum Verständnis des Interface zum Program.

Buttons:
bbbbbbbbbbbbbb

Definition:


Definition Button


Dem Button hinterlegtes Script:
In diesem Beispiel wird nur die Bezeichnung 'ON' in 'OFF' und umgekehrt gewechselt.
Auch andere Optionen wie etwa die Farbe können geändert werden.

Textwechsel


Es gibt 2 Möglichkeiten zum Ausdrucken von Wetterdaten:

a) durch einen externen Server
Vorteil ist, dass kein interner Speicher benötigt wird. Dafür sind die Abläufe etwas umständlicher

ThingSpeak

b) Plotten mit dem Rechner
In unserem Projekt verwenden wir das Softwarepaket 'matplotlib', das eine Fülle von Funktionen bietet.

- Temperatur
Mehrere Plots in einer Grafik.
Indiesem Beispiel die Innentemperatur der Sensoren BMP280 und DHT22

- Luftdruck
Eine Grafik mit y-Achse 'Luftdruck' und der x-Achse 'Zeit'

- Aussen
Plots zum gleichen Thema 'Aussenklima' in Verschiedenen Subplots wie in unserem Projekt Temperatur und Luftfeuchtigkeit

- Innen
analog wie 'Aussen'

- animierte Plots
nicht realisiert, da die relativ langen Intervalle wenig Effekte zeigen.

Uebersicht Wetterstation (Basismodell)

Beispiel Plot 'Aussenbereich'

Plot aller 3 Temperatursensoren

Automatische Lüftung je nach Temperatur und Zeit

Luftdruckmessung mit dem Sensor BMP280 von Bosch
Der Sensor misst den absoluten Luftdruck mit einer Genauigkeit von +/- 1 hPa. Die Luftdruck- und Temperaturdaten sowie die Kompensionsdaten werden im Burst-Mode ausgelesen und daraus der absolute Luftdruck auf Stationshöhe (QFE) kalkuliert. Um vergleichbare Messwerte zu erhalten, wird anschliessend der relative Luftdruck (QFF), basierend auf Normal-Null (NN) berechnet.

Ich vergleiche mit den Messwerten von MeteoSchweiz.
Den absoluten Wert QFE muss mit einer möglichst nahen Station auf gleicher Höhe sein, hier Fribourg.
Der daraus berechnete Wert QFF vergleiche ich mit dem Wert vom nahe gelegenen Thun

Fazit:
Die absoluten und relativen Messwerte meiner Station stimmen sehr gut mit denjenigen von MeteoSchweiz überein. Der Unterschied liegt im Bereich der angegebenen Toleranz des BMP280 von +/- 1 hPa. Das heisst, dass der Sensor genau misst und die Berechnung der Kompensation richtig ist,


Anmerkung:
Nach etwa 5 Wochen (am 13.4.19) verabschiedete sich der BMP280 still und wurde ersetzt. Der neue Lzftdruckmesser liegt nun nur noch 1 hPa über dem Wert von 'ThunWettwer', also innerhalb der Toleranz.

Vergleich QFF mit Meteo Schweiz


Temperaturmessung
Die beiden Sensoren DHT22 zeigen -am gleichen Ort gemessen- exakt dieselben Werte an.

Der Sensor BMP280 zeigt demgegenüber -kompensiert- etwas höhere Werte an (siehe Plot der beiden Temperatur-Sensoren)





Vergleich QFE mit Meteo Schweiz

Vergleich Temperatur-Sensoren


Gasmessung
Die Kalibrierung wurde getestet:
Index 3: sehr gute Luft (gut gelüftet)
Index 4: normale Luftqualität bei geschlossenen Fenstern
Index 6: simuliertes Gas mit einem Deospray (kurz gesprayt)






Luftqualität


Luftdruckmessung
Die Genauugkeit wurde mit verschiedenen Stationen von MeteoSchweiz verglichen und kann sich sehen lassen.






Luftdruck


Mobilbetrieb
Testen 'frische Luft' zu Level 2 auf der Terrasse. Speisung mitteks Power Bank

Wetterstation 'mobil'


Web Uhr/Wecker
Lautsprecher muss an der Basisstation angeschlossen werden

Web Uhr/Wecker


Reboot-Prozess
Für einen automatischen Neustart des Programms muss zuerst die grafische Oberfläche des Pi bereit sein ....


https://learn.sparkfun.com/tutorials/how-to-run-a-raspberry-pi-program-on-startupThe three methods covered in this tutorial are:

rc.local - Likely the easiest and simplest way to get your program to run on boot. The downside is that tasks started with rc.local happen before the X windows system starts, which means you will not have access to graphical user interface (GUI) elements.
autostart - Used to automatically run your programs once LXDE (graphical desktop environment used by Raspbian) starts. It's slightly more complicated than rc.local, but it lets you run programs that require graphical elements.
systemd - The new and popular way to automatically start programs in Linux. It is definitely the most complicated of the three, but it allows you to run before LXDE starts, wait until you have access to other processes (e.g. networking, graphical desktop), or simply restart your program over and over again until it works. As such, it is a robust way to create and manage services that run in the background.

Startup process

https://opensource.com/article/17/2/linux-boot-and-startup

Admin