Der Raspberry Pi 7″ Touchscreen eignet sich hervorragend als Panel für die Hausautomatisierung. Hierbei können Bedienelemente einfach platziert und zugänglich gemacht werden. Damit der Bildschirm allerdings nicht 24 Stunden am Tag hell leuchtet und nur dann aktiviert wird, wenn er wirklich gebraucht wird, müssen wir ihn so konfigurieren. Hierbei nutzen wir einen Bewegungs- und Abstandssensor, um den Bildschirm zu aktivieren, sobald sich jemand nähert.
Mit Hilfe dieser Sensoren erstellen wir ein Skript, welches automatisch erkennt, ob jemand den Touchscreen nutzen will oder nicht und ihn ggf. danach ausschaltet.
Gerade nachts ist es störend, wenn dauerhaft eine Lichtquelle aktiv ist, weshalb dieses Tutorial den Komfort um einiges erhöht. Und ganz nebenbei wird ein wenig Strom gespart. Dieses Projekt kann mit kleineren Anpassungen übrigens auch wunderbar mit einem Magic Mirror genutzt werden, sodass der Bildschirm erst angeht, wenn jemand in der Nähe davor steht.
Zubehör
Folgendes Zubehör wirst du für die Schritte dieses Tutorials benötigen:
- Raspberry Pi (mit DSI Anschluss)
- Offiziellen 7 Zoll RPi Touchscreen (mit DSI Kabel)
- Bewegungssensor
- Ultraschallsensor (zur Abstandserfassung)
- Jumper Kabel
- ggf. Halterung für den Touchscreen
Theoretisch würde eine Erkennung auch mit nur einem der beiden Sensoren – entweder dem PIR Bewegungsmelder oder dem Abstandssensor – funktionieren, allerdings ist die Methode mit beiden komfortabler. Wer dennoch nur einen Sensor nutzen möchte, muss den Code für seine Zwecke modifizieren.
Viele weitere hilfreiche Tipps & Tricks zum offiziellen Touchscreen Modul findest du übrigens in diesem Artikel.
Aufbau
Bevor wir starten verkabeln wir den HC-SR04 Ultraschallsensor sowie den PIR-Bewegungsmelder. Wie in den beiden Tutorials schließen wir die Pins an unsere GPIOs (falls du andere verwendest, muss du diese später im Skript anpassen). Für den Ultraschallsensor:
- VCC an Pin 2 (VCC)
- GND an Pin 6 (GND)
- TRIG an Pin 12 (GPIO18)
- an ECHO wird der 330Ω Widerstand angeschlossen. An dessen Ende geht eine Verbindung zu Pin 18 (GPIO24) und über den 10kΩ Widerstand eine Verbindung zu Pin6 (GND). Somit stellen wir sicher, dass immer eine Spannung (ggf. LOW) anliegt. Der Vorwiderstand ist zum schonen der GPIOs, da diese bei 5V Spannung kaputt gehen könnten.
Der PIR Bewegungssensor wird an 5V (VCC, rot), GND (GND, schwarz) und OUT/DATA an Pin 16 des Raspberry Pi’s, was GPIO 24 ist angeschlossen.
Schematisch sieht es folgendermaßen aus:
Die beiden Sensoren können oberhalb oder unterhalb des Displays platziert und befestigt werden. Diese sollten geradeaus auf den bedienenden Nutzer zeigen.
Falls der Bewegungssensor zu sensibel eingestellt ist, kannst du ihn durch die Drehregler auch justieren:
Vorbereitung
Zunächst einmal aktualisieren wir das Betriebssystem und aktivieren den Bildschirm per SSH :
sudo apt-get update sudo rpi-update sudo reboot
Nach dem Neustart rufen wir dies auf:
sudo raspi-config
Unter „Boot Options“ stellen wir sicher, dass direkt in den Desktop / CLI gestartet wird.
Bevor wir schon mit den eigentlichen Skripten beginnen, müssen wir den automatischen Screensaver (Bildschirmschoner) deaktivieren, damit wir dies selbst in der Hand haben. Dazu installieren zunächst folgendes Paket:
sudo apt-get install xscreensaver
Anschließend gehen wir entweder über den Touchscreen oder über eine Remotedesktopverbindung auf Preferences -> Sceensaver.
Hier können wir den Bildschirmschoner ganz einfach deaktivieren (Disable Screen Saver):
Damit wir die Helligkeit gleich per Skript steuern können, müssen wir noch Rechte über die Shell / SSH verteilen (Wichtig: Der Bildschirm muss angeschlossen sein!):
sudo chmod 777 /sys/class/backlight/rpi_backlight/bl_power
Skript zum Aktivieren des Touchpanels
Kommen wir nun zum eigentlichen Teil, dem Skript, welches für die Steuerung zuständig ist. Wir erstellen nun ein neues Skript im Homeordner:
sudo nano ~/displaystandby.py
Hier kommt folgender Inhalt hinein:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import RPi.GPIO as GPIO import time, os, threading GPIO_PIR = 23 GPIO_TRIGGER = 18 GPIO_ECHO = 24 THRESHOLD = 60 # cm TIMEOUT = 180 # sec ############################ GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(GPIO_PIR, GPIO.IN) GPIO.setup(GPIO_TRIGGER, GPIO.OUT) GPIO.setup(GPIO_ECHO, GPIO.IN) LAST_MOVE = 0 def distance(sample_size=5, sample_wait=0.01): # https://raw.githubusercontent.com/alaudet/hcsr04sensor/master/hcsr04sensor/sensor.py speed_of_sound = 331.3 sample = [] for distance_reading in range(sample_size): GPIO.output(GPIO_TRIGGER, GPIO.LOW) time.sleep(sample_wait) GPIO.output(GPIO_TRIGGER, True) time.sleep(0.00001) GPIO.output(GPIO_TRIGGER, False) echo_status_counter = 1 sonar_signal_on, sonar_signal_off = time.time(), time.time() while GPIO.input(GPIO_ECHO) == 0: if echo_status_counter < 1000: sonar_signal_off = time.time() echo_status_counter += 1 #else: # raise SystemError('Echo pulse was not received') while GPIO.input(GPIO_ECHO) == 1: sonar_signal_on = time.time() time_passed = sonar_signal_on - sonar_signal_off distance_cm = time_passed * ((speed_of_sound * 100) / 2) sample.append(distance_cm) sorted_sample = sorted(sample) return sorted_sample[sample_size // 2] def standby(): d = distance() if d >= THRESHOLD: os.system("echo 1 > /sys/class/backlight/rpi_backlight/bl_power") # off else: os.system("echo 0 > /sys/class/backlight/rpi_backlight/bl_power") # on threading.Timer(TIMEOUT, standby).start() LAST_MOVE = time.time() def has_moved(channel): d = distance() if d <= THRESHOLD: os.system("echo 0 > /sys/class/backlight/rpi_backlight/bl_power") # on if time.time() - LAST_MOVE >= 1: threading.Timer(TIMEOUT, standby).start() try: #while True: GPIO.add_event_detect(GPIO_PIR , GPIO.RISING, callback=has_moved) while True: time.sleep(1) except KeyboardInterrupt: print "Beende..." GPIO.cleanup() |
Vergiss nicht die GPIOs ggf, anzupassen und ebenso die Standardwerte (Entfernung, Timeout Zeit) anzupassen, sofern nötig.
Du kannst es bereits testen mit:
sudo python ~/displaystandby.py
Autostart des Skripts
Als letztes wollen wir noch, dass auch beim Neustart dieses Skript automatisch startet. Dazu nutzen wir crontab:
sudo crontab -e
Ans Ende fügen wir folgende Zeilen:
@reboot /usr/bin/sudo /bin/chmod 777 /sys/class/backlight/rpi_backlight/bl_power @reboot /usr/bin/sudo /usr/bin/python /home/pi/standpyscreen.py
Da das Tutorial auf verschiedenen Raspbian Betriebssystemen lauffähig ist und der Homepfad oft unterschiedlich ist, kannst du mit cd ~; pwd;
den absoluten Pfad herausfinden. Diesen wirst du gleich brauchen und anpassen müssen (bei mir ist es /home/pi/
).
Nach dem Neustart startet es nun automatisch:
sudo reboot
11 Kommentare
Interessant und nutzvoll…dieses wir ich implementieren.
Ich suche ein geeignete spritzwasserfest Gehäuse für ein RPi3+ plus 2 zusätzliche boards, ein HAT und die Screen mit genug Abstand/platz für Schalter…kann einer mir Hilfen?
rpi-update ist keine gute idee, es wird dabei kein stable sondern beta ins system gespielt.
Sehr gut aber im prinzip könnte man aber auch einfach ein Tablet aus china bestellen wäre halt kompakter aber man hat halt keinen bastell spaß aber sehr gut geschrieben werde ich demnächst ma ausprobieren
Euer Script hat leider einen Bug. Ihr habt vom Originalcode in Zeile 36,37 die Fehlermeldung auskommentiert, weil ihr das Script vermutlich nicht abbrechen lassen wolltet. Allerdings besteht nun die Gefahr einer Endlosschleife. Und zwar wenn das Signal nicht erkannt wird, bleibt GPIO.input(GPIO_ECHO) == 0 dauerhaft true und die while-schleife hängt dann fest. Der echo_counter ist dafür vorgesehen, diesen Fall abzusichern.
Der Code muss wie folgt lauten (Zeilen 31-37 ersetzen):
sonar_signal_on, sonar_signal_off = time.time()+1, time.time()
while GPIO.input(GPIO_ECHO) == 0 and echo_status_counter < 1000:
sonar_signal_off = time.time()
echo_status_counter += 1
Ich habe euere Anleitung genutzt um meinen Sensor anzubinden. Vielen Dank dafür. Euer Skript habe ich auf meine Bedürftnisse angepasst. Ihr findet es hier: https://github.com/markus-hsk/raspi_tuerspion/blob/master/src/displaystandby.py
VG
Super 😃 was mich aber noch brennend interessiert ist wo ihr die Sensoren versteckt. Ich habe das offizielle case. Da ist eine Einkerbung für die offizielle pi cam, aber sonst nichts. Es soll ja auch hübsch aussehen. Habt ihr da einen Tipp?
Gruß Daniel
Das würde mich auch noch brennend interessieren. Hat da jemand mittlerweile eine Lösung gefunden ?
Moin zusammen.
Ich stehe gerade irgendwie auf dem Schlauch. Ich hab einen IR Abstandssensor mit einem Transistor versehen, der bei passender Entfernung ein Signal gibt.
Ich habe gedacht Ich könnte einfach die PIR Sequenz übernehmen und fertig ist es.
Leider fehlen mir da die Kentnisse.
Kann mir hier jemand einen Tip geben? Ich habe somit kein Echo und ich kann auch keine Distanz messen.
Hallo, kann anstelle des Displays auch ein Monitor über HDMI angesteuert werden? Gruß, Florian
Das kommt auf die Funktionen des Displays an. Prinzipiell könntest du aber den „screensaver“ Modus über das Raspberry Pi OS aktivieren.
Hallo,
Vielen dank für diese tolle Anleitung. Ich bin dadurch auf die Anwendungsmöglichkeiten eines Raspberry aufmerksam geworden und stehe noch ganz am Anfang. Habe mich Schritt für Schritt an diese Anleitung gehalten. Das Skript funktioniert leider nicht zuverlässig, (kann natürlich auch an aktuellen Updates liegen). Ich bekomme das Skript zum laufen…dann läuft es 5min und danach geht der Bildschirm (offizielles 7“ Display) nicht mehr an. Die Änderungen von Markus am 24. Oktober 2018 18:56 gehen gar nicht, da bekomme ich stets direkt einen Fehler.
Mein Aufbau sieht wie in der Anleitung aus. An GPIO 1 und 14 hängt bei mir noch das Display- liegt darin der Fehler? (Nutze den RaspberryPi 3+ Aktuelles Raspbian OS mit Desktop).
Vielen Dank schonmal für die Hilfe! LG
Moin,
mal eine ganz stumpfe frage, warum brauche ich hier den Ultraschall Sensor? Wenn der Bewegungssensor niedrig eingestellt ist, würde es doch denselben Effekt haben, oder nicht?