Components and supplies
Resistor 100 ohm
Silicone wire, 22 awg
LED (generic)
Switch spst
Arduino Nano ESP32
PIR Sensor
Tools and machines
Soldering kit
Wire Stripper
Apps and platforms
Arduino IDE
Project description
Code
Intrudalizer 2000 Pro Code
cpp
This is the Arduino code (passwords etc removed)
1/* ------------------------------------------------------------------------------------------ 2 Intruder Alarm with text messaging: "Intrudalizer 2000 Pro" 3 By: Michael Willems - michael@willems.ca 4 Needs: 5 -Arduino Nano ESP32 6 -WiFi connectivity (2.4 GHz) 7 -Twilio account 8 -twilio-esp32-client library (from Arduino IDE) 9 -PIR sensor 10 -LEDs, resistor, SPDT switch, pushbutton. 11 12 Alarm is activated with switch (flashing yellow); 60 seconds later it's active (solid yellow). 13 Sends SMS to phone upon bootup, arm, disarm, and alarm. 14 15 After an alarm, it stays in alarmed status for an hour, and then it resets so that 16 new alarms can be generated and new alarm SMSs can be sent. 17 18 Version 0.4 - 11 Aug 2023 19 Change log: 20 0.4 added a 2x retry to a failed SMS on trigger 21 0.32 minor changes, tidied up, removed unnecessary pushbotton, removed serialWrite. 22 0.31 documentation/comments added 23 0.3 added one hour trigger reset 24 0.2 added SMS on arm/disarm 25 0.1 made it work 26--------------------------------------------------------------------------------------------*/ 27 28//------------------------------------------------------------------------------------------- 29// INCLUDES, DECLARATIONS: 30//------------------------------------------------------------------------------------------- 31#include "WiFi.h" 32#include "twilio.hpp" 33 34// define WiFi and SMS credentials: 35const char *ssid = "xxxxx"; 36const char *password = "xxxxx"; 37Twilio *twilio; 38 39// Values from Twilio (from the dashboard): 40static const char *account_sid = "xxxxx"; 41static const char *auth_token = "4xxxxx"; 42static const char *from_number = "+1xxxxx"; 43static const char *to_number = "+1xxxxx"; 44static const char *messageStart = "I2kPro Home: Startup"; 45static const char *messageAlert = "I2kPro Home: MOTION DETECTED"; 46static const char *messageArmed = "I2kPro Home: Armed"; 47static const char *messageDisarmed = "I2kPro Home: Disarmed"; 48String response; 49 50// define misc pins: 51int PIRpin = 2; 52int Switch = 10; 53 54// on-board LEDs: 55int activeled = 13; // flashes 1x/sec to indicate functioning 56int blueled = 16; // blue when WiFi is connected 57 58// External LEDs: 59int OkLed = 3; // WiFi and SMS OK 60int WiFiErrLed = 4; // WiFi Error 61int SmsErrLed = 5; // SMS Error 62int ArmLed = 6; // Armed 63int TrigLed = 7; // Motion seen! 64 65// Counters etc: 66unsigned long oneseccounter; 67unsigned long quartersecondcounter; 68unsigned long fourseccounter; 69unsigned long prearmtimer; // delay before armed is active (default: 60000) 70unsigned long prearmdelay = 60000; 71unsigned long rearmtimer; // "no new alarm" time after alarm (default: 3600000) 72unsigned long rearmdelay = 3600000; 73unsigned long resendtimer; // TBD: resend an SMS on error 74unsigned long resenddelay = 60000; 75boolean ArmedStat = false; // Flag: are we armed? 76boolean PreArmInhibit = false; // Flag: are we stil in pre-arm time, so no alarms yet please? 77boolean TriggeredStat = false; // Flag: is the alarm triggered? 78 79 80//------------------------------------------------------------------------------------------- 81// THE SETUP (RUNS ONCE): 82//------------------------------------------------------------------------------------------- 83void setup() { 84 pinMode(PIRpin, INPUT); 85 pinMode(Switch, INPUT_PULLUP); 86 pinMode(activeled, OUTPUT); 87 pinMode(blueled, OUTPUT); 88 pinMode(OkLed, OUTPUT); // green 89 pinMode(WiFiErrLed, OUTPUT); // red 90 pinMode(SmsErrLed, OUTPUT); // red 91 pinMode(ArmLed, OUTPUT); // yellow 92 pinMode(TrigLed, OUTPUT); // blue 93 94 // Set inital LED status: 95 digitalWrite(OkLed, LOW); 96 digitalWrite(WiFiErrLed, HIGH); 97 digitalWrite(SmsErrLed, HIGH); 98 digitalWrite(ArmLed, LOW); 99 digitalWrite(TrigLed, LOW); 100 101 // Now connect to WiFi and wait until connected: 102 WiFi.begin(ssid, password); 103 while (WiFi.status() != WL_CONNECTED) { 104 digitalWrite(activeled, LOW); 105 analogWrite(blueled, LOW); 106 delay(250); // and if we use a hardware watchdog, don't forget to reset it here! 107 } 108 // We are connected, so indicate this: 109 analogWrite(blueled, HIGH); 110 digitalWrite(activeled, HIGH); 111 digitalWrite(WiFiErrLed, LOW); 112 delay(250); 113 114 // start Twilio instance: 115 twilio = new Twilio(account_sid, auth_token); 116 117 // Now send SMS: 118 String response; 119 bool success = twilio->send_message(to_number, from_number, messageStart, response); 120 if (success) { 121 digitalWrite(SmsErrLed, LOW); 122 digitalWrite(OkLed, HIGH); // because if SMS was sent, WiFi must also be OK 123 } else { 124 digitalWrite(SmsErrLed, HIGH); // TBD: Decide what to do now. Retry? 125 } 126 // set the timers to start: 127 oneseccounter = millis(); 128 quartersecondcounter = millis(); 129} 130 131 132//------------------------------------------------------------------------------------------- 133// THE LOOP (RUNS CONTINUOUSLY): 134//------------------------------------------------------------------------------------------- 135void loop() { 136 137 // now do the "once every second" things: 138 if ((millis() - oneseccounter) > 1000) { 139 140 //Toggle the on-board active LED: 141 digitalWrite(activeled, !digitalRead(activeled)); 142 143 // is WiFi connected? If not, turn off the blue and OK LED, and turn on WiFi Error LED: 144 if (WiFi.status() != WL_CONNECTED) { 145 analogWrite(blueled, LOW); 146 analogWrite(WiFiErrLed, HIGH); 147 digitalWrite(OkLed, LOW); 148 } else { 149 // wifi is OK, so turn the on-board blue LED on, and turn WiFi error light off: 150 analogWrite(blueled, HIGH); 151 analogWrite(WiFiErrLed, LOW); 152 digitalWrite(OkLed, HIGH); 153 } 154 // Now reset counter so we can start counting another second: 155 oneseccounter = millis(); 156 } 157 // End of "once a second" things. 158 159 // The "every quarter second" thing - for flashing the light while armed+inhibited: 160 if ((millis() - quartersecondcounter) > 250) { 161 if ((ArmedStat == true) && (PreArmInhibit == true)) { 162 digitalWrite(ArmLed, !digitalRead(ArmLed)); 163 } 164 quartersecondcounter = millis(); 165 } 166 // End of the "every quarter second" thing. 167 168 169 // Now the "always do this" things: 170 171 // ------------------- 172 // Arm/Disarm routines: 173 // ------------------- 174 if (digitalRead(Switch) == LOW) { //switch is turned on (up) 175 if ((millis() - prearmtimer) > prearmdelay) { 176 PreArmInhibit = false; 177 digitalWrite(ArmLed, HIGH); // turn on "Armed" light just in case it's not on yet 178 } 179 if (ArmedStat == false) { // i.e. it was just now turned to ARM... 180 ArmedStat = true; // so next loop it knows it's not only just been armed, so not another SMS 181 digitalWrite(ArmLed, HIGH); // turn on "Armed" light just in case it's not on yet 182 // Send "Armed" SMS: 183 bool success = twilio->send_message(to_number, from_number, messageArmed, response); 184 if (success) { 185 digitalWrite(SmsErrLed, LOW); 186 digitalWrite(OkLed, HIGH); // because of SMS was sent, WiFi must also be OK 187 } else { 188 digitalWrite(SmsErrLed, HIGH); 189 } 190 // Start Inhibit timer (minute to get out of the room): 191 PreArmInhibit = true; 192 prearmtimer = millis(); 193 } 194 } else { // Switch is turned down (off) 195 digitalWrite(ArmLed, LOW); // so turn off Armed LED 196 if (ArmedStat == true) { // i.e. it was just turned to DISARM... 197 // Send "Disarmed" SMS: 198 bool success = twilio->send_message(to_number, from_number, messageDisarmed, response); 199 if (success) { 200 digitalWrite(SmsErrLed, LOW); 201 digitalWrite(OkLed, HIGH); // We can do this because if SMS was sent, WiFi must also be OK 202 } else { 203 digitalWrite(SmsErrLed, HIGH); 204 } 205 ArmedStat = false; // so next loop it knows it's not only just been disarmed, so not another SMS 206 } 207 } 208 209 // ----------------------- 210 // Trigger Event Routines: 211 // ----------------------- 212 if (digitalRead(PIRpin) == HIGH) { // The PIR is giving an trigger indication... 213 digitalWrite(TrigLed, HIGH); // ..so, turn on the Trigger LED just in case it's not on yet. 214 if ((ArmedStat == true) && (PreArmInhibit == false)) { // we are armed and we are not inhibited 215 if (TriggeredStat == false) { // we WERE not triggered, but now we are. 216 // So, send an SMS: we had a motion alert. 217 218 bool success = twilio->send_message(to_number, from_number, messageAlert, response); 219 if (success) { // SMS sent successfully. 220 digitalWrite(SmsErrLed, LOW); 221 digitalWrite(OkLed, HIGH); 222 } else { // uh oh, SMS failure 223 digitalWrite(SmsErrLed, HIGH); 224 digitalWrite(OkLed, LOW); 225 } 226 227 if (digitalRead(SmsErrLed) == HIGH) { // that means we failed - let's try once more 228 delay (250); // Wait 1/4 sec. This is the only time we accept using a DELAY... 229 bool success = twilio->send_message(to_number, from_number, messageAlert, response); 230 if (success) { // SMS sent successfully. 231 digitalWrite(SmsErrLed, LOW); 232 digitalWrite(OkLed, HIGH); 233 } else { // uh oh, SMS failure 234 digitalWrite(SmsErrLed, HIGH); 235 digitalWrite(OkLed, LOW); 236 } 237 } 238 239 if (digitalRead(SmsErrLed) == HIGH) { // that means we failed - let's try again, 3rd and final try 240 delay (250); // Wait 1/4 sec. This is the only time we accept using a DELAY... 241 bool success = twilio->send_message(to_number, from_number, messageAlert, response); 242 if (success) { // SMS sent successfully. 243 digitalWrite(SmsErrLed, LOW); 244 digitalWrite(OkLed, HIGH); 245 } else { // uh oh, SMS failure 246 digitalWrite(SmsErrLed, HIGH); 247 digitalWrite(OkLed, LOW); 248 } 249 } 250 251 TriggeredStat = true; // Trigger status ON (so we won't send another SMS, for a start!) 252 rearmtimer = millis(); // Start the re-arm timer (after which we will turn triggered status off) 253 } 254 } 255 } else { // the PIR is not giving an trigger indication 256 if ((ArmedStat == false) || (PreArmInhibit == true)) { 257 digitalWrite(TrigLed, LOW); // ...we are not [yet] armed, so turn off Trigger LED after PIR stops activating 258 TriggeredStat = false; // also, since we are not armed and not triggered, turn off triggered status 259 } 260 } 261 262 // If we are past the rearm timer, re-arm the system, ie turn off blue LED & get ready to send SMS if triggered+armed 263 // It is safe to do this even when we are not armed: all it does is say we are not triggered and turn off blue LED. 264 // It is better to do this unnecessarily than to risk missing a condition and not re-arming in error. 265 // This will never happen within an hour of sending a trigger SMS (that's what this condition is for) 266 if (((millis() - rearmtimer) > rearmdelay) && (digitalRead(PIRpin) == LOW)) { 267 digitalWrite(TrigLed, LOW); // ...we are not triggered, so turn off Trigger LED after PIR stops activating 268 TriggeredStat = false; // also, since we are not armed and not triggered, turn off triggered status 269 } 270 271 //--end of loop code here-- 272 // 273} 274 275//------------------------------------------------------------------------------------------- 276// THE FUNCTIONS (CALLED AS NEEDED): 277//------------------------------------------------------------------------------------------- 278// tbd if needed
Downloadable files
Manual
Project manual inc. photos and code (download)
file.None
Documentation
Manual
Full project manual
Intrudalizer Manual.pdf
Comments
Only logged in users can leave comments
michaelwillems
0 Followers
•0 Projects
+1
Work attribution
Table of contents
Intro
0
0