Using motion detection to switch your mirror on and off is very appealing. PIRs are a good option and Paviro’s module does a wonderful job. However, for an aesthetic point of view, I would like to mount the motion sensor behind the mirror, i.e. in such a way you can’t see the sensor. Since glass absorbs the light the PIR is sensitive to, PIRs (or at least the ones I tested, played with sensitivities as well) are not the best option. I played around a bit and found an alternative solution based on the Picamera, OpenCV and Paviro’s MMM-PIR module.
Downsides include having to run a python program next to the Magic Mirror. On a RPi3 it this is not a problem and is in my view therefore a rather minor drawback. If you run your MM on a RPi2, this may be an issue. Getting this to work also requires a non-trivial installation of OpenCV. However, thanks to the fantastic people over at PyImageSearch, detailed instructions are available. Upsides of this solution are: motion detection using a camera from behind the glass and the possibility to upload a photo taken by the camera each time it detects motion to your dropbox account.
Steps to follow:
- Disable the red LED on the Picamera by adding
disable_camera_led = 1
to\boot\config.txt
(you don’t want to see red LED of the camera when looking at your mirror) - Install a full version of OpenCV on the RPi. Detailed instructions can be found here
- Follow the two part tutorial on writing a python based code for motion detection: Part I and Part II
- Modify the python program found on the second page to generate a 3.3 V signal on a specified pin when the camera detects motion. This pin (pin 4 below) is then connected by a wire to the pin you specified in the MMM-PIR section of the MM
config.js
file. My modifications to the python code are:
On line 14 of the python code, add:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
OPENCV_pin = 4 # specify whatever pin you want to generate the 3.3 V at when motion is detected.
GPIO.setup(OPENCV_pin, GPIO.OUT)
On line 26 add:
UnoccupiedCounter = 0
NumUnoccFramesSwitchOff = conf["fps"] * conf["time_to_switch_off"]
On line 108 insert:
UnoccupiedCounter = 0
if GPIO.input(OPENCV_pin) == 0 # check if openCV pin is high or low. If low, turn high
GPIO.output(OPENCV_pin,1)
print "Switched Mirror ON"
On line 137 insert:
UnoccupiedCounter = UnoccupiedCounter + 1
if UnoccupiedCounter = numUnoccFramesSwitchOff and GPIO.input(OPENCV_pin)==1:
GPIO.output(OPENCV_pin, 0)
print "Switched Mirror OFF"
- Add
"time_to_switch_off": 30
to theconf.json
file. Don’t forget to add the comma behind the previous entry. - Optional but recommended to get a clean exit:
Insert the wholefor
loop in atry
statement.
Between line 53 and 54, add
try:
Don’t forget to indent all the code that comes next. Add the very bottom, add:
except KeyboardInterrupt:
print "Stopped camera surveillance" # exit the program when you press CNRL +C
except:
print "Other error or exception occurred!" # catch all other errors
finally:
GPIO.cleanup() # this ensures a clean exit.
I hope the above is of use to some of you.