Wie hier im Blog schon beschrieben, habe ich mir mit einem Pi A einen kleinen Statusscreen gebastelt, der sich immer dann anschaltet, wenn jemand in die nähe des Pi’s kommt. Realisiert wurde das mit der PiCam – basierend auf Helligkeitsänderungen beim Snapshot. Soweit so gut. Seit 2 Monaten hängt sich der olle Pi jedoch regelmässig auf. So schlimm, dass ich Ihm einen crontab-Eintrag verpasst habe, mit dem er jede Nacht neu bootet.
Zeit der Sache mal auf den Grund zu gehen. Das Problem war: Zu wenig RAM. Der Pi A hat gerade 256MB davon (eigentlich mehr als genug, für soetwas). Dummerweise hängt in PiCam direkt an der GPU des kleinen Rechners. Was bedeutet, dass man dem Ding in der /boot/config.txt den Parameter gpu_mem=128 mitgeben muss. Heisst: 128MB für die GPU (drunter funktioniert die cam nicht) und 128MB für das OS. Sofern man nun nicht eine extraschlanke Distribution mit busybox und dem ganzen Small-Mem-Footprint-gedönse nutzt, ist das verdammt mau. Erst recht mit der extrem aufgeblasenen Raspianedition.
Also mussten Lösungsansätze her. Die Cam mit weniger als 128MB GPU-RAM zu betreiben funktioniert also schon mal nicht. Dann halt komplett anders. Für gerade mal 1,10 Euro/Stück gibt es bei Amazon PIR-Sensoren. PIR steht für Pyroelektrische Passive Infrarot Sensoren. Die Dinger, die man aus den Bewegungsmeldern an Aussenlampen kennt. Das besondere an diesen PIRs ist, dass sie out-of-the-box mit dem Pi über GPIO spielen können.
Obwohl das Chinaware ist, ist es relativ gut dokumentiert. In dieser Grafik findet sich alles, was man wissen muss:
Wir sehen zwei Potentiometer, mit denen man die Empfindlichkeit und eine Art “Nachlaufwert” einstellen kann. Den Timer stellt man am besten auf “0” (Anschlag ganz links), das “Distanz”-Poti nach Gusto. Nun zum elektrischen:
- VCC bei dem Ding ist 5V – der kommt also an PIN2 des GPIO’s (+5V OUT)
- GND auf GND – PIN 6
- OUT ist der PIN, der “HIGH” wird, wenn sich was vor dem Sensor bewegt. Und coolerweise spuckt das Ding ca. 3,3V aus – also genau richtig für den GPIO. Den hängen wir an GPIO18 (PIN 12)
Hier eine Übersicht der GPIO-PINs des raspis:
Nach dem das nun alles Erledigt ist, geht es zum simpleren Teil. Der Software. Ich habe das ganze, wie bereits beim Cam-Script in Python realisiert:
#!/usr/bin/python
import subprocess
import os
import time
import RPi.GPIO as io
from datetime import datetime
delay=60
monitor='on'
pir_pin = 18
io.setmode(io.BCM)
io.setup(pir_pin, io.IN) # activate input
def turnMonitorOn(extrarg):
global monitor
monitor='on'
subprocess.call("/usr/bin/screen.sh on "+extrarg, shell=True)
def turnMonitorOff(extrarg):
global monitor
monitor='off'
subprocess.call("/usr/bin/screen.sh off "+extrarg, shell=True)
# Reset last capture time
lastCapture = time.time()
# added this to give visual feedback of camera motion capture activity. Can be removed as required
while True:
time.sleep(0.5)
if io.input(pir_pin):
lastCapture = time.time()
if (monitor == 'off'):
turnMonitorOn("y")
if (time.time()-lastCapture > delay):
if (monitor == 'on'):
turnMonitorOff('x')
In der Variable “delay” kann man einstellen, wie lange der Screen nach einer Bewegungserkennung angeschaltet bleiben soll. Es sind natürlich auch andere Pins als GPIO18 möglich (bspw. GPIO4 / Pin7)
Das Shellscript, “screen.sh” ist dasselbe, wie im Cam-Post:
#!/bin/bash
tvstat=$(tvservice -s |grep off)
if [[ $tvstat == *off* ]]; then
TV=OFF
else
TV=ON
fi
if [ "$1" == 'on' ] && [ "$TV" == "OFF" ]; then
/usr/bin/tvservice -p;
#fbset -depth 8;
#fbset -depth 16;
chvt 2;
sleep 1
chvt 1;
chvt 2;
chvt 1;
#echo 'Switched Screen ON!'
fi
if [ "$1" == 'off' ] && [ "$TV" == "ON" ]; then
/usr/bin/tvservice -o
echo 'Switched Screen OFF!'
fi
Nun noch in der /boot/config.txt den Wert gpu_mem auf 32 oder gar 16 stellen, rebooten, und wir haben wieder mehr als genug RAM. Dass die CAM nun nicht mehr funktioniert, sollte jedem klar sein – aber das war ja auch Sinn und Zweck der Sache.