Gartenhäuschen mit Micro Controller und Sensoren überwachen - Teil 2
Im ersten Teil habe ich beschrieben, wie der D1 Mini (ESP8266) mit Temperatursensor DHT22 und Gassensor MQ-2 als Web Server Messwerte aus unserem Gartenhäuschen ins heimische WLAN sendet.

Diese Werte werden im Browser auf dem PC oder dem Smartphone (siehe Bild) angezeigt, wenn man die IP-Adresse des Web Servers (hier: http://192.168.178.100) in die Adresszeile eingibt.

Der Webserver ist so programmiert, dass er bei Überschreiten einer Temperatur von 50°C oder einer Gaskonzentration von 100 das Wort „Alarm“ ausgibt. Aber man muss schon aktiv auf der entsprechenden Seite nachsehen, um alles angezeigt zu bekommen. Das hat mir nicht gereicht, ich wollte auch mit einem akustischen und optischen Signal benachrichtigt werden. Also musste ich die Webseite mit einem Micro Controller oder Micro Computer auswerten, die Messwerte herausfiltern und ggf. den Alarm mit Buzzer und LED auslösen.

Benötigte Hardware für den ersten Teil

1

D1 Mini NodeMcu mit ESP8266-12F WLAN Modul

optional

Batterie Shield für Lithium Batterien für D1 Mini

optional

Lithium Batterie 3,7V 

1

DHT22 AM2302 Temperatursensor und Luftfeuchtigkeitssensor

1

MQ-2 Gas Sensor Rauch Sensor Luftqualität Modul

Mini Breadboard, Jumperkabel


Benötigte Hardware für den zweiten Teil

1

Raspberry Pi 3B, 4B oder Zero W (WLAN-fähig)

1

1,3 Zoll OLED I2C 128 x 64 Pixel Display

Mini Breadboard, Jumperkabel

Aktiver Buzzer

rote LED mit Vorwiderstand 200 bis 330 Ohm


Naheliegend ist die Benutzung eines Micro Controllers, da der nach dem Einschalten „auf Fingerschnipp“ funktioniert. Aber es wollte mir nicht auf Anhieb gelingen, mein D1 Board für die Abfrage zu nutzen. Erst nach der Hilfe eines Blogger-Kollegen habe ich es geschafft. Deshalb stelle ich zunächst die (für mich) schnellere Lösung mit dem Raspberry Pi vor und verschiebe den Sketch für das D1 Board als Web Client auf den dritten Teil der Blog-Serie.

Das Auslesen einer textbasierten Webseite habe ich im Zusammenhang mit dem Download von Treibern und Programmbibliotheken schon häufiger vorgenommen. Mit curl ( „Client for URLs“ ist ein Kommandozeilen-Werkzeug zum Herunter- oder Hochladen von Dateien über eine Internetadresse) kann ich im Terminal den kompletten HTML-Text von dem ESP Web Server mit der IP-Adresse 192.168.178.100 herunterladen. (Die entsprechende Zeile im Programm mit der IP-Adresse müssen Sie selbstverständlich für Ihren Web Server anpassen).

Nach vielen Zeilen mit Formatierungen finden wir ganz am Ende die gesuchten Messwerte für Temperatur, Rel. Luftfeuchtigkeit (engl. Humidity) vom DHT22 und für die Gaskonzentration vom MQ-2.

Mit der Umleitung >text.txt speichere ich den gesamten Text für die weitere Bearbeitung in einer Datei.

 curl 192.168.178.100 >text.txt

Für das Herausfiltern der Messwerte, Überprüfung der Überschreitung von Grenzwerten und ggf. der Auslösung des Alarm benutze ich ein selbstentwickeltes Python-Programm. Für die Ausführung des eben genannten Terminal-Befehls wird das Programm-Modul os benötigt, also

 import os

und dann

 os.system('curl 192.168.178.100 >text.txt')

Um den abgespeicherten Text der Webseite einer Variablen zuzuordnen, werden folgende Befehle benötigt:

 f=open("text.txt","r")
 daten = f.read()
 f.close

Mit den String-Methoden find(), slicing[from:to], split() und strip() werden schließlich die Messwerte herausgefiltert.

Hier das Python-Programm mit Web Client und Alarm (Download):

 import os
 import time
 import RPi.GPIO as GPIO
 
 buzzer=21
 GPIO.setwarnings(False)
 GPIO.setmode(GPIO.BCM)
 GPIO.setup(buzzer,GPIO.OUT)
 
 def alarm():
     print("Alarm")
     for i in range(2):
         GPIO.output(buzzer,True)
         time.sleep(0.2)
         GPIO.output(buzzer,False)
         time.sleep(0.1)
         GPIO.output(buzzer,True)
         time.sleep(0.2)
         GPIO.output(buzzer,False)
         time.sleep(1)
         
 while True:
     try:
         os.system('curl 192.168.178.100 >text.txt')
         f=open("text.txt","r")
         daten = f.read()
         f.close
         #print(daten)
         print()
         index=daten.find("Temperature")
         #print(index)
         daten1=daten[index:-23]
         print(daten1)
         werte=daten1.split(":")
         print(werte)
         t=float(werte[1][0:6].strip())
         print("t = ",t," °C")
         h=int(werte[2][1:3])
         print("h = ",h," %")
         g=int(werte[3][1:4])
         print("g = ",g," ppm")
         if (t>25.0 or g>100):
             alarm()        
         time.sleep(1)
 
     except:
         time.sleep(10)

Die Ausgabe der Daten erfolgt in der Python-Shell, bei Überschreiten der Grenzwerte werden Buzzer und LED an GPIO21 aktiviert.

Um den Raspi im „Headless Mode“, also ohne Tastatur und Monitor zu betreiben, macht es Sinn, ein kleines OLED-Display für die Datenausgabe in die Anordnung zu integrieren. Das 1,3 Zoll OLED I2C 128 x 64 Pixel Display begnügt sich mit vier Anschlüssen für 3,3V (Pin 1) und GND (Pin 9) sowie SDA (Pin 3) und SCL (Pin 5). Dafür habe ich die Programm-Bibliothek luma.core von RM Hull von github heruntergeladen.
Wenn Ihr Raspberry Pi OS nicht auf dem neuesten Stand ist, sind ggf. folgende Befehle notwendig:

  $ sudo usermod -a -G i2c,spi,gpio pi
  $ sudo apt install python3-dev python3-pip libfreetype6-dev libjpeg-dev build-essential
  $ sudo apt install libsdl-dev libportmidi-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-image1.2-dev

Das Klonen des Repository erfolgt mit:

   $ git clone https://github.com/rm-hull/luma.examples.git
   $ cd luma.examples
   $ sudo -H pip install -e .

In dem Verzeichnis oled mit seinen weiteren Unterverzeichnissen haben wir zunächst keine Schreibrechte. Aufgrund der internen Abhängigkeiten zu dem Programm-Modul demo_opts.py und dem Unterverzeichnis fonts macht es jedoch Sinn, unser Programm ebenfalls in das Unterverzeichnis examples zu schreiben. Wir holen uns die Schreibrechte mit:

 sudo chmod 777 -c -R /home/pi/oled
Bitte vergessen Sie nicht, in der Raspberry Pi – Konfiguration auf der Registerkarte Schnittstellen sowohl SSH als auch I2C zu aktivieren.

Hier das Schaltbild:

und das vollständige Python-Programm, das Teile des luma.core-Beispiels terminal.py verwendet: (Download)

 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # Web Client to read environmental data
 # By Bernd Albrecht for AZ-Delivery
 #
 # luma.core: Copyright (c) 2014-2020 Richard Hull and contributors
 # See LICENSE.rst for details.
 
 import os
 import time
 from pathlib import Path
 from demo_opts import get_device
 from luma.core.virtual import terminal
 from PIL import ImageFont
 import RPi.GPIO as GPIO
 
 buzzer=21
 GPIO.setwarnings(False)
 GPIO.setmode(GPIO.BCM)
 GPIO.setup(buzzer,GPIO.OUT)
 
 def make_font(name, size):
     font_path = str(Path(__file__).resolve().parent.joinpath('fonts', name))
     return ImageFont.truetype(font_path, size)
 
 def alarm():
     print("Alarm")
     for i in range(2):
         GPIO.output(buzzer,True)
         time.sleep(0.2)
         GPIO.output(buzzer,False)
         time.sleep(0.1)
         GPIO.output(buzzer,True)
         time.sleep(0.2)
         GPIO.output(buzzer,False)
         time.sleep(1)
 
 def sensor():
     global t,h,g,zeit
     try:
         os.system('curl 192.168.178.100 >text.txt')
         f=open("text.txt","r")
         daten = f.read()
         f.close
         
     except:
         t=h=g=0
         time.sleep(10)
 
     #print(daten)
     print()
     index=daten.find("Temperature")
     #print(index)
     daten1=daten[index:-23]
     print(daten1)
     werte=daten1.split(":")
     print(werte)
     t=float(werte[1][0:6].strip())
     print("t = ",t," °C")
     h=int(werte[2][1:3])
     print("h = ",h," %")
     g=int(werte[3][1:4])
     print("g = ",g)
     if (t>25.0 or g>100):
         alarm()        
     time.sleep(1)
 
 def main():
     #       for fontname, size in [(None, None), ("ProggyTiny.ttf", 16), ('ChiKareGo.ttf', 16)]:
     for fontname, size in [("ProggyTiny.ttf", 16)]:
         print()
         print(fontname, size)
         font = make_font(fontname, size) if fontname else None
         term = terminal(device, font)
             
     while True:
             sensor()
 
             term.clear()
             term.animate = False
             term.clear()
             term.puts("Temperature:")
             term.puts(str(t))
             term.puts("°C")
             term.println()
             term.println()
             term.puts("Humidity: ")
             term.puts(str(h))
             term.puts(" %")
             term.println()
             term.println()
             term.puts("Gas: ")
             term.puts(str(g))
             term.println()          
             term.flush()
             time.sleep(2)
 
 if __name__ == "__main__":
     try:
         device = get_device()
         main()
     except KeyboardInterrupt:
         pass

Für den Programmstart haben Sie grundsätzlich drei Möglichkeiten:

  1. Normaler Start mit Tastatur und Monitor, anschließend “abnabeln“.
  2. Start über SSH (secure shell) vom PC z.B. mit dem Programm Putty
  3. Einrichten von Autostart (beschrieben im Blog Robot Car mit Raspberry Pi)

Es reicht jedoch nicht, das Programm zu laden und zu starten, weil die Voreinstellungen für ein anderes Display mit dem Treiber SSD1306 festgelegt sind. Deshalb muss für unser 1,3 Zoll OLED I2C 128 x 64 Pixel Display beim Programmaufruf der Parameter --display sh1106 übergeben werden.

Die weiteren Voreinstellungen für Interface: I2C und Dimensions: 128 x 64 sind richtig. Wenn Sie ein anderes Display verwenden, lohnt der Blick in die Datei README.rst im Verzeichnis luma.examples.

Im dritten Teil werde ich die Auswertung der Messwerte mit einem D1 Board (oder einem beliebigen anderen ESP8266 Micro Controller) vorstellen.


Download als pdf

DisplaysEsp-8266Projekte für anfängerRaspberry piSmart home

3 Kommentare

Bernd Albrecht

Bernd Albrecht

@ Sylvio Beck:
In seinem Blog vom 12. August 2020 zeigt Markus Pohle die Verwendung von IFTTT (if this than that).
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/enc28j60-ethernet-modul-fur-arduino-esp-und-raspi
Nachteil beider Lösungen: Man benötigt einen Internet-Dienstleister für das Versenden einer Nachricht. Das wollte ich vermeiden.

Wolfgang Herz

Wolfgang Herz

Sehr schönes Projekt. Sicherlich lässt sich da etwas optimieren. _Vielleicht ist der Vorschlag von Hr. Beck auch als Beispiel abbildbar. Trotzdem finde ich die direkte Anzeige im Display gut. Es macht Spaß derart tolle Projekt im AZ-Delivery zu haben! Ich habe bisher viel dazugelernt.

Danke

Sylvio Beck

Sylvio Beck

Schönes Projekt
Aber viel zu kompliziert viel einfacher wäre es wenn das Gerät im Garten Anomalien selbst erkennt und mit Hilfe eines Web Dienstes wie notifymydevice.com eine push Meldung auf das Handy sendet.

Die Daten die der Server sammelt können auch direkt per ftp upload ins Web oder eigene nas hochgeladen werden.

Bei Interesse könnt ich den entsprechenden Code zur Verfügung stellen.

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi