Like every person, I have a burning desire to know who’s in my house when I’m not. A few months ago, I decided that I had had enough of the uncertainty of my extradomicilial activities, and that I needed to do something about it. I realized that I had two options. The first option would be to hire someone to be in my house 24/7, but that would get a bit embarrassing when I wanted to watch reruns of Desperate Housewives. The other option would be a motion sensor that texts me when it detects motion.
Luckily, this proved really easy to do with an Arduino. All I needed to get was the Arduino itself, and a PIR motion sensor, plus my home server. The motion sensor uses infrared to detect whether someone is moving, and outputs high or low accordingly, which the Arduino passes to the server via USB, and the server texts me using Twilio. Let me show you how the setup works.
Detecting motion
The thingy in the photo on the right is the sensor. It costs $3 or so, and it’s a thing of beauty. You simply connect it to the Arduino, and it outputs HIGH when it detects motion, and LOW otherwise. In itself, that isn’t very useful, but the Arduino can do much more with it.
To make the motion sensor more useful, I decided to have the Arduino output “seconds since last motion” every second. This means that there’s a counter that counts up every second there’s no motion, and it resets when the sensor sees something moving, like my body. The code for this is pretty straightforward, it just resets the counter whenever there’s motion and outputs the value every second on the serial (USB, really) port:
#define INPUT_PIN 5
unsigned long lastMotionTime = 0;
unsigned long lastOutputTime = 0;
void setup() {
// Initialize various things.
pinMode(INPUT_PIN, INPUT);
lastMotionTime = millis();
Serial.begin(9600);
}
void loop() {
if (digitalRead(INPUT_PIN) == 1) {
// When we sense motion, store the time.
lastMotionTime = millis();
}
// Output the last motion time every second.
if ((millis() - lastOutputTime) > 1000) {
// Convert to seconds and print.
Serial.println((millis() - lastMotionTime) / 1000);
lastOutputTime = millis();
}
}
This whole thing is pretty much two useful lines, one to reset and one to output. The rest is just C.
Do note that millis()
wraps around to 0 at some point (after about 50 days, I think?), which may trigger some odd behaviour, but just make sure to get out of the house once every two months or so and you should be fine.
Doing something with it
Now that we know how many seconds it has been since the last attempt, it’s very easy to do something based on that value. I wrote a very short Python script that will read the value every time it’s output and will do something based on that.
The “something” is that it will set an away
variable to True
if it detects no motion for more than five minutes, and, if the counter suddenly resets when away
is True
, it means there’s someone home, so the server should text/email/otherwise notify me. Here’s the code (it requires pyserial
):
import serial
away = False
# Open the connection.
com = serial.Serial("/dev/ttyACM0", 9600)
while True:
# Read a line, convert it to a number and store it.
last_motion = int(com.readline())
if away is False and last_motion > 10 * 60:
# If there's no motion for more than 5 min,
# we're not here any more.
away = True
elif away is True and last_motion < 10:
# We are (were?) away, yet there's motion.
# Someone's here!
away = False
send_message("Someone's home!")
The send_message
function is just what notifies me, and it’s rather outside the scope of this post. You can use the Twilio Python library, or send an email, or a push notification, or hook it up to a wet blanket so it can send smoke signals, whatever is your preference.
I’d write some more stuff here, but this is a pretty simple setup, so I ran out of things to write. I could tell you about how I hooked this up to the house lights so it can turn them on and off when I’m in or out, but that will probably be the subject of another post.
As always, if you have any feedback, questions, or free money you want to send me, leave a comment below, or get me on Twitter. Have fun sensing motion, and remember: This doesn’t work for vampires.