|
DIY Arduino intrusion alarm
with real time clock
and iphone notification |
Pardawl is an intrusion alarm project that combines the following components:
-
Arduino UNO (CPU board and power supply)
- PIR Infrared 6m movement/ presence sensor
- Real time clock module ( TinyRTC v1.1 design by waiman)
- ENC28J60 ethernet breakout
When movement is detected and the alarm is active, a notification is sent to your iPhone. The Alarm stays idle for one minute and then rearms. If movement continues, another notification is sent. And so on. This alarm produces no local sound.
The real time clock is used to activate/deactivate the alarm at suitable times, when nobody is supposed to be in range, so you don't have to worry about turning the alarm on and off. For instance, you can set the alarm to be active only on weekends and weekdays between 9PM and 6AM. Times can be changed by editing and compiling Arduino source code (need Arduino IDE). The ethernet interface is used to send alarm notifications to the iphone. Connect the ethernet module to your Internet router or switch, using a ethernet cable.

the Pardawl above was assembled inside an iphone carton box
( not sure is a good idea, may start a fire! )
The iPhone notification
system is deployed using Prowl, a iphone notification app ( from Appstore. costs US$2.99. No, I'm not associated to it ). When a notification is received, Prowl app for the iPhone can play a sound and display a message box. These can be configured. You also have to set your Prowl user and password in the phone app.
To setup the alarm, you have to register in Prowl website ( www.prowl.com ). Registration is free and you receive your API key. You will need access to a PHP enabled webserver. In it, you will post a couple PHP pages, to help the alarm notification process. I used Prowl PHP, by Xenji ( https://github.com/xenji/ProwlPHP). Download ProwlPHP to your website and save to a secret path only your Pardawl alarm knows. I suppose one could easily implement basic authentication, to prevent a hacker from triggering false alarms by calling your page directly. But keeping the url itself a secret (and out of search engine eyes) also works. I found the PHP configuration (PHP.INI) has to have MB (multi-byte strings) and OpenSSL extensions enabled, in order to ProwlPHP to work. You can test the Prowl PHP by opening the page in the web browser. Your iPhone should receive the notification.
The alarm will send notifications to your site. The Prowl PHP page forwards the notification to some Prowl server, which will send to your phone via Apple. This triangulation is necessary because there is no https implementation for Arduino, as required by Prowl API ( https is a secure version of the web protocol ).
Pardawl alarm --> your ProwPHP page --> Prowl server --> Apple --> your iPhone
The whole thing is bureaucratic, but it works and latency is only a couple seconds.
Edit the following lines in your Prowl PHP main page (red text):
...
// You can ADD up to 5 api keys
// This is a Test Key, please use your own.
$oMsg->addApiKey('123456789abcdef123456789abcdef123456789abcdef'); // <-- Use your Prowl API key goes here
$oMsg->setEvent('My Alarm!'); // <-- Notification title
//optional
$oMsg->setDescription('Alarm: Intruder in myOffice!!'); // <-- Notification message
$oMsg->setApplication('Pardawl alarm'); // <-- application name

Pardawl wiring
 |
Wiring is simple and requires no extra board, only jumper cables (female-male and one pair of female-female) .
VCC and GND for the sensor was taken from the tinyRTC module.
TinyRTC comes without pins, so you have to weld male pins as shown (7 in one side and 2 on the other (VCC and GND)). Remove the battery before welding the pins. Note that you will need to set date/time after that. I found this the most difficult step in the alarm construction.
|
Pardawl Arduino source code is shown below. I also posted to Google Code:
https://code.google.com/p/pardawl/source/browse/trunk/Pardawl.ino
Use the Arduino IDE to compile and send the program to Arduino UNO. I used two libraries not present in the default Arduino IDE installation: EtherCard and tinyRTC. Install them inside \program files\Arduino\libraries\.
Configuration - You need to change the configuration section in the Arduino source code to reflect your particular setup. Configuration is hardcoded in the source code. TinyRTC has 56 bytes of unvolatile memory, so one could store the configuration there instead of in the program itself. I didn't do that.
The configuration fields are in red. You have to set:
-
your Pardawl static IP number
-
local network Gateway ( router static IP)
-
Pardawl MAC address
-
website name (hosting your prowl php pages)
-
website static IP number
-
full path to your Prowl PHP page
-
times of alarm on/off
Choosing the IP number - Pardawl IP number must be static ( DHCP is not supported ) and chosen outside the DHCP server IP address range, to avoid IP number conflict. Check your intranet router configuration before choosing the alarm ip number. The gateway IP number is the intranet address of the router. Normally a number finished with 1. If you use Windows in your desktop, open a command prompt and type:
This will show the gateway address.
The MAC address must be unique in your network, change if you use more than 1 Pardawl in the same network.
Setting the date/time - You may need to set the real time clock in the first use. This is done by uncommenting the set date/time section in the Arduino setup(). After adjusting the time, comment the section and recompile, so the set time section is not in the final version.
TinyRTC battery is supposed to keep the time for a couple years.
Arduino source code:
// Pardawl - Intrusion alarm with:
// - Real Time clock, for automatic activation of alarm during the night and week-ends
// - PIR motion sensor (6 meters)
// - Ethernet connection, to send iPhone notification (using app Prowl)
// by Omar Reis - Public domain app
// - uses Xenji ProwlPHP - https://github.com/xenji/ProwlPHP
#include <Wire.h>
#include <DS1307.h>
#include <EtherCard.h>
/*
about set time using Arduino serial:
format: year,month,day,week,hour,min,sec
example: 14,03,25,02,13,55,10 2014.03.25 tuesday 13:55:10
ver http://www.dfrobot.com/wiki/index.php/Real_Time_Clock_Module_%28DS1307%29_V1.1_%28SKU:DFR0151%29
This is a demo of the RBBB running as webserver with the Ether Card
2010-05-28 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php
*/
// configure the following fields for your particular setup ------------------------------------------
static byte myip[] = { 192,168,10,123 }; // static ip address of your Arduino Burglar Alarm
static byte gwip[] = { 192,168,10,1 }; // static ip address of local gateway (ex: local router IP)
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x37,0x33 }; // ethernet interface mac address
// change MAC if two alarms in the same network
// site where your ProwlPHP pages are hosted
const char website[] PROGMEM = "www.yoursite.com"; // website name
static byte hisip[] = { 200,123,123,123 }; // website ip address(static IP corresp to 'www.yoursite.com')
const char phpFile[] PROGMEM = "/MySecret/Folder123/myoffice.php"; // secret path to your prowlPHP page
// (mantain a secret, otherwise someone else can trigger false alarms)
float timeAlarmOff=6.0; // during weekdays, alarm is on before that (and off during business hours)
float timeAlarmOn=21.0; // during weekdays, alarm is on after that
// /config ------------------------------------------------------------------------------------------
String comdata = "";
int mark=0;
int rtc[7]; //store the current time data
byte rr[7]; //store the set time data
int ledPin = 13; //light pin
//initial light
int IRSensor = 0;
int pinIRSensor = 3;
// RTC time vars
float theTime = 0;
float timeDisparoAlarm = 0;
int dayOfWeek = 0;
char strbuf[20]; // string buffer
byte Ethernet::buffer[500]; // tcp/ip receive buffer
boolean alarmOn = false;
// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
Serial.print("<<< reply ");
Serial.println((const char*) Ethernet::buffer + off);
}
//out date/time to Serial
static void showTime() {
RTC.get(rtc, true); // get current time
Serial.print(rtc[6]); //ano
Serial.print("/");
Serial.print(rtc[5]); //mes
Serial.print("/");
Serial.print(rtc[4]); //dia
switch (rtc[3]) {
case 1: Serial.print(" sun "); break;
case 2: Serial.print(" mon "); break;
case 3: Serial.print(" tue "); break;
case 4: Serial.print(" wed "); break;
case 5: Serial.print(" thu "); break;
case 6: Serial.print(" fri "); break;
case 7: Serial.print(" sat "); break;
default: Serial.print(" ?? ");
}
Serial.print(rtc[2]); //hh
Serial.print(":");
Serial.print(rtc[1]); //nn
Serial.print(":");
Serial.println(rtc[0]); //ss
}
void setup() // <-------------------------- setup()
{
DDRC |= _BV(2) | _BV(3); // POWER:Vcc Gnd
PORTC |= _BV(3); // VCC PINC3
pinMode(ledPin, OUTPUT); //Arduino UNO inboard LED signals sensor trigger
pinMode (pinIRSensor, INPUT); //PIR Sensor input
//initial serial baudrate
Serial.begin(9600);
Serial.println("----------Pardawl----------");
Serial.println("intrusion alarm with realtime clock and iPhone notifications");
showTime(); //show RTC date/time
// uncomment below to set date/time in the first run. Then comment and recompile.
// RTC.stop(); //stop rtc time
// RTC.set(DS1307_SEC, 30);
// RTC.set(DS1307_MIN, 24);
// RTC.set(DS1307_HR, 9);
// RTC.set(DS1307_DOW, 2); //Sunday=1, Monday=2 etc
// RTC.set(DS1307_DATE, 16);
// RTC.set(DS1307_MTH, 06);
// RTC.set(DS1307_YR, 14);
// RTC.start(); //restart rtc time
RTC.SetOutput(DS1307_SQW32KHZ);
// ethernet start
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
ether.staticSetup(myip, gwip);
ether.copyIp(ether.hisip, hisip);
ether.printIp("Server: ", ether.hisip);
while (ether.clientWaitingGw())
ether.packetLoop(ether.packetReceive());
Serial.println("Gateway found");
}
void blinkLED() {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
// alarm ligado das 19:00 as 7:00 e nos fins de semana..
boolean alarmLigado() {
boolean fimDeSemana = (dayOfWeek==1) || (dayOfWeek==7);
boolean deNoite = (theTime<timeAlarmOff) || (theTime>timeAlarmOn);
// during weekdays, alarm is turned on during the night and off during bussiness hours
return (deNoite || fimDeSemana);
}
// set clock with serial data
void setClockDateTime() {
//read serial data to set clock
int j = 0;
while (Serial.available() > 0) {
comdata += char(Serial.read());
delay(2);
mark = 1;
}
//if data is all collected,then parse it
if (mark == 1) {
Serial.println(comdata);
Serial.println(comdata.length());
//parse data
for (int i = 0; i < comdata.length() ; i++) {
//if the byte is ',' jump it,and parse next value
if (comdata[i] == ',') { j++; }
else { rr[j] = rr[j] * 10 + (comdata[i] - '0'); }
}
comdata = String("");
RTC.stop();
RTC.set(DS1307_SEC, rr[6]);
RTC.set(DS1307_MIN, rr[5]);
RTC.set(DS1307_HR, rr[4]);
RTC.set(DS1307_DOW, rr[3]);
RTC.set(DS1307_DATE, rr[2]);
RTC.set(DS1307_MTH, rr[1]);
RTC.set(DS1307_YR, rr[0]);
RTC.start();
mark = 0;
}
}
void loop() // <------------------------------------ loop()
{
//get IR sensor input
// showTime();
IRSensor = digitalRead(pinIRSensor);
// Serial.print("IR Sensor:");
// Serial.println(IRSensor);
//get current time
RTC.get(rtc, true);
theTime = (float)(rtc[0] + rtc[1]*60.0 + rtc[2]*3600.0)/(3600.0); //seconds --> hrs
dayOfWeek = rtc[3];
if (IRSensor == 1) { blinkLED(); } //para ajuste da sensibilidade
alarmOn = (IRSensor == 1) && alarmLigado();
ether.packetLoop(ether.packetReceive()); //receive any data
if (alarmOn) {
if (timeDisparoAlarm==0) {
Serial.print("alarm triggered at ");
showTime();
timeDisparoAlarm = theTime;
Serial.println("\n notify Prowl");
ether.browseUrl( phpFile, "", website, my_result_cb);
};
} else {
delay(500);
}
//resseta alarm apos 10 min
if (timeDisparoAlarm != 0) {
if (theTime-timeDisparoAlarm > 0.017) {
timeDisparoAlarm = 0;
Serial.print("alarm rearmed at ");
showTime();
}
}
//uncomment below to set time using serial ...
// if (Serial.available() > 0) {
// setClockDateTime();
// }
}

©Copr 2014 Omar F. Reis