Bereits vor einiger Zeit habe ich meinen Wall Mounted Google Calendar mit einer Bewegungserkennung, die automatisch den Bildschirm an und abschaltet, (Motion Tracking) via Raspberry Pi Kamera betrieben. Leider war ich langfristig nicht mit der Funktion der eingesetzten Motion Software, welche das Tracking übernimmt, zufrieden da ich öfters die Parameter anpassen musste und Bewegungen im Allgemeinen nicht immer erkannt wurden.
Da ich meinen Google Kalender allerdings weiter betrieben möchte habe ich mich dazu entschieden einen passiven Infrarot Bewegungsmelder als Sensor einzusetzen. Der Bewegungsmelder ist im Vergleich zur Pi Cam recht günstig, wird mit 5V betrieben (der Ausgang ist 3,3V), und kann anhand von Stellschrauben ohne größere Probleme bezüglich der Sensibilität und der Zeitverzögerung beim Auslösen eingestellt werden. Der Erfassungsbereich liegt bei den meisten Geräten um die 120Grad.
Benötigte Hardware
- Einen Raspberry Pi, B, B+ oder 2B mit notwendigem Zubehör
- Passive Infrared Motion-Sensor / PIR Sensor. PIR mit Kabel, PIR ohne Kabel
- Jumper Kabel Female/Female zum direkten Anschließen an die GPIOs, mit Breadboard Male/Female
Der RasPi PIR Sensor
- Der SW1 Jumper bestimmt das Triggering Verhalten von Data
- Position 1 – Bei Bewegung wird alle Sekunde Data auf High gesetzt (Auf dem Bild zu sehen)
- Position 2 – Bei Bewegung bleibt Data auf High (Die verwende ich, Jumper nach unten setzen)
- Die Time Stellschraube bestimmt wie lange Data auf High bleibt wenn Bewegung erkannt wurde
- Die Sensitive Stellschraube bestimmt die Sensität der Bewegungserkennung
- Die Anschlüsse von Links nach Rechts sind GND, DATA, 5V
- Die Reichweite beträgt bis zu 7 Meter (abhängig von Sensor)
Die Verkabelung
Die Verkabelung des Bewegungsmelders ist recht einfach, die PINs werden wie folgt verbunden
- VCC => 5V => PIN2
- Data => 3,3V Datenausgang high/low => PIN7
- GND => Erde => PIN6
Monitor mit Bewengungsmelder steuern
Es ist relativ einfach den Sensor abzufragen, der Sensor hat einen Digitalen Ausgang, somit geht, wenn eine Bewegung erkannt wird, der Ausgang auf High bzw. Low wenn keine mehr erkannt wird. Wir müssen also nur den Status High / Low am GPIO Pin, an welchem der Sensor angeschlossen ist, abfragen. Stellt sicher das ihr den Jumper, wie oben beschrieben, auf die untere Position gesetzt habt (Data bleibt high solange Bewegung erkannt wird).
Den Sensor Testen
Zum Einstellen der Zeit und der Sensibilität eignet sich folgendes Programm da wir direkt auf der Konsole eine Ausgabe bekommen wenn Bewegung erkannt wurde, bisher habe ich keinen Python Code verwendet, entscheide mich aber der Einfachheit halber bei diesem Projekt für Python.
Wir erstellen eine Python Datei mit dem Editor Nano
1 |
nano /home/pi/bewegungsmelder.py |
Die Datei bekommt folgenden Inhalt
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 |
#!/usr/bin/python # Import der Python libraries import RPi.GPIO as GPIO import time import datetime # Wir verwenden den Board Mode, Angabe der PIN Nummern anstelle der GPIO BCM Nummer GPIO.setmode(GPIO.BOARD) # GPIO definieren, 7 da bei mir der Sensor auf Pin7 steckt GPIO_PIR = 7 print "Bewegungsmelder Test (CTRL-C zum Beenden)" print "=========================================" # GPIO als "Input" festlegen GPIO.setup(GPIO_PIR,GPIO.IN) Current_State = 0 Previous_State = 0 try: print "%s: Sensor initialisieren ..." % datetime.datetime.now() # Warten bis Sensor sich meldet while GPIO.input(GPIO_PIR)==1: Current_State = 0 print "%s: Fertig! Warte auf Bewegung..." % datetime.datetime.now() # Schleife bis CTRL+C while True : #Status von Sensor auslesen Current_State = GPIO.input(GPIO_PIR) if Current_State==1 and Previous_State==0: print " %s: Bewegung erkannt!" % datetime.datetime.now() Previous_State=1 elif Current_State==0 and Previous_State==1: print " %s: Fertig! Warte auf Bewegung..." % datetime.datetime.now() Previous_State=0 time.sleep(0.01) except KeyboardInterrupt: print " Exit" GPIO.cleanup() |
Gespeichert wird das Programm mit STRG-X, Y und Enter. Den Code könnt ihr nun mit folgendem Befehl ausführen.
1 |
sudo python bewegungsmelder.py |
Ich habe den Time und Sensivität Drehregler mit einem kleinen Schraubenzieher angepasst bis es zu meinen Anforderungen gepasst hat (~3 Minuten High).
Bildschirm steuern
Da ich einen Bildschirm mit „Energy Star“ verwende, der schwarz wird wenn er das VGA/DVI-Signal verliert und dann nach kurzer Zeit selbst in den Standby wechselt, muss ich nichts weiter tun als beim erkennen einer Bewegung via Kommando Zeile den HDMI Ausgang an bzw abzuschalten, auch hier verwende ich wieder ein Python Script, ähnlich dem Test-Script von oben
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 |
#!/usr/bin/python # Import der Python libraries import RPi.GPIO as GPIO import time import datetime import subprocess # Wir verwenden den Board Mode, Angabe der PIN Nummern anstelle der GPIO BCM Nummer GPIO.setmode(GPIO.BOARD) # GPIO definieren, 7 da bei mir der Sensor auf Pin7 steckt GPIO_PIR = 31 # GPIO als "Input" festlegen GPIO.setup(GPIO_PIR,GPIO.IN) Current_State = 0 Previous_State = 0 try: # erst mal schlafen bis der bootvorgang abgeschlossen ist time.sleep(120) # Warten bis Sensor sich meldet while GPIO.input(GPIO_PIR)==1: Current_State = 0 subprocess.Popen('echo initilized PIR | wall', shell=True) # Schleife bis CTRL+C while True : #Status von Sensor auslesen Current_State = GPIO.input(GPIO_PIR) if Current_State==1 and Previous_State==0: # Kommando zum anschalten, Frambuffer erneuern subprocess.Popen('echo Monitor on | wall', shell=True) subprocess.Popen('/opt/vc/bin/tvservice -p', shell=True) subprocess.Popen('fbset -depth 8', shell=True) subprocess.Popen('fbset -depth 16', shell=True) subprocess.Popen('sudo /bin/chvt 6 && sudo /bin/chvt 7', shell=True) Previous_State=1 elif Current_State==0 and Previous_State==1: # Ausschalten des Monitors subprocess.Popen('echo Monitor off | wall', shell=True) subprocess.Popen('/opt/vc/bin/tvservice -o', shell=True) Previous_State=0 # 5 Sek Warten time.sleep(5) except KeyboardInterrupt: print " Exit" GPIO.cleanup() |
Das Script führe ich bei jedem Startvorgang automatisch aus, siehe Cronjob als root einrichten. Da der Bildschrim zwecks Frambuffer Problematik nach dem erneuten anschalten oftmals schwarz bleibt müssen wir die x11 Utils installieren um einen Workarround zu schaffen, im Script wird z.B. via xrefresh -d :0 & chvt die Problematik umgangen, zusätzlich die Datei noch mit +x ausführbar machen.
1 2 |
sudo apt-get install x11-xserver-utils sudo chmod +x monitor.py |
Zusätzlich muss, um den Screensaver zu deaktivieren, in der Datei „/etc/xdg/lxsession/LXDE/autostart“ folgendes bearbeitet werden, hier meine Datei.
1 2 3 4 5 6 7 |
@lxpanel --profile LXDE @pcmanfm --desktop --profile LXDE # @xscreensaver -no-splash @xset s noblank @xset s off @xset -dpms |
Nach Montage auf meinem Raspberry Pi HAT Prototyping Board neben meine 433MHz Modulen sieht das ganze so aus