/*This sketch uses the Arduino MKR WiFi 1010, Arduino MKR Connector Carrier and Seeed Studios Grove Sound Sensor
to sense the audible alarm output of a traditional smoke, fire or carbon monoxide alarm and send an Internet push notification the the Pushsafer web
service to the Pushsafer smart phone app.
Created July 8, 2022 13:31 by Andy Meranda*/
//Include libraries
#include <RTCZero.h>
#include <WiFiNINA.h>
#include <WiFiClient.h>
#include <Pushsafer.h>
#include "arduino_secrets.h"
//Constants
const long EDT = -14400; //Eastern Daylight Time adjustment
const long EST = -18000; //Eastern Standard Time adjustment
const long TIMEADJUST = EDT; //Set time adjustment
const int sensorThreshold = 475; //Sound sensor threshold level
//Private credentials for wifi and Pushsafer from arduino_secrets.h
String dev = SECRET_DEV; //Device name for notification
String msg = SECRET_MSG; //Message for notification
char ssid[] = SECRET_SSID; // wifi network SSID (name)
char password[] = SECRET_PASS; // wifi network password
char PushsaferKey[] = SECRET_KEY; // pushsafer private key
//Object declarations
WiFiClient client; // The wifi client object is used for pushsafer notification
Pushsafer pushsafer(PushsaferKey, client); // Pushsafer object to send event
RTCZero rtc; // Real time clock object
//variables
uint32_t epoch; //Used to get WiFiNINA time
unsigned long int lastpush = 0; //Timestamp of last push notification to limit number of notifications
String dtstg = String(__DATE__); //Compiler date for initial RTC setting
String tmstg = String(__TIME__); //Compiler time for initial RTC setting
// Executes once on startup
void setup()
{
pinMode(A0,INPUT); //Sound sensor is on pin A0 as input
pinMode(LED_BUILTIN,OUTPUT); //Set LED output pin
Serial.begin(9600); //Serial monitor output for debugging
rtc.begin(); //Start the real time clock;
rtcSet(); //Set the RTC from the compile time
}
// Executes continuously after startup
void loop()
{
// This is the structure of the pushsafer input object
// Change the values for different notifications
struct PushSaferInput input;
input.sound = "8";
input.vibration = "1";
input.icon = "1";
input.iconcolor = "#FFCCCC";
input.priority = "1";
input.device = "a";
input.url = "https://www.pushsafer.com";
input.urlTitle = "Open Pushsafer.com";
input.picture = "";
input.picture2 = "";
input.picture3 = "";
input.time2live = "";
input.retry = "";
input.expire = "";
input.answer = "";
int soundLevel = analogRead(A0); //Read the sound sensor
/*If the sound sensor level is high enough and the last notification was more than 5 seconds ago,
then connect to wifi, issue a PushSafer notification and flash the built-in LED 3 times.*/
if (soundLevel > sensorThreshold && (millis() - lastpush) > 5000) {
// Try to connect to wifi up to 20 times at half second intervals
WiFi.begin(ssid, password);
int wifiTries = 0;
while (WiFi.status() != WL_CONNECTED && wifiTries < 20)
{
delay(500);
wifiTries++;
}
//Get time from WiFiNINA module and sync RTC
epoch = WiFi.getTime();
if (epoch > 0) {
rtc.setEpoch(epoch+TIMEADJUST);
}
//Send the PushSafer notification
input.message = msg; //PushSafer message body
input.title = dev+" "+getTime(); //PushSafer message title and time
input.sound = "8"; //PushSafer notification sound
pushsafer.sendEvent(input); //Send the PushSafer notification
lastpush = millis(); //Timestamp the last notification sent
flashLED(3,150); //Flash the LED repetitions and duration to signal notification sent
//Serial print debugging message showing sound sensor level
Serial.print("Fire alarm sound level: ");
Serial.println(soundLevel);
}
delay(1000); //1 second delay between sound sensor reads
}
//Flashes LED specified repetitions and duration
void flashLED(int x, int y) {
for (int i=1;i <= x;i++) {
digitalWrite(LED_BUILTIN,HIGH);
delay(y);
digitalWrite(LED_BUILTIN,LOW);
delay(y);
}
}
// Sets the real time clock from the compile date and time
void rtcSet()
{
String months = "JanFebMarAprMayJunJulAugSepOctNovDec"; // Month identifier array
// Parses the compiler DATE string into separate substrings needed to set the RTC
String mm = dtstg.substring(0,3);
String dd = dtstg.substring(4,7);
String yy = dtstg.substring(8,11);
// Convert the date strings to integers needed to set the RTC
int ddnbr = dd.toInt();
int mmnbr = int((months.indexOf(mm)/3)+1);
int yynbr = yy.toInt();
// Parses the compiler TIME string into separate substrings needed to set the RTC
String hh = tmstg.substring(0,2);
String mn = tmstg.substring(3,5);
String ss = tmstg.substring(6,8);
// Convert the time strings to integers needed to set the RTC
int hhnbr = hh.toInt();
int mnnbr = mn.toInt();
int ssnbr = mn.toInt();
// Set the RTC date and time
rtc.setDate(ddnbr,mmnbr,yynbr);
rtc.setTime(hhnbr,mnnbr,ssnbr);
}
// Gets human readable time from the real time clock
String getTime()
{
String yy,mm,dd,hr,mn,se; // String variables to hold the elements of the RTC timestamp
yy = String(rtc.getYear()); // Get the timestamp year from the RTC
if (rtc.getMonth() < 10) // Add a leading month zero if < 10
{
mm = String("0")+String(rtc.getMonth());
} else {
mm = String(rtc.getMonth());
}
if (rtc.getDay() < 10) // Add a leading day zero if < 10
{
dd = String("0")+String(rtc.getDay());
} else {
dd = String(rtc.getDay());
}
if (rtc.getHours() < 10) // Add a leading hour zero if < 10
{
hr = String("0")+String(rtc.getHours());
} else {
hr = String(rtc.getHours());
}
if (rtc.getMinutes() < 10) // Add a leading minute zero if < 10
{
mn = String("0")+String(rtc.getMinutes());
} else {
mn = String(rtc.getMinutes());
}
if (rtc.getSeconds() < 10) // Add a leading second zero if < 10
{
se = String("0")+String(rtc.getSeconds());
} else {
se = String(rtc.getSeconds());
}
// Combine the RTC timestamp elements into a single string
String timestr = mm+"-"+dd+"-"+yy+" "+hr + ":" + mn + ":" + se;
return timestr;
}
Comments
Please log in or sign up to comment.