maulepilot
Published © GPL3+

Smoke/Fire alarm IoT interface

Get smoke or fire alarms anywhere in the world through a simple interface without hacking the detector

IntermediateFull instructions provided260
Smoke/Fire alarm IoT interface

Things used in this project

Hardware components

Arduino MKR WiFi 1010
Arduino MKR WiFi 1010
×1
Arduino MKR Grove Connector Carrier
×1
Seeed Studio Grove Sound Sensor/Noise Detector for Arduino
×1
First Alert SA3210 Dual Sensor Smoke and Fire Alarm
×1
18650 3.7 Volt 4200 mAh Lithium Ion Battery
×1
18650 battery holder
×1

Software apps and online services

PushSafer website
PushSafer app

Story

Read more

Schematics

Wiring photo

Code

Smoke Detector Interface

Arduino
Simple interface between Arduino MKR WiFi 1010 and any commercially available smoke/fire detector without hacking the detector
/*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;
}

Credits

maulepilot
0 projects • 1 follower
Contact

Comments

Please log in or sign up to comment.