[SOLVED] Blynk causing Photon to Blink Cyan... Sometimes forever!

Hi there!
The app I’m trying to execute on Particle Photon, frequently stalls within a duration of 20 secs to 10 minutes…
While using SparkCorePolledTimer to execute two functions…

  1. The device’s loop stops… (I know this with a Physical & Virtual Activity LED)
  2. Starts breathing green for 1-2 minutes
  3. Then blinks Cyan for 30 seconds
  4. Followed by rapid flashing Cyan
  5. And then starts to breathe Cyan
  6. And the loop starts back up…

While using milis() as an interval timer to execute two functions…

  1. The device’s loop stops… (Confirmed with a physical & Virtual Activity LED)
  2. Blinks Cyan for 30 seconds
    From here one of 2 options will happen…
    Option a) At times, it’ll flash Cyan forever… We have no choice but to do a physical reset to get the device back on its loop…
    Option b) Followed by rapid flashing Cyan… Then starts to breathe Cyan… And the loop starts back up…

I also update data to, 1) Particle Cloud & 2) UBIDots
If I disable all Blynk events & Blynk.run()… It runs forever without issues…

Refer to the attached picture here… Its so frequent!

Please post your code for a complete picture

@vshymanskyy - please check on your end

@Pavel @vshymanskyy

Code with millis:

SYSTEM_THREAD(ENABLED);

// #define BLYNK_DEBUG
// #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space

// 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 "PietteTech_DHT/PietteTech_DHT.h"

// This #include statement was automatically added by the Particle IDE.
#include "Ubidots/Ubidots.h"

// For Mathematical Operations
#include "math.h"

// #define ActLED D7
// #define buzzPin D6
#define LDRPin A0
#define SmokePin A1
#define DHTTYPE DHT22   // Choose if you're using DHT11 / DHT22
#define DHTPIN 2 // DHT22's Data Pin to Arduino's Digital Pin 7
#define DHT_SAMPLE_INTERVAL 10000    // Sample every two seconds
#define FIRE_SMOKE_INTERVAL 1000     // Sample every half second

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

unsigned long FireSmokenextSampleTime;
int fs;

//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

//DANGER - DO NOT SHARE!!!!
char auth[] = ""; // Put your blynk token here
//DANGER - DO NOT SHARE!!!!
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);
        if(WiFi.ready()) {
            Blynk.notify(szMsg);
        }
        // Serial.println("Sent!");
    }

    if (Email)
    {
        // Serial.print("Sending Email: ");
        Serial.println(szMsg);
        if(WiFi.ready()) {
        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);
    Serial.println("Hi!");
    ubidots.setDatasourceName("ilak2k Home"); // Uncomment this line to change the DataSource Name.
    Blynk.begin(auth);
    Particle.publish("DHT22 - firmware version", VERSION, 60, PRIVATE);
    pinMode(ActLED, OUTPUT);
    pinMode(buzzPin, OUTPUT);
    pinMode(LDRPin, INPUT);
    pinMode(SmokePin, INPUT);
    
    // 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);
    
    // timer1.start();
    // timer2.start();
    DHTnextSampleTime = 0;  // Start the first sample immediately
    FireSmokenextSampleTime = 0;
}

void loop() {
    if (WiFi.ready()) {
        Blynk.run();
    }
    if (millis() > FireSmokenextSampleTime)  {
        // Serial.printlnf("System Memory is: %d",System.freeMemory());
	   // Serial.print(fs);
	   // Serial.print(": Retrieving information from Fire Smoke sensor: ");

        // 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))
        {
            // Serial.println("Blynk: Turning On Virtual Buzz LED");
            if(WiFi.ready()) {
                VBuzzLED.on();
            }
        }
        else
        {
            // Serial.println("Blynk: Turning Off Virtual Buzz LED");
            if(WiFi.ready()) {
                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!!!");
        if(WiFi.ready()) {
            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++;
        fs++;
        FireSmokenextSampleTime = millis() + FIRE_SMOKE_INTERVAL;  // set the time for next sample
    }

    // Check if we need to start the next sample
    if (millis() > DHTnextSampleTime) {
      
        //  Temperature, Relative Humidity, Dew Point
        // to reduce global variables make them local and static
        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 heatindex = calc_heat_index(temp, relhumid);
                double humidex = calc_humidex(temp, dewpt);

                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);
                if(Particle.connected()) {
                    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
    	    DHTnextSampleTime = millis() + DHT_SAMPLE_INTERVAL;  // set the time for next sample
	    }
    }
}

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
	}
}

Please also connect to your device via Serial Monitor (Putty, etc) and see what’s going on…

@vshymanskyy Do you mean Serial Monitoring via USB? I used Arduino IDE’s Serial Monitor… Or, is it something else? Refer to the attached screenshots of Serial Monitor Data…

Serial Screenshot #1: App’s Activity

Serial Screenshot #2: While particle photon stops running loop()… And then starts to blink Cyan 10 secs later

Serial Screenshot #3: After blinking Cyan for 20-30 secs, starts breathing Cyan and then the loop() starts backup…

Well! Yesterday, my Internet Service went down completely. Had to call a service technician… And ever since he fixed, Photon with Blynk & UBIDOTS has not disconnected ever, in the past 24hrs!

So, I believe, since Blynk maintains an Internet Link at very close intervals with its Blynk.run() in loop, it looked as if Blynk itself is the source of the issue, while its not… Blynk just exposed a weakness with the ISP Service with its rapid internet connectivity requirement… I hope that fixes the whole connection dropout issue here!

Thanks @Pavel @vshymanskyy for your efforts in helping me out…
It has always been an ISP issue! Thank you very much!

Ok! All is not fixed @Pavel @vshymanskyy Particle photon works as far as I don’t access Blynk App on my Android… And when I do, the moment I accessed Blynk App, The Device Goes Offline!

Or, when I get notified of an event:

  1. I see the notification
  2. I open Blynk App to see whats wrong and the device is already offline and I couldn’t check status
  3. I wait for 30-60 secs for the device to reconnect
    This is bad!

And this happens every single time…

And when it does, it takes around 30 seconds to come back up. And it comes back up every single time!

Can you try to run the Blynk example sketch and see if it works.

I have 3 photons running with no issues. So I believe that something is within your code.

Cool! Ill try that! May be, I’m sending and receiving too much than what’s allowed every second. I know there’s a limit for Push/Email Notifications. Do you have a per sec limit on other data exchanged between device and app?

Yes. 100 req/sec per connection.

Found it! :smiley:

I was uploading too many values from Particle Photon.
I was calling ubidots.sendAll():

  1. Every second for Air Quality
  2. Every 10 seconds for Temperature & Humidity

Device is already running Blynk & Particle Cloud. Now, executing ubidots.sendAll() once doesn’t affect… But when it executes twice every 10 seconds. That’s when loop() activity stops, device goes offline, reconnects,…

Solved Now!

Blynk Example sketch worked fine… got me convinced there’s no issue with Blynk… that helped me find what the real issue is… Thanks @Pavel

1 Like