Skip to content

Commit ae32f14

Browse files
authored
Merge pull request #69 from adafruit/io-home-security
Adding Sketch for: IO Home #2: Home Security
2 parents 2d3cccb + 65b8974 commit ae32f14

File tree

2 files changed

+341
-0
lines changed

2 files changed

+341
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/************************ Adafruit IO Config *******************************/
2+
3+
// visit io.adafruit.com if you need to create an account,
4+
// or if you need your Adafruit IO key.
5+
#define IO_USERNAME "YOUR_AIO_USERNAME"
6+
#define IO_KEY "YOUR_AIO_KEY"
7+
8+
/******************************* WIFI **************************************/
9+
10+
// the AdafruitIO_WiFi client will work with the following boards:
11+
// - HUZZAH ESP8266 Breakout -> https://www.adafruit.com/products/2471
12+
// - Feather HUZZAH ESP8266 -> https://www.adafruit.com/products/2821
13+
// - Feather M0 WiFi -> https://www.adafruit.com/products/3010
14+
// - Feather WICED -> https://www.adafruit.com/products/3056
15+
16+
#define WIFI_SSID "YOUR_WIFI_SSID"
17+
#define WIFI_PASS "YOUR_WIFI_PASS"
18+
19+
// comment out the following two lines if you are using fona or ethernet
20+
#include "AdafruitIO_WiFi.h"
21+
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
22+
23+
24+
/******************************* FONA **************************************/
25+
26+
// the AdafruitIO_FONA client will work with the following boards:
27+
// - Feather 32u4 FONA -> https://www.adafruit.com/product/3027
28+
29+
// uncomment the following two lines for 32u4 FONA,
30+
// and comment out the AdafruitIO_WiFi client in the WIFI section
31+
// #include "AdafruitIO_FONA.h"
32+
// AdafruitIO_FONA io(IO_USERNAME, IO_KEY);
33+
34+
35+
/**************************** ETHERNET ************************************/
36+
37+
// the AdafruitIO_Ethernet client will work with the following boards:
38+
// - Ethernet FeatherWing -> https://www.adafruit.com/products/3201
39+
40+
// uncomment the following two lines for ethernet,
41+
// and comment out the AdafruitIO_WiFi client in the WIFI section
42+
// #include "AdafruitIO_Ethernet.h"
43+
// AdafruitIO_Ethernet io(IO_USERNAME, IO_KEY);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
// Adafruit IO House: Security System
2+
//
3+
// Learn Guide: https://learn.adafruit.com/adafruit-io-home-security
4+
//
5+
// Adafruit invests time and resources providing this open source code.
6+
// Please support Adafruit and open source hardware by purchasing
7+
// products from Adafruit!
8+
//
9+
// Written by Brent Rubell for Adafruit Industries
10+
// Copyright (c) 2018 Adafruit Industries
11+
// Licensed under the MIT license.
12+
//
13+
// All text above must be included in any redistribution.
14+
15+
/************************** Configuration ***********************************/
16+
17+
// edit the config.h tab and enter your Adafruit IO credentials
18+
// and any additional configuration needed for WiFi, cellular,
19+
// or ethernet clients.
20+
#include "config.h"
21+
22+
// include the NeoPixel library
23+
#include "Adafruit_NeoPixel.h"
24+
25+
// include the SGP30 library
26+
#include <Wire.h>
27+
#include "Adafruit_SGP30.h"
28+
29+
/************************ Example Starts Here *******************************/
30+
31+
// delay the main `io.run()` loop
32+
#define LOOP_DELAY 3000
33+
// delay for each sensor send to adafruit io
34+
#define SENSOR_DELAY 1000
35+
36+
// PIR sensor input pin
37+
#define pirPin 13
38+
// reed switch input pin
39+
#define doorPin 2
40+
// piezo (alarm) buzzer
41+
#define piezoPin 14
42+
43+
/**** Time Setup ****/
44+
// set the hour to start at
45+
int startingHour = 1;
46+
// set the second to start at
47+
int seconds = 56;
48+
// set the minutes to start at
49+
int minutes = 56;
50+
// set the hour at which the motion alarm should trigger
51+
int alarmHour = 16;
52+
53+
unsigned long currentTime = 0;
54+
unsigned long prevTime = 0;
55+
int currentHour = startingHour;
56+
57+
58+
/*********NeoPixel Setup*********/
59+
// pin the NeoPixel strip and jewel are connected to
60+
#define NEOPIXEL_PIN 12
61+
// amount of neopixels on the NeoPixel strip
62+
#define STRIP_PIXEL_COUNT 60
63+
#define JEWEL_PIXEL_COUNT 7
64+
// type of neopixels used by the NeoPixel strip and jewel.
65+
#define PIXEL_TYPE NEO_GRB + NEO_KHZ800
66+
// init. neoPixel Strip
67+
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_PIXEL_COUNT, NEOPIXEL_PIN, PIXEL_TYPE);
68+
69+
// sketch starts assuming no motion is detected
70+
int pirState = LOW;
71+
// sketch starts assuming the the door is closed
72+
int doorState = LOW;
73+
// alarm state
74+
bool isAlarm = false;
75+
// variable for reading the pin status
76+
int pirRead = 0;
77+
// SGP30 Sensor Object
78+
Adafruit_SGP30 sgp;
79+
80+
/*** Adafruit IO Feed Setup ***/
81+
// 'indoor-lights' feed
82+
AdafruitIO_Feed *indoorLights = io.feed("indoor-lights");
83+
// `outdoor-lights` feed
84+
AdafruitIO_Feed *outdoorLights = io.feed("outdoor-lights");
85+
// `front-door` feed
86+
AdafruitIO_Feed *frontDoor = io.feed("front-door");
87+
// `motion-detector` feed
88+
AdafruitIO_Feed *motionFeed = io.feed("motion-detector");
89+
// `home-alarm` feed
90+
AdafruitIO_Feed *alarm = io.feed("home-alarm");
91+
// 'tvoc' feed
92+
AdafruitIO_Feed *tvocFeed = io.feed("tvoc");
93+
// 'eco2' feed
94+
AdafruitIO_Feed *eco2Feed = io.feed("eco2");
95+
96+
void setup() {
97+
// start the serial connection
98+
Serial.begin(115200);
99+
100+
// wait for serial monitor to open
101+
while(! Serial);
102+
Serial.println("Adafruit IO Home: Security");
103+
104+
Serial.println("Connecting to Adafruit IO");
105+
// start MQTT connection to io.adafruit.com
106+
io.connect();
107+
108+
// attach a message handler for the `home-alarm` feed
109+
alarm->onMessage(handleAlarm);
110+
// subscribe to lighting feeds and register message handlers
111+
indoorLights->onMessage(indoorLightHandler);
112+
outdoorLights->onMessage(outdoorLightHandler);
113+
114+
// wait for an MQTT connection
115+
// NOTE: when blending the HTTP and MQTT API, always use the mqttStatus
116+
// method to check on MQTT connection status specifically
117+
while(io.mqttStatus() < AIO_CONNECTED) {
118+
Serial.print(".");
119+
delay(500);
120+
}
121+
// we are connected
122+
Serial.println();
123+
Serial.println(io.statusText());
124+
125+
// declare PIR sensor as input
126+
pinMode(pirPin, INPUT);
127+
// declare reed switch as input
128+
pinMode(doorPin, INPUT);
129+
// set up the SGP30 sensor
130+
setupSGP30();
131+
// init the neopixel strip and set to `off`
132+
strip.begin();
133+
strip.show();
134+
}
135+
136+
void loop(){
137+
// io.run(); is required for all sketches.
138+
// it should always be present at the top of your loop
139+
// function. it keeps the client connected to
140+
// io.adafruit.com, and processes any incoming data.
141+
io.run();
142+
143+
getTime();
144+
Serial.println("* read door sensor...");
145+
readDoorSensor();
146+
Serial.println("* read motion detector");
147+
readPIR();
148+
Serial.println("* reading SGP30...");
149+
readSGP30();
150+
151+
// check if the alarm toggle is armed from the dashboard
152+
if (isAlarm == true) {
153+
if (doorState == HIGH || (currentHour>alarmHour && pirState == HIGH)) {
154+
playAlarmAnimation();
155+
}
156+
}
157+
}
158+
159+
void playAlarmAnimation() {
160+
// plays the alarm piezo buzzer and turn on/off neopixels
161+
Serial.println("ALARM TRIGGERED!");
162+
tone(piezoPin, 220, 2);
163+
for(int i=0; i<JEWEL_PIXEL_COUNT; ++i) {
164+
strip.setPixelColor(i, 255, 0, 0);
165+
}
166+
strip.show();
167+
delay(500);
168+
for(int i=0; i<JEWEL_PIXEL_COUNT; ++i) {
169+
strip.setPixelColor(i, 0, 0, 0);
170+
}
171+
strip.show();
172+
}
173+
174+
void readDoorSensor() {
175+
// reads the status of the front door and sends to adafruit io
176+
doorState = digitalRead(doorPin);
177+
if (doorState == LOW) {
178+
Serial.println("* Door Closed");
179+
frontDoor->save(1);
180+
} else {
181+
Serial.println("* Door Open");
182+
frontDoor->save(3);
183+
}
184+
delay(SENSOR_DELAY);
185+
}
186+
187+
void readPIR() {
188+
// check if motion is detected in front of the home
189+
pirRead = digitalRead(pirPin);
190+
if (pirRead == HIGH) {
191+
if (pirState == LOW) {
192+
// we have just turned on
193+
Serial.println("* Motion detected in front of home!");
194+
motionFeed->save(3);
195+
pirState = HIGH;
196+
}
197+
}
198+
else {
199+
if (pirState == HIGH) {
200+
Serial.println("* Motion ended.");
201+
motionFeed->save(0);
202+
pirState = LOW;
203+
}
204+
}
205+
delay(SENSOR_DELAY);
206+
}
207+
208+
void readSGP30() {
209+
// reads the SGP30 sensor and sends data to Adafruit IO
210+
if (! sgp.IAQmeasure()) {
211+
Serial.println("Measurement failed");
212+
return;
213+
}
214+
Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t");
215+
Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm");
216+
tvocFeed->save(int(sgp.TVOC));
217+
delay(SENSOR_DELAY/2);
218+
eco2Feed->save(int(sgp.eCO2));
219+
delay(SENSOR_DELAY/2);
220+
}
221+
222+
/*** MQTT messageHandlers ***/
223+
void handleAlarm(AdafruitIO_Data *data) {
224+
// handle the alarm toggle on the Adafruit IO Dashboard
225+
String toggleValue = data->toString();
226+
Serial.print("> rcv alarm: ");
227+
Serial.println(toggleValue);
228+
if(toggleValue == String("ON")) {
229+
Serial.println("* Alarm Set: ON");
230+
isAlarm = true;
231+
} else {
232+
Serial.println("* Alarm Set: OFF");
233+
isAlarm = false;
234+
}
235+
}
236+
237+
// handles the indoor light colorpicker on the Adafruit IO Dashboard
238+
void indoorLightHandler(AdafruitIO_Data *data) {
239+
Serial.print("-> indoor light HEX: ");
240+
Serial.println(data->value());
241+
long color = data->toNeoPixel();
242+
// set the color of each NeoPixel in the jewel
243+
for(int i=0; i<JEWEL_PIXEL_COUNT; ++i) {
244+
strip.setPixelColor(i, color);
245+
}
246+
// 'set' the neopixel jewel to the new color
247+
strip.show();
248+
}
249+
250+
// handles the outdoor light colorpicker on the Adafruit IO Dashboard
251+
void outdoorLightHandler(AdafruitIO_Data *data) {
252+
Serial.print("-> outdoor light HEX: ");
253+
Serial.println(data->value());
254+
long color = data->toNeoPixel();
255+
// set the color of each NeoPixel in the strip
256+
for(int i=JEWEL_PIXEL_COUNT; i<STRIP_PIXEL_COUNT+JEWEL_PIXEL_COUNT; ++i) {
257+
strip.setPixelColor(i, color);
258+
}
259+
// 'set' the neopixel strip to the new color
260+
strip.show();
261+
}
262+
263+
264+
void setupSGP30(){
265+
// sets up the SGP30 Sensor
266+
if (! sgp.begin()) {
267+
Serial.println("Sensor not found :(");
268+
while (1);
269+
}
270+
Serial.print("Found SGP30 serial #");
271+
Serial.print(sgp.serialnumber[0], HEX);
272+
Serial.print(sgp.serialnumber[1], HEX);
273+
Serial.println(sgp.serialnumber[2], HEX);
274+
}
275+
276+
void getTime() {
277+
currentTime = millis()/1000;
278+
seconds = currentTime - prevTime;
279+
280+
if (seconds == 60) {
281+
prevTime = currentTime;
282+
minutes += 1;
283+
}
284+
if (minutes == 60) {
285+
minutes = 0;
286+
currentHour += 1;
287+
}
288+
if (currentHour == 24) {
289+
currentHour = 0;
290+
}
291+
292+
Serial.print("Time:");
293+
Serial.print(currentHour);
294+
Serial.print(":");
295+
Serial.print(minutes);
296+
Serial.print(":");
297+
Serial.println(seconds);
298+
}

0 commit comments

Comments
 (0)