Code with SparkCorePolledTimer:
// This #include statement was automatically added by the Particle IDE.
#include "PietteTech_DHT/PietteTech_DHT.h"
// This #include statement was automatically added by the Particle IDE.
#include "blynk/blynk.h"
// This #include statement was automatically added by the Particle IDE.
#include "SparkCorePolledTimer/SparkCorePolledTimer.h"
// This #include statement was automatically added by the Particle IDE.
#include "Ubidots/Ubidots.h"
#include "math.h"
#define LDRPin A0
#define SmokePin A1
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define BLYNK_PRINT Serial
WidgetLED VSmokeLED(V1); // Registered to Virtual Pin 1
WidgetLED VTempLED(V3); // Registered to Virtual Pin 3
WidgetLED VHumidLED(V4); //Registered to Virtual Pin 4
WidgetLED VBuzzLED(V6); //Registered to Virtual Pin 6
// DHT Declaration
void dht_wrapper(); // must be declared before the lib initialization
// Initializing DHT Library
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
// DHT Globals
unsigned long DHTnextSampleTime; // Next time we want to start sample
bool DHTStarted; // flag to indicate we started acquisition
int d; // counter
SparkCorePolledTimer updateTimer1(1000); //Create a timer object and set it's timeout in milliseconds
void FireSmoke(void);
SparkCorePolledTimer updateTimer2(5000); //Create a timer object and set it's timeout in milliseconds
void TemperatureHumidity(void); //Prototype for timer callback method
// float h, t, f, c, hi, dp;
// int m, sRaw, l, lRaw;
//this is coming from http://www.instructables.com/id/Datalogging-with-Spark-Core-Google-Drive/?ALLSTEPS
char szMsg[256]; // buffer for all sorts of messages
char auth[] = "";
char VERSION[8] = "0.04";
// UBI Dots //
#define TOKEN "" // Put here your Ubidots TOKEN
Ubidots ubidots(TOKEN);
// Pin Allocate //
int ActLED = D7;
int buzzPin = D6;
// Initial Activity & Alert States //
int actState = LOW; // Particle Photon & Blynk's Initial Activity State
int Buzzer = HIGH;
int Push = HIGH;
int Email = HIGH;
// Blynk First Connection Flag
bool isFirstConnect = true; // Keep this flag not to re-sync on every reconnection
BLYNK_CONNECTED()
{
// Serial.println("Blynk: Connected");
if (isFirstConnect) {
// Serial.println("Blynk: First Connected");
Blynk.syncVirtual(V21); // Syncs Virtual Pin 21
Blynk.syncVirtual(V22); // Syncs Virtual Pin 22
Blynk.syncVirtual(V23); // Syncs Virtual Pin 23
Blynk.syncVirtual(V24); // Syncs Virtual Pin 24
Blynk.syncVirtual(V29); // Syncs Virtual Pin 29
Blynk.syncVirtual(V31); // Syncs Virtual Pin 31
isFirstConnect = false;
// Serial.println("Blynk: Virtual Pins Synced");
}
}
// Initial Alert Threshold Values //
int SmokeThreshold = 420;
int FireThreshold = 220;
int TempThreshold = 40;
int HumidThreshold = 90;
// Threshold Controls //
BLYNK_WRITE(V21)
{
// Serial.println(param.asInt());
// Serial.println("Blynk: Setting Smoke Threshold");
SmokeThreshold = (param.asInt());
}
BLYNK_WRITE(V22)
{
// Serial.println(param.asInt());
// Serial.println("Blynk: Setting Fire Threshold");
FireThreshold = (param.asInt());
}
BLYNK_WRITE(V23)
{
// Serial.println(param.asInt());
// Serial.println("Blynk: Setting Temp Threshold");
TempThreshold = (param.asInt());
}
BLYNK_WRITE(V24)
{
// Serial.println(param.asInt());
// Serial.println("Blynk: Setting Humid Threshold");
HumidThreshold = (param.asInt());
}
// Buzzer Status Active/Off
BLYNK_WRITE(V29)
{
if (param.asInt())
{
// Serial.println("Blynk: Turning Off Buzzer");
Buzzer = LOW; // Set Buzzer state to LOW
digitalWrite(buzzPin, LOW);
// digitalWrite(ledPin, HIGH);
}
else
{
// Serial.println("Blynk: Turning On Buzzer");
Buzzer = HIGH;
// digitalWrite(ledPin, LOW);
}
}
// Clear Virtual LED Alerts //
BLYNK_WRITE(V30)
{
// Serial.println("Blynk: Clearing LED Alerts");
VSmokeLED.off(); // Virtual Smoke LED
VTempLED.off(); // Virtual Temperature LED
VHumidLED.off(); // Virtual Humidity LED
}
BLYNK_WRITE(V31)
{
if (param.asInt())
{
// Serial.println("Blynk: Turning Off Notify");
Push = LOW;
Email = LOW;
}
else
{
// Serial.println("Blynk: Turning On Notify");
Push = HIGH;
Email = HIGH;
}
}
int calibrationTime = 10; // Sensors Calibration Time, in seconds
// Variables for Surge/Early Detection
int ttimer = 3; // Value in Minutes
int htimer = 3; // Value in Minutes
int stimer = 5; // Value in Seconds
int tdiff = 5; // Value in Degrees
int hdiff = 20; // Value in Percentage
int sdiff = 30; // Difference in the Smoke Sensor's Analogread range of of 0-1023
int firsttemp = true;
int firsthumid = true;
int firstsmoke = true;
// Device Location //
char Location[] = "ilak2k Home";
void Alert(char* Sensor, int AlertType)
{
if (Buzzer)
{
// Serial.println("Activating BuzzPIN LED");
digitalWrite(buzzPin, HIGH); // Activate Buzzer
}
if (AlertType == 1)
{
snprintf(szMsg, sizeof(szMsg), "Emergency: %s Alert! @%s", Sensor, Location);
}
else
{
snprintf(szMsg, sizeof(szMsg), "%s Surge Detected! @%s", Sensor, Location);
}
if (Push)
{
// Serial.print("Sending Notification: ");
Serial.println(szMsg);
Blynk.notify(szMsg);
// Serial.println("Sent!");
}
if (Email)
{
// Serial.print("Sending Email: ");
Serial.println(szMsg);
Blynk.email("ilak2k@gmail.com", szMsg, "Investigate location");
// Serial.println("Sent!");
}
}
double calc_humidex(double tempC, double DewPoint)
{
double e = 5417.7530*((1/273.16)-(1/(273.16 + DewPoint)));
double h = tempC + 0.5555 * ( 6.11 * exp (e) - 10);
return h;
}
double calc_heat_index(double temperature, double percentHumidity)
{
double hi;
hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094));
if (hi > 79) {
hi = -42.379 +
2.04901523 * temperature +
10.14333127 * percentHumidity +
-0.22475541 * temperature*percentHumidity +
-0.00683783 * pow(temperature, 2) +
-0.05481717 * pow(percentHumidity, 2) +
0.00122874 * pow(temperature, 2) * percentHumidity +
0.00085282 * temperature*pow(percentHumidity, 2) +
-0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);
if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
}
return hi;
}
void dht_wrapper() {
DHT.isrCallback();
}
void setup() {
Serial.begin(9600);
updateTimer1.SetCallback(FireSmoke);
updateTimer2.SetCallback(TemperatureHumidity);
pinMode(ActLED, OUTPUT);
pinMode(buzzPin, OUTPUT);
pinMode(LDRPin, INPUT);
pinMode(SmokePin, INPUT);
Blynk.begin(auth);
Particle.connect();
Particle.publish("DHT22 - firmware version", VERSION, 60, PRIVATE);
ubidots.setDatasourceName("ilak2k Home"); // Uncomment this line to change the DataSource Name.
// Sensors Calibration & Warmup Delay, at startup
Serial.print("Calibrating Sensors");
for(int i = 0; i < calibrationTime; i++)
{
Serial.print(".");
delay(1000);
}
Serial.println(" Complete!");
Serial.println("Sensors, ACTIVE!");
delay(100);
}
void loop() {
Particle.process();
if (WiFi.ready()) {
Blynk.run();
}
updateTimer1.Update();
updateTimer2.Update();
}
void FireSmoke(void) {
// Initialize Variables //
static int scount = 0;
static int s1;
static int s2;
//Blynk Activity LED Status
actState = !actState; // toggle the state
digitalWrite(ActLED, actState);
// Serial.println("Blynk: Blinking Activity LED");
if(WiFi.ready()) {
Blynk.virtualWrite(V0, actState ? 1023 : 0);
}
// Blynk Buzzer LED Status
if (digitalRead(buzzPin) && WiFi.ready())
{
// Serial.println("Blynk: Turning On Virtual Buzz LED");
VBuzzLED.on();
}
else
{
// Serial.println("Blynk: Turning Off Virtual Buzz LED");
VBuzzLED.off();
}
// Read Light Level //
int lightlevel = analogRead(LDRPin);
lightlevel = map(lightlevel, 0, 4095, 0, 100);
if (WiFi.ready()) {
Blynk.virtualWrite(V16, lightlevel);
}
ubidots.add("Ambient Light Level", lightlevel, "context1=value_context1$context2=value_context2"); // Change for your variable name
// Read Smoke Level //
int smokelevel = analogRead(SmokePin);
smokelevel = map(smokelevel, 0, 4095, 0, 1023);
// Serial.print("Current Smoke Level: ");
// Serial.println(smokelevel);
if (WiFi.ready()) {
Blynk.virtualWrite(V17, smokelevel);
ubidots.add("Air Quality Level", smokelevel, "context1=value_context1$context2=value_context2"); // Change for your variable name
// Serial.println("Sending Light/Smoke Levels To UBIDOTS!!!");
ubidots.sendAll();
}
if (smokelevel >= SmokeThreshold) // Multiply by 5 for Photon's Range of 0 - 4095
{
// Serial.printlnf("%d >= %d", smokelevel, SmokeThreshold); // check in case of false positive
if (WiFi.ready()) {
VSmokeLED.on(); // Turn On Virtual Humidity LED
}
Alert("Smoke", 1);
}
// Smoke Alarm
if ((scount == 0) && (firstsmoke == true))
{
s1 = smokelevel;
// Serial.print("Smoke Value 1: ");
// Serial.println(s1);
firstsmoke = false;
}
if (scount == stimer)
{
s2 = smokelevel;
// Serial.printlnf("Smoke Value 1: %d | Smoke Value 2: %d | Smoke Difference: %d", s1, s2, (s2-s1));
if ((s2 - s1) >= sdiff)
{
if (WiFi.ready()) {
VSmokeLED.setValue(127); // Set Virtual Smoke LED to 50% Brightness
}
Alert("Smoke", 2);
}
scount = 0;
s1 = s2;
}
scount++;
}
void TemperatureHumidity(void) { //Handler for the timer, will be called automatically
static int tcount = 0;
static int t1;
static int t2;
static int hcount = 0;
static int h1;
static int h2;
if (!DHTStarted) { // start the sample
Serial.print(d);
Serial.print(": Retrieving information from DHT22 Sensor: ");
DHT.acquire();
DHTStarted = true;
}
if (!DHT.acquiring()) { // Has sample completed?
// get DHT status
int result = DHT.getStatus();
Serial.print("Read sensor: ");
switch (result) {
case DHTLIB_OK:
Serial.println("OK");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Error\n\r\tChecksum error");
break;
case DHTLIB_ERROR_ISR_TIMEOUT:
Serial.println("Error\n\r\tISR time out error");
break;
case DHTLIB_ERROR_RESPONSE_TIMEOUT:
Serial.println("Error\n\r\tResponse time out error");
break;
case DHTLIB_ERROR_DATA_TIMEOUT:
Serial.println("Error\n\r\tData time out error");
break;
case DHTLIB_ERROR_ACQUIRING:
Serial.println("Error\n\r\tAcquiring");
break;
case DHTLIB_ERROR_DELTA:
Serial.println("Error\n\r\tDelta time to small");
break;
case DHTLIB_ERROR_NOTSTARTED:
Serial.println("Error\n\r\tNot started");
break;
default:
Serial.println("Unknown error");
break;
}
if (result == DHTLIB_OK)
{
Serial.println("DHT22 Read Complete!. Computing Values...");
double temp = DHT.getCelsius();
double relhumid = DHT.getHumidity();
double dewpt = DHT.getDewPoint();
double humidex = calc_humidex(temp, dewpt);
double heatindex = calc_heat_index(temp, relhumid);
if (WiFi.ready()) {
// Virtual Write & Publish Readings to Blynk
snprintf(szMsg, sizeof(szMsg), "%.1lf", temp);
Blynk.virtualWrite(V11, szMsg);
ubidots.add("Temperature", temp, "context1=value_context1$context2=value_context2"); // Change for your variable name
snprintf(szMsg, sizeof(szMsg), "%.1lf", relhumid);
Blynk.virtualWrite(V12, szMsg);
ubidots.add("Relative Humidity", relhumid, "context1=value_context1$context2=value_context2"); // Change for your variable name
snprintf(szMsg, sizeof(szMsg), "%.1lf", dewpt);
Blynk.virtualWrite(V13, szMsg);
snprintf(szMsg, sizeof(szMsg), "%.1lf", heatindex);
Blynk.virtualWrite(V14, szMsg);
snprintf(szMsg, sizeof(szMsg), "%.1lf", humidex);
Blynk.virtualWrite(V15, szMsg);
Serial.println("Sending Environment Data To UBIDOTS!!!");
ubidots.sendAll();
}
snprintf(szMsg, sizeof(szMsg), "Temperature: %.1lf°C | Relative Humidity %.1lf%% | Dew Point: %.1lf°C | Humidex: %.1lf°C", temp, relhumid, dewpt, humidex);
Serial.println(szMsg);
Particle.publish("AmbientData", szMsg, PRIVATE);
// Temperature Alarm
if (temp >= TempThreshold)
{
Serial.printlnf("%.1lf >= %d", temp, TempThreshold); // check in case of false positive
if(WiFi.ready()) {
VTempLED.on(); // Turn On Virtual Temperature LED
}
Alert("Temperature", 1);
}
// Relative Humidity Alarm
if (relhumid >= HumidThreshold)
{
Serial.printlnf("%.1lf >= %d", relhumid, HumidThreshold); // check in case of false positive
if(WiFi.ready()) {
VHumidLED.on(); // Turn On Virtual Humidity LED
}
Alert("Humidity", 1);
}
// Temperature/Humidity Surge Alert System
if ((tcount == 0) && (firsttemp == true))
{
t1 = temp;
// Serial.print("Temp Value: ");
// Serial.println(t1);
firstsmoke = false;
}
if (tcount == (ttimer * 6)) // Multiplied by 6 instead of 60, cause the Temperature Function runs only every 10 seconds
{
t2 = temp;
// Serial.print("Temp Difference: ");
// Serial.println(t2-t1);
if ((t2 - t1) >= tdiff)
{
Serial.printlnf("Temp Value 1: %d | Temp Value 2: %d | Temp Difference: %d", t1, t2, (t2-t1));
if(WiFi.ready()) {
VTempLED.setValue(127); // Set Virtual Temperature LED to 50% Brightness
}
Alert("Temperature", 2);
}
tcount = 0;
t1 = t2;
}
tcount++;
if ((hcount == 0) && (firsthumid == true))
{
h1 = relhumid;
// Serial.print("Humidity Value 1: ");
// Serial.println(h1);
firsthumid = false;
}
if (hcount == (htimer * 6)) // Multiplied by 6 instead of 60, cause the Temperature Function runs only every 10 seconds
{
h2 = relhumid;
// Serial.print("Humidity Value 2: ");
// Serial.println(h2);
// Serial.print("Humidity Difference: ");
// Serial.println(h2-h1);
if ((h2 - h1) >= hdiff)
{
Serial.printlnf("%.1lf - %.1lf", h2, h1); // check in case of false positive
Serial.printlnf("Humidity Value 1: %d | Humidity Value 2: %d | Humidity Difference: %d", h1, h2, (h2-h1));
if(WiFi.ready()) {
VHumidLED.setValue(127); // Set Virtual Humidity LED to 50% Brightness
}
Alert("Humidity", 2);
}
hcount = 0;
h1 = h2;
}
hcount++;
}
else
{
Serial.println("Cannot Read From DHT22!");
}
d++; // increment counter
DHTStarted = false; // reset the sample flag so we can take another
}
}