Set subscribe handler data as global

Hi, I am using two photon devices communicating via MQTT pub/sub. Device 1 crashes everytime (Disconnects from wifi, blinks cyan, then flash red once and connects back to wifi)10-20seconds after running the code below. Device 2 is stays fine. I assume this is due to stack overflow/buffer overload when getting subscribe event data,

I have tried solving the issue by

  1. Changing the subscribe handler delay from 1000ms to 10000ms, eventually device 1 still crashes after 2 minutes.

  2. Storing subscribe data as global char, print global char in function called displaytemp() and call the function in void loop.

I was still not able to solve this. Your response is greatly appreciated!

Example-

char myGlobalTempData[5]; //Global Temp Data define length

void myTempHandler(const char *event, const char *data){
    strcpy(myGlobalTempData, data);
}

void displaytemp(){
    Serial.print(myGlobalTempData);
}

void setup{
 // 
{

void loop{
    displaytemp();
}

Device 1 -
Publishes two events, ambience and event_change
Subscribes to two events, temp and pressure

Device 2 -
Publishes two events, temp and pressure
Subscribes to ambience

<Device 1 Code>

#include <DailyTimerSpark.h>
#include <blynk.h>

char auth[] = "<---redacted--->";

int led3=D0;             // Blynk Nightlight Control + HTML Nightlight Toggle On/Off
int led3_status=-1;      // HTML Nightlight Toggle On/Off

int ldr=A0;              // Blynk Ambience Brightness 
int ldr_status=0;        // Blynk Ambience Brightness 
int ldranalogvalue=0;    // Blynk Ambience Brightness Gauge

WidgetLCD lcd(V1);       // Blynk LCD (Date Day Greeting)
WidgetLCD lcd2(V3);

// Get Temperature data from subscribed topic and print on LCD

void myTempHandler(const char *event, const char *data){
    double temp_val = atof(data);
    Serial.println("Temperature Handler executed");
    Serial.println(temp_val);

    char number[24]; // dummy size, you should take care of the size!
    sprintf(number, "%.2f", temp_val);
    String displaywarm=String(number)+"°C Warm";
    String displaycold=String(number)+"°C Cool";

    if(temp_val > 32.50){
        lcd2.print(0,0, displaywarm);
    }
    else{
        lcd2.print(0,0, displaycold);
    }
    delay(10000);
}

void myPressHandler(const char *event, const char *data){
    double press_val = atof(data);
    Serial.println("Pressure Handler executed");
    Serial.println(press_val);
    
    char number[24]; // dummy size, you should take care of the size!
    sprintf(number, "%.2f", press_val);
    String displayhigh=String(number)+"Pa High";
    String displaylow=String(number)+"Pa Low";
    
    if(press_val > 900){
        lcd2.print(0,1, displayhigh); // High Pressure
        digitalWrite(D7, HIGH);
    }
    else{
        lcd2.print(0,1, displaylow);  // Low Pressure
        digitalWrite(D7, LOW);
    }
    delay(10000);
}

void setup(){
    // Nightlight Toggle On/Off
    pinMode(led3, OUTPUT); 
    Particle.function("led",ledToggle);

    // HTML Ambience Brightness Gauge
    pinMode(ldr, INPUT);
    ldr_status=analogRead(ldr);
    ldranalogvalue=ldr_status;
    Particle.variable("ldranalogvalue", &ldranalogvalue, INT);
    
    Blynk.begin(auth); 
     
    // Blynk LCD ADVANCED
    lcd.clear();

    // bLYNK LCD Time Display (Set Timezone to SG using +8)
    Time.zone(+8);  

    // iot_C8 Device MQTT subscribe to Ambience Change Value
    Particle.subscribe("Ambience Change", event_change, MY_DEVICES); 
    
    // iot_C8 MQTT sub to temp and pressure data vals from D8 published temp and pressure readings
    Particle.subscribe("temperature_D8", myTempHandler, MY_DEVICES);
    Particle.subscribe("pressure_D8", myPressHandler, MY_DEVICES);
      
    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
}

void loop(){                         
    // Run Blynk App
    Blynk.run();

    // Ambience Brightness LDR Treshold
    if(analogRead(ldr) >= (ldr_status+30) || analogRead(ldr) <= (ldr_status-30)) //50
    {
        ldr_status = analogRead(ldr);
        Serial.println("Ambience Change");
        Serial.print("LDR Status= ");
        Serial.println(analogRead(ldr));
        Serial.println("     ");
        Particle.publish("Ambience Change", (String)ldr_status, PRIVATE);
        delay(1000);
    }
    
    // Blynk LDR Gauge
    Blynk.virtualWrite(V0, ldranalogvalue);
    
    // Blynk LCD Display (Date + Greeting)
    DisplayTime();
    Greeting();
}

int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led3,HIGH);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led3,LOW);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 0;
    }
    else if (command=="read") {
        return digitalRead(led3);
    }
    else {
        return -1;
    }
}

// iot_C8 Device - MQTT Publish Ambience Room Status (Dark/Bright/Dim) 
void event_change(const char *event, const char *data) { 
     ldranalogvalue=atoi(data);
     if (ldranalogvalue <= 100){    // Modify this in class
         Particle.publish("ambience_C8", "Dark", PRIVATE);
         Serial.println("Ambience Status= Dark");
         Serial.println("Ambience Dark Request triggered");

         delay(1000);
     }
     else if (ldranalogvalue >= 300){
         Particle.publish("ambience_C8", "Bright", PRIVATE);
         Serial.println("Ambience Status= Bright");
         Serial.println("Ambience Bright Request triggered");
         delay(1000);
     }
     else{
         Particle.publish("ambience_C8", "Dim", PUBLIC);
         Serial.println("Ambience Status= Dim");
         Serial.println("Ambience Dim Request triggered");
         delay(1000);
     }
}

void DisplayTime(){
    String time1 = Time.format(Time.now(), "%I:%M%p");
    String date = String(Time.day()); 
    String month = Time.format(Time.month(), "%b");    // abbreviated month name (3 char)
    String day = Time.format(Time.day(), "%a");        // abbreviated day name (3 char)
    String display = day+" "+date+" "+month+"      ";

    lcd.print(0,0, time1); 
    lcd.print(0,1, display);
    delay(1000);
}

void Greeting(){
    MorningDisplay();
    AfternoonDisplay();    
}

void MorningDisplay(){
    DailyTimer MorningTimer(6, 0, 11, 59, EVERY_DAY);  // Fixed start time and end time
    if(MorningTimer.startTrigger()){
        lcd.print(0,1, "Good Morning!");
        delay(2000);
        
        MorningMsg();
        delay(1000);
    }
}

void AfternoonDisplay(){
    DailyTimer AfternoonTimer(12, 0, 17, 59, EVERY_DAY);  // Fixed start time and end time
    if(AfternoonTimer.startTrigger()){
        lcd.print(0,1, "Good Afternoon! ");
        delay(1000);
        
        AfternoonMsg();
        delay(1000);
    }
}

/*
void EveningDisplay(){
    DailyTimer EveningTimer(18, 0, 19, 59, EVERY_DAY);  // Fixed start time and end time
    if(EveningTimer.startTrigger()){
        lcd.print(0,1, "Good Evening!");
        delay(2000);
        
        EveningMsg();
        delay(1000);
        
        EveningMsg2();
        delay(1000);
    }
}

void NightDisplay(){
    DailyTimer NightTimer(20, 0, 23, 59, EVERY_DAY);  // Fixed start time and end time
    if(NightTimer.startTrigger()){
        lcd.print(0,1, "Night Time");
        delay(1000);
        
        NightMsg();
        delay(1000);
    }
}

void MidNightDisplay(){
    DailyTimer MidNightTimer(24, 0, 5, 59, EVERY_DAY);  // Fixed start time and end time
    if(MidNightTimer.startTrigger()){
        lcd.print(0,1, "Mid Night");
        delay(1000);
        
        MidNightMsg();
        delay(1000);
    }
}
*/

void MorningMsg(){
    String text = "Time for Breakfast";
    int space=(strlen(text)-15);                 // Set no. of space for text to move
    for(int start=0; start<space; start++){      // Increment loop
        
        lcd.print(0,1, text.substring(start));   // substring func remove char of string via loop and prints continuously
        delay(1000);
    }
}

void AfternoonMsg(){
    String text = "Lunch Break     ";            // Spaces to avoid other text from overlapping
    lcd.print(0,1, text);   
    delay(1000);
}

<Device 2 Code>

#include <Adafruit_BMP280.h>
#include <blynk.h>

Adafruit_BMP280 bmp; // I2C

char auth[] = "<---redacted--->";  

double env_temp;
double env_Pressure;

// HTML Temp + Press Gage Data
double temp_reading;
double press_reading;

// Blynk Slider + Button
int led1 = D2;

// Get data from subscribed topic ambience_C8, on / off led according to ambience status
void myAmbienceHandler(const char *event, const char *data){
    String ambience_status = String(data);
    Serial.println("Ambience Handler executed");
    Serial.println(ambience_status);

    if(ambience_status == "Dark"){
        digitalWrite(D2, HIGH);
        Serial.println("Led turns on");
        delay(1000);
    }
    else if(ambience_status == "Bright"){
        digitalWrite(D2, LOW);
        Serial.println("Led stays off");
        delay(1000);
    }
    else if(ambience_status == "Dim"){
        digitalWrite(D2, LOW);
        Serial.println("Led stays off");
        delay(1000);
    }
}

void setup() {
    pinMode(led1, OUTPUT);

    // HTML Temp and pressure gauge reading
    Particle.variable("temp", temp_reading);    
    Particle.variable("press", press_reading);    
    
    // iot_D8 Device MQTT subscribe to Temperature and pressure
    Particle.subscribe("ambience_C8", myAmbienceHandler, MY_DEVICES); 

    Blynk.begin(auth); 

    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
 
    if (!bmp.begin()){
        Serial.println("Can't find the sensor BMP280");
    }
 
    if (bmp.begin()){
        Serial.println("DEBUG, starting the environment timer...");
        Particle.publish("DEBUG", "starting the environment timer...");
    }
    else{
        Serial.println("WARN, Could not find a valid BMP280 sensor, check wiring!");
    }

    Serial.println("DEBUG, started!");
    Particle.publish("DEBUG", "started!");
}

void loop() {
    // Run Blynk App
    Blynk.run();
    
    temp_reading = bmp.readTemperature();
    press_reading = bmp.readPressure();
    
    double t_temp = bmp.readTemperature();
    double t_Pressure = bmp.readPressure();

    // Compare temp to env, if change, publish value
    if (t_temp >= env_temp + 0.1 || t_temp <= env_temp - 0.1){
        Particle.publish("temperature_D8", String(t_temp), PRIVATE);
        Serial.println("Temperature Request triggered");
    }
    
    if (t_Pressure >= env_Pressure + 5 || t_Pressure <= env_Pressure - 5){
        Particle.publish("pressure_D8", String(t_Pressure), PRIVATE);
        Serial.println("Pressure Request triggered");
    }
    delay(10000);
}

void checkEnvironment() {
    env_temp = bmp.readTemperature();
    env_Pressure = bmp.readPressure();
}

From reference to this, what I understand is that the data is copied as string and put into global char, and each element from data is assigned into global char as an array.

Hey @kannnyyy, welcome to the Particle community.

If you surround your code with three backticks it will enable syntax highlighting, making it much easier to read.

int example = 0;

image


Alternatively, you could create a private gist of your code on GitHub.

The first thing you want to find out is which of your subscribe handlers is actually causing the crash.
You do have multiple Serial.print() statements in your code, these should provide some hints regarding the place where the crash happens.
If you could tell us too, we may not have to guess as much about the cause is we'd need to without that bit of information :wink:

However, a common advice we give is to avoid using String and rather go with old-fashioned C strings (aka char arrays). You are already using sprintf() (better would be snprintf()) in some places, so I'd suggest you stick with that everywhere.

You can also use Serial.printlnf() to create compound output
e.g.

    Serial.println("Temperature Handler executed");
    Serial.println(temp_val);

simplifies to

    Serial.printlnf("Temperature Handler executed %f.1", temp_val);

Also, why build two extra strings when you only display one?!?!
This simplifies to

    char msg[32];
    snprintf(msg, sizeof(msg), "%.2f°C %s", temp_val, (temp_val > 32.50) ? "Warm" : "Cool");
    lcd2.print(0, 0, msg);

When you then use the same string for Serial.println() you can save even more code lines :wink:

simplifies to

    ldr_status = 
    ldranalogvalue = analogRead(ldr); // analogRead() does NOT require pinMode()
    Particle.variable("ldranalogvalue", ldranalogvalue);

Event names should not contain blanks hence subscribe handlers shouldn't filter for that either

Here it would be better to only analogRead() once and store the data in a variable to be used in the condition

or go with a mathematical approach

  int l = analogRead(ldr);
  if(abs(l - ldr_status) >= 30) {
    char msg[8];
    ldr_status = l;
    Serial.printlnf("Ambience Change\r\nLDR Status = %d\r\n", l);
    snprintf(msg, siztof(msg), "%d", l);
    Particle.pulish("AmbienceChange", msg);
    delay(1000);
  } 
1 Like

Hi ScruffR!! Thank you so much for your swift and detailed response!! I have made changes to my code based on your feedback as well as setting the delay on particle .subscribe(temp) and (pressure) to 5000 and particle.publish(temp) and (pressure) to 5000 as well.

I think I have found the cause of the crash (device1 photon flashes red SOS then connects to wifi, then flashes red SOS and repeats, device2 stays fine)

It was due to

  1. Both particle subscribe (temp) and (pressure) running at same time and particle subscribe (ambience_c8) commented away.
    Putty Serial monitor output:
    Serial is Running
    Blynk is running. Ensure wifi connected on device and app are same
    Temperature Handler executed, 31.190000°C
    Pressure Handler executed, 101007.906250Pa
    Device crashes, Putty inactive

  2. Both particle subscribe (ambience_c8) and (pressure) running at same time and particle subscribe (temp) commented away.
    Putty Serial monitor output:
    Serial is Running
    Blynk is running. Ensure wifi connected on device and app are same
    Pressure Handler executed, 101005.062500Pa
    Pressure Handler executed, 101007.906250Pa
    Device crashes, Putty inactive

When I run particle subscribe (temp) and (ambience_c8) together and particle (pressure) commented away, it works fine.

I think multiple particle subscribe functions sending data every 5 seconds is causing data overload… how can I fix this?

This shouldn’t really pose a major issue.
However, there are some things you can do to drill down on the issue a bit more.

  • add a Serial.printlnf("%s: <%s>", event, data); to all your subscription handlers and see what data actually comes in
  • guard your Blynk calls with a if(Particle.connected() against being called without connection
  • instead of having 2 handlers on and 1 off, rather have only 1 on at any given test time

Also post your updated code so that we know what we are talking about :wink:

BTW, when you have full control over both devices I’d rather use one event that holds all data instead of multiple independent events with dedicated subscribe handlers.

< Device 1 Code>

#include <DailyTimerSpark.h>
#include <blynk.h>

char auth[] = "<---redacted--->";
    
int led3=D0;             // Blynk Nightlight Control + HTML Nightlight Toggle On/Off
int led3_status=-1;      // HTML Nightlight Toggle On/Off

int ldr=A0;              // Blynk Ambience Brightness 
int ldr_status=0;        // Blynk Ambience Brightness 
int ldranalogvalue=0;    // Blynk Ambience Brightness Gauge

WidgetLCD lcd(V1);       // Blynk LCD (Date Day Greeting)
WidgetLCD lcd2(V3);

// Get Temperature data from subscribed topic and print on LCD
void myTempHandler(const char *event, const char *data){
    double temp_val = atof(data);
    Serial.printlnf("Temperature Handler executed, %f°C", temp_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%.2f°C %s", temp_val, (temp_val > 32.50) ? "Warm" : "Cool");
    lcd2.print(0, 0, msg);
    delay(5000);
}

void myPressHandler(const char *event, const char *data){
    double press_val = atof(data);
    Serial.printlnf("Pressure Handler executed, %fPa", press_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%dPa %s", press_val, (press_val > 900) ? "High" : "Low");
    lcd2.print(0, 0, msg);

    /*if(press_val > 900){
        digitalWrite(D7, HIGH);
    }
    
    else{
        digitalWrite(D7, LOW);
    }*/
    delay(5000);
}

void setup() {
    //DisplayTemp();
    DisplayTime();
    Greeting();
    
    // Nightlight Toggle On/Off
    pinMode(led3, OUTPUT); 
    Particle.function("led",ledToggle);

    // HTML Ambience Brightness Gauge
    ldr_status=analogRead(ldr);      // pinMode not needed since analogRead used
    ldranalogvalue=ldr_status;
    //Particle.variable("ldranalogvalue", &ldranalogvalue, INT);
    Particle.variable("ldranalogvalue", ldranalogvalue);
    
    Blynk.begin(auth); 
     
    // Blynk LCD ADVANCED
    lcd.clear();

    // bLYNK LCD Time Display (Set Timezone to SG using +8)
    Time.zone(+8);  

    // IP ADDRESS
    // iot_C8 MQTT sub to temp and pressure data vals from D8 published temp and pressure readings
    //Particle.subscribe("temperature_D8", myTempHandler, MY_DEVICES);
    //Particle.subscribe("pressure_D8", myPressHandler, MY_DEVICES);
    
    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
}

void loop(){                     
    // Run Blynk App
    Blynk.run();

    // iot_C8 Device - MQTT Publish Ambience Room Status (Dark/Bright/Dim) 
    // Ambience Brightness LDR Treshold
    if(analogRead(ldr) >= (ldr_status+30) || analogRead(ldr) <= (ldr_status-30)) //50
    {
        ldr_status = analogRead(ldr);
        Serial.println("Ambience Change");
        Serial.printlnf("LDR Status = %d", ldr_status);

        if (ldr_status <= 100){    // Modify this in class
         Particle.publish("ambience_C8", "Dark", PRIVATE);
         Serial.println("Ambience Status= Dark");
         Serial.println("Ambience Dark Request triggered");
         delay(1000);
        }
     
         else if (ldr_status >= 300){
         Particle.publish("ambience_C8", "Bright", PRIVATE);
         Serial.println("Ambience Status= Bright");
         Serial.println("Ambience Bright Request triggered");
         delay(1000);
        }
     
        else{
         Particle.publish("ambience_C8", "Dim", PUBLIC);
         Serial.println("Ambience Status= Dim");
         Serial.println("Ambience Dim Request triggered");
         delay(1000);
        }
    }
    
    // Blynk LDR Gauge
    Blynk.virtualWrite(V0, ldr_status);
    
    // Blynk LCD Display (Date + Greeting)
    DisplayTime();
    Greeting();
}

int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led3,HIGH);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led3,LOW);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 0;
    }
    else if (command=="read") {
        return digitalRead(led3);
    }

    else {
        return -1;
    }
}

void DisplayTime(){
    String time1 = Time.format(Time.now(), "%I:%M%p");  
    String date = String(Time.day()); 
    String month = Time.format(Time.month(), "%b");    // abbreviated month name (3 char)
    String day = Time.format(Time.day(), "%a");        // abbreviated day name (3 char)
    String display = day+" "+date+" "+month+"      ";

    lcd.print(0,0, time1); 
    lcd.print(0,1, display);
    delay(1000);
}

void Greeting(){
    MorningDisplay();
    AfternoonDisplay();

    //EveningDisplay();
    //NightDisplay();
    //MidNightDisplay();    
}

void MorningDisplay(){
    DailyTimer MorningTimer(6, 0, 11, 59, EVERY_DAY);  // Fixed start time and end time
    if(MorningTimer.startTrigger()){
        lcd.print(0,1, "Good Morning!");
        delay(2000);
        
        MorningMsg();
        delay(1000);
    }
}

void AfternoonDisplay(){
    DailyTimer AfternoonTimer(12, 0, 17, 59, EVERY_DAY);  // Fixed start time and end time
    if(AfternoonTimer.startTrigger()){
        lcd.print(0,1, "Good Afternoon! ");
        delay(1000);
        
        AfternoonMsg();
        delay(1000);
    }
}

<Device 2 Code>

#include <Adafruit_BMP280.h>
#include <blynk.h>

Adafruit_BMP280 bmp; // I2C

char auth[] = "<---redacted--->";  

double env_temp;
double env_Pressure;

// HTML Temp + Press Gage Data
double temp_reading;
double press_reading;

// Blynk Slider + Button
int led1 = D2;

// Get data from subscribed topic ambience_C8, on / off led according to ambience status
void myAmbienceHandler(const char *event, const char *data){
    String ambience_status = String(data);
    Serial.println("Ambience Handler executed");
    Serial.println(ambience_status);

    if(ambience_status == "Dark"){
        digitalWrite(D2, HIGH);
        Serial.println("Led turns on");
        delay(1000);
    }
    else if(ambience_status == "Bright"){
        digitalWrite(D2, LOW);
        Serial.println("Led stays off");
        delay(1000);
    }
    else if(ambience_status == "Dim"){
        digitalWrite(D2, LOW);
        Serial.println("Led stays off");
        delay(1000);
    }
}

void setup() {    
    pinMode(led1, OUTPUT);

    // HTML Temp and pressure gauge reading
    Particle.variable("temp", temp_reading);    
    Particle.variable("press", press_reading);    
    
    // iot_D8 Device MQTT subscribe to Ambience_C8
    Particle.subscribe("ambience_C8", myAmbienceHandler, MY_DEVICES); 

    Blynk.begin(auth); 

    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
 
    if (!bmp.begin()){
        Serial.println("Can't find the sensor BMP280");
    }
 
    if (bmp.begin()){
        Serial.println("DEBUG, starting the environment timer...");
        Particle.publish("DEBUG", "starting the environment timer...");
    }
    
    else{
        Serial.println("WARN, Could not find a valid BMP280 sensor, check wiring!");
    }

    Serial.println("DEBUG, started!");
    Particle.publish("DEBUG", "started!");
}

void loop() {
    // Run Blynk App
    Blynk.run();
    
    temp_reading = bmp.readTemperature();
    press_reading = bmp.readPressure();
    
    double t_temp = bmp.readTemperature();
    double t_Pressure = bmp.readPressure();

    // Compare temp to env, if change, publish value
    if (t_temp >= env_temp + 0.1 || t_temp <= env_temp - 0.1){
        Particle.publish("temperature_D8", String(t_temp), PRIVATE);
        Serial.println("Temperature Request triggered");
    }
    
    if (t_Pressure >= env_Pressure + 5 || t_Pressure <= env_Pressure - 5){
        Particle.publish("pressure_D8", String(t_Pressure), PRIVATE);
        Serial.println("Pressure Request triggered");
    }
    delay(5000);
}

void checkEnvironment() {
    env_temp = bmp.readTemperature();
    env_Pressure = bmp.readPressure();
} 

I will try this out now!

I have reformatted your code and redacted your Blynk token, which you shouldn’t share publicly :wink:

In order to properly format code blocks you wouldn’t use three apostrophes ( ‘’’ ) but rather grave accents ( ``` ) or just use the “preformatted text” feature image at the top of the edit box.

Also (over)use of blank lines doesn’t really make reading code easier. It just drags it out and sometimes makes it even harder to get a feeling for the actual code flow - hence I removed some of your superfluous blank lines and the super-superfluous “// This #include statement was automatically added by the Particle IDE.” comments

Another code simplification

void DisplayTime(){
    lcd.print(0,0, (const char*)Time.format("%I:%M%p")); 
    lcd.print(0,1, (const char*)Time.format("%a %e %b"));
    delay(1000);
}

BTW, since you do have delay(1000) in your display routines anyway, you can remove the delays after your publish calls as there will only ever by one publish per iteration of loop() which will be paced down by the display delays.
I wouldn’t have delay() in the subscribe handlers either.

Thanks! I’ll remember to hide my auth token!

Here is my updated code, I tested with only temp handler subscribed, while publishing ambience_c8 in void loop.

The red SOS comes on based on this serial monitor output:
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 11
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Ambience Change
LDR Status = 45
Ambience Status= Dark
Ambience Dark Request triggered
temperature_D8: <31.379999>
Temperature Handler executed, 31.379999°C
temperature_D8: <31.379999>
Temperature Handler executed, 31.379999°C
temperature_D8: <31.370001>
Temperature Handler executed, 31.370001°C
temperature_D8: <31.370001>
Temperature Handler executed, 31.370001°C

After the red SOS, it reconnects to cloud and shows this:
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online

<Device 1 code>

int led3=D0;             // Blynk Nightlight Control + HTML Nightlight Toggle On/Off
int led3_status=-1;      // HTML Nightlight Toggle On/Off

int ldr=A0;              // Blynk Ambience Brightness 
int ldr_status=0;        // Blynk Ambience Brightness 
int ldranalogvalue=0;    // Blynk Ambience Brightness Gauge

WidgetLCD lcd(V1);       // Blynk LCD (Date Day Greeting)
WidgetLCD lcd2(V3);

// Get Temperature data from subscribed topic and print on LCD
void myTempHandler(const char *event, const char *data){
    double temp_val = atof(data);
    Serial.printlnf("%s: <%s>", event, data);
    
    Serial.printlnf("Temperature Handler executed, %f°C", temp_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%.2f°C %s", temp_val, (temp_val > 32.50) ? "Warm" : "Cool");
    lcd2.print(0, 0, msg);
    delay(5000);
}

/*void myPressHandler(const char *event, const char *data){
    double press_val = atof(data);
    Serial.printlnf("Pressure Handler executed, %fPa", press_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%dPa %s", press_val, (press_val > 900) ? "High" : "Low");
    lcd2.print(0, 0, msg);

    if(press_val > 900){
        digitalWrite(D7, HIGH);
    }
    
    else{
        digitalWrite(D7, LOW);
    }
    delay(5000);
}
*/

void setup(){
    //DisplayTemp();
    DisplayTime();
    Greeting();

    // Nightlight Toggle On/Off
    pinMode(led3, OUTPUT); 
    Particle.function("led",ledToggle);

    // HTML Ambience Brightness Gauge
    ldr_status=analogRead(ldr);      // pinMode not needed since analogRead used
    ldranalogvalue=ldr_status;
    //Particle.variable("ldranalogvalue", &ldranalogvalue, INT);
    Particle.variable("ldranalogvalue", ldranalogvalue);
    
    Blynk.begin(auth); 
     
    // Blynk LCD ADVANCED
    lcd.clear();

    // bLYNK LCD Time Display (Set Timezone to SG using +8)
    Time.zone(+8);  

    // IP ADDRESS
    // iot_C8 MQTT sub to temp and pressure data vals from D8 published temp and pressure readings
    Particle.subscribe("temperature_D8", myTempHandler, MY_DEVICES);
    //Particle.subscribe("pressure_D8", myPressHandler, MY_DEVICES);
    
    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
}


void loop(){                     
    
    // Run Blynk App
    if(Particle.connected()){
        Serial.println("Particle connected, blynk online");
        Blynk.run();
    }
    else{
        Serial.println("Particle disconnected");
    }

    // iot_C8 Device - MQTT Publish Ambience Room Status (Dark/Bright/Dim) 
    // Ambience Brightness LDR Treshold
    if(analogRead(ldr) >= (ldr_status+30) || analogRead(ldr) <= (ldr_status-30)) //50
    {
        ldr_status = analogRead(ldr);
        Serial.println("Ambience Change");
        Serial.printlnf("LDR Status = %d", ldr_status);

        if (ldr_status <= 100){    // Modify this in class
         Particle.publish("ambience_C8", "Dark", PRIVATE);
         Serial.println("Ambience Status= Dark");
         Serial.println("Ambience Dark Request triggered");
        }
     
         else if (ldr_status >= 300){
         Particle.publish("ambience_C8", "Bright", PRIVATE);
         Serial.println("Ambience Status= Bright");
         Serial.println("Ambience Bright Request triggered");
        }
     
        else{
         Particle.publish("ambience_C8", "Dim", PUBLIC);
         Serial.println("Ambience Status= Dim");
         Serial.println("Ambience Dim Request triggered");
        }
    }
    
    // Blynk LDR Gauge
    Blynk.virtualWrite(V0, ldr_status);
    
    // Blynk LCD Display (Date + Greeting)
    DisplayTime();
    Greeting();
}



int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led3,HIGH);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led3,LOW);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 0;
    }
    else if (command=="read") {
        return digitalRead(led3);
    }

    else {
        return -1;
    }
}


void DisplayTime(){
    lcd.print(0,0, (const char*)Time.format("%I:%M%p")); 
    lcd.print(0,1, (const char*)Time.format("%a %e %b"));
    delay(1000);
}

/*void DisplayTime(){

    String time1 = Time.format(Time.now(), "%I:%M%p");
    
    String date = String(Time.day()); 
    String month = Time.format(Time.month(), "%b");    // abbreviated month name (3 char)
    String day = Time.format(Time.day(), "%a");        // abbreviated day name (3 char)
    String display = day+" "+date+" "+month+"      ";

    lcd.print(0,0, time1); 
    lcd.print(0,1, display);
    delay(1000);
}*/

void Greeting(){
    MorningDisplay();
    AfternoonDisplay();

    //EveningDisplay();
    //NightDisplay();
    //MidNightDisplay();    
}

void MorningDisplay(){
    DailyTimer MorningTimer(6, 0, 11, 59, EVERY_DAY);  // Fixed start time and end time
    if(MorningTimer.startTrigger()){
        lcd.print(0,1, "Good Morning!");
        delay(2000);
        
        MorningMsg();
        delay(1000);
    }
}

void AfternoonDisplay(){
    DailyTimer AfternoonTimer(12, 0, 17, 59, EVERY_DAY);  // Fixed start time and end time
    if(AfternoonTimer.startTrigger()){
        lcd.print(0,1, "Good Afternoon! ");
        delay(1000);
        
        AfternoonMsg();
        delay(1000);
    }
}

<Device 2 code>

double env_temp;
double env_Pressure;

// HTML Temp + Press Gage Data
double temp_reading;
double press_reading;

// Blynk Slider + Button
int led1 = D2;

// Get data from subscribed topic ambience_C8, on / off led according to ambience status
void myAmbienceHandler(const char *event, const char *data){
   String ambience_status = String(data);
   Serial.printlnf("%s: <%s>", event, data);
   Serial.println("Ambience Handler executed");
   Serial.println(ambience_status);

   if(ambience_status == "Dark"){
       digitalWrite(D2, HIGH);
       Serial.println("Led turns on");
       delay(1000);
   }
   else if(ambience_status == "Bright"){
       digitalWrite(D2, LOW);
       Serial.println("Led stays off");
       delay(1000);

   }
   else if(ambience_status == "Dim"){
       digitalWrite(D2, LOW);
       Serial.println("Led stays off");
       delay(1000);
   }
}


void setup() {
   
   pinMode(led1, OUTPUT);

   // HTML Temp and pressure gauge reading
   Particle.variable("temp", temp_reading);    
   Particle.variable("press", press_reading);    
   
   // iot_D8 Device MQTT subscribe to Ambience_C8
   Particle.subscribe("ambience_C8", myAmbienceHandler, MY_DEVICES); 

   Blynk.begin(auth); 

   Serial.begin(9600);
   while (!Serial);
   Serial.println("Serial is Running");
   Serial.println("Blynk is running. Ensure wifi connected on device and app are same");

   if (!bmp.begin()){
       Serial.println("Can't find the sensor BMP280");
   }

   if (bmp.begin()){
       Serial.println("DEBUG, starting the environment timer...");
   }
   
   else{
       Serial.println("WARN, Could not find a valid BMP280 sensor, check wiring!");
   }

}

void loop() {
   // Run Blynk App
   Blynk.run();
   
   temp_reading = bmp.readTemperature();
   press_reading = bmp.readPressure();
   
   double t_temp = bmp.readTemperature();
   double t_Pressure = bmp.readPressure();

   // Compare temp to env, if change, publish value
   if (t_temp >= env_temp + 0.1 || t_temp <= env_temp - 0.1){
       Particle.publish("temperature_D8", String(t_temp), PRIVATE);
       Serial.println("Temperature Request triggered");
   }
   
   if (t_Pressure >= env_Pressure + 5 || t_Pressure <= env_Pressure - 5){
       Particle.publish("pressure_D8", String(t_Pressure), PRIVATE);
       Serial.println("Pressure Request triggered");
   }
}


void checkEnvironment() {
   env_temp = bmp.readTemperature();
   env_Pressure = bmp.readPressure();
} 

I’m not sure if im guarding the blynk.run correctly. Here’s another output of my serial monitor.

Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 17
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Ambience Change
LDR Status = 58
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
temperature_D8: <25.879999>
Temperature Handler executed, 25.879999°C
temperature_D8: <25.879999>
Temperature Handler executed, 25.879999°C
Particle connected, blynk online

I still wouldn’t see a reason for the subscribe handler to cause the SOS panic, although I’d still advise against the use of delay() therein.

I think Blynk.run() is not the only thing you’d need to guard.
Blynk.virtualWrite() and your lcd.print() calls are also relating to Blynk and should be guarded too (IMO).

What if you disable all subscribe handlers?
You could also use the brute force crash detection by adding this in multiple places in your code

  Serial.printlnf("%4d", __LINE__); delay(10);

This will print the respective code line number and the last one before the crash is potentially your culprit.
It’s advisable to have a reference Serial.printlnf("%4d <-- reference", __LINE__); at the top of setup() since the preprocessor may add some offset.

Alright thanks!! I will use the full code which you have edited for device1 and 2, guard the blynk related codes, use the brute force crash detection and remember to test two scenarios, 1. Disable all subscribe handlers/2.Single subscribe handler then run monitor check for red SOS on both scenarios.

I will also guard all blynk code related lines with:

if(particle.connected()) {
print("connected)"
virtualblynk/lcd.print/lcd2.print
}
else{
print("disconnected)
}

I’ll be back in 20hours!

Hi ScruffR, I get this compile error when I add the reference above the setup(). No error with Serial.printlnf("%4d", LINE); delay(10);

Compile error -
ino:60:7: expected constructor, destructor, or type conversion before ‘.’ token

60 Serial.printlnf("%4d <-- reference", __LINE__);
61
62void setup(){
63   //DisplayTemp();
    DisplayTime();
    //Greeting();

    // Nightlight Toggle On/Off
    pinMode(led3, OUTPUT); 
    Particle.function("led",ledToggle);

<Device 1 Code>

char auth[] = "HIDDEN";  

int led3=D0;             // Blynk Nightlight Control + HTML Nightlight Toggle On/Off
int led3_status=-1;      // HTML Nightlight Toggle On/Off

int ldr=A0;              // Blynk Ambience Brightness 
int ldr_status=0;        // Blynk Ambience Brightness 
int ldranalogvalue=0;    // Blynk Ambience Brightness Gauge

WidgetLCD lcd(V1);       // Blynk LCD (Date Day Greeting)
WidgetLCD lcd2(V3);

// Get Temperature data from subscribed topic and print on LCD
void myTempHandler(const char *event, const char *data){
    double temp_val = atof(data);
    Serial.printlnf("%s: <%s>", event, data);
    
    Serial.printlnf("Temperature Handler executed, %f°C", temp_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%.2f°C %s", temp_val, (temp_val > 32.50) ? "Warm" : "Cool");
    if(Particle.connected()){
        Serial.println("Particle handler connected");
        lcd2.print(0, 0, msg);
    }
    else{
        Serial.println("Particle handler disconnected");
    }
}

/*void myPressHandler(const char *event, const char *data){
    double press_val = atof(data);
    Serial.printlnf("Pressure Handler executed, %fPa", press_val);

    char msg[32];
    snprintf(msg, sizeof(msg), "%dPa %s", press_val, (press_val > 900) ? "High" : "Low");
    lcd2.print(0, 0, msg);

    if(press_val > 900){
        digitalWrite(D7, HIGH);
    }
    
    else{
        digitalWrite(D7, LOW);
    }
}
*/
//Serial.printlnf("%4d <-- reference", __LINE__);

void setup(){
    //DisplayTemp();
    DisplayTime();
    //Greeting();

    // Nightlight Toggle On/Off
    pinMode(led3, OUTPUT); 
    Particle.function("led",ledToggle);

    // HTML Ambience Brightness Gauge
    ldr_status=analogRead(ldr);      // pinMode not needed since analogRead used
    ldranalogvalue=ldr_status;
    //Particle.variable("ldranalogvalue", &ldranalogvalue, INT);
    Particle.variable("ldranalogvalue", ldranalogvalue);
    
    Blynk.begin(auth); 
     
    // Blynk LCD ADVANCED
    //lcd.clear();

    // bLYNK LCD Time Display (Set Timezone to SG using +8)
    Time.zone(+8);  

    // IP ADDRESS
    // iot_C8 MQTT sub to temp and pressure data vals from D8 published temp and pressure readings
    Particle.subscribe("temperature_D8", myTempHandler, MY_DEVICES);
    //Particle.subscribe("pressure_D8", myPressHandler, MY_DEVICES);
    
    Serial.begin(9600);
    while (!Serial);
    Serial.println("Serial is Running");
    Serial.println("Blynk is running. Ensure wifi connected on device and app are same");
}


void loop(){                     
    
    // Run Blynk App
    if(Particle.connected()){
        Serial.println("Particle connected, blynk online");
        Serial.printlnf("%4d", __LINE__); delay(10);
        Blynk.run();
    }
    else{
        Serial.println("Particle disconnected");
    }

    // iot_C8 Device - MQTT Publish Ambience Room Status (Dark/Bright/Dim) 
    // Ambience Brightness LDR Treshold
    if(analogRead(ldr) >= (ldr_status+30) || analogRead(ldr) <= (ldr_status-30)) //50
    {
        ldr_status = analogRead(ldr);
        Serial.println("Ambience Change");
        Serial.printlnf("LDR Status = %d", ldr_status);

        if (ldr_status <= 100){    // Modify this in class
         Particle.publish("ambience_C8", "Dark", PRIVATE);
         Serial.println("Ambience Status= Dark");
         Serial.println("Ambience Dark Request triggered");
         Serial.printlnf("%4d", __LINE__); delay(10);

        }
     
         else if (ldr_status >= 300){
         Particle.publish("ambience_C8", "Bright", PRIVATE);
         Serial.println("Ambience Status= Bright");
         Serial.println("Ambience Bright Request triggered");
         Serial.printlnf("%4d", __LINE__); delay(10);

        }
     
        else{
         Particle.publish("ambience_C8", "Dim", PUBLIC);
         Serial.println("Ambience Status= Dim");
         Serial.println("Ambience Dim Request triggered");
         Serial.printlnf("%4d", __LINE__); delay(10);

        }
    }
    
    // Blynk LDR Gauge
    if(Particle.connected()){
        Serial.println("particle v0 connected");
        Blynk.virtualWrite(V0, ldr_status);
    }
    else{
        Serial.println("particle v0 disconnected");
    }
    
    // Blynk LCD Display (Date + Greeting)
    DisplayTime();
    Greeting();
}



int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led3,HIGH);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led3,LOW);
        Serial.print("HTML led3 ");
        Serial.println(command);
        return 0;
    }
    else if (command=="read") {
        return digitalRead(led3);
    }

    else {
        return -1;
    }
}


void DisplayTime(){
    if(Particle.connected()){
        Serial.println("Particle display connecteed");
        lcd.print(0,0, (const char*)Time.format("%I:%M%p")); 
        lcd.print(0,1, (const char*)Time.format("%a %e %b"));
        delay(1000);
    }
    else{
        Serial.println("Particle display disconnecteed");
    }
}

/*void DisplayTime(){

    String time1 = Time.format(Time.now(), "%I:%M%p");
    
    String date = String(Time.day()); 
    String month = Time.format(Time.month(), "%b");    // abbreviated month name (3 char)
    String day = Time.format(Time.day(), "%a");        // abbreviated day name (3 char)
    String display = day+" "+date+" "+month+"      ";

    lcd.print(0,0, time1); 
    lcd.print(0,1, display);
    delay(1000);
}*/

void Greeting(){
    MorningDisplay();
    AfternoonDisplay();

    //EveningDisplay();
    //NightDisplay();
    //MidNightDisplay();    
}

void MorningDisplay(){
    DailyTimer MorningTimer(6, 0, 11, 59, EVERY_DAY);  // Fixed start time and end time
    if(MorningTimer.startTrigger()){
        lcd.print(0,1, "Good Morning!");
        delay(2000);
        
        MorningMsg();
        delay(1000);
    }
}

void AfternoonDisplay(){
    DailyTimer AfternoonTimer(12, 0, 17, 59, EVERY_DAY);  // Fixed start time and end time
    if(AfternoonTimer.startTrigger()){
        lcd.print(0,1, "Good Afternoon! ");
        delay(1000);
        
        AfternoonMsg();
        delay(1000);
    }
}


void MorningMsg(){
    String text = "Time for Breakfast";
    int space=(strlen(text)-15);                 // Set no. of space for text to move
    for(int start=0; start<space; start++){      // Increment loop
        
        lcd.print(0,1, text.substring(start));   // substring func remove char of string via loop and prints continuously
        delay(1000);
    }
}

void AfternoonMsg(){
    String text = "Lunch Break     ";            // Spaces to avoid other text from overlapping
    lcd.print(0,1, text);   
    delay(1000);
}

<Device 2 Code>

Adafruit_BMP280 bmp; // I2C

char auth[] = "HIDDEN";  

double env_temp;
double env_Pressure;

// HTML Temp + Press Gage Data
double temp_reading;
double press_reading;

// Blynk Slider + Button
int led1 = D2;

//Serial.printlnf("%4d <-- reference", __LINE__);

// Get data from subscribed topic ambience_C8, on / off led according to ambience status
void myAmbienceHandler(const char *event, const char *data){
   String ambience_status = String(data);
   Serial.printlnf("%s: <%s>", event, data);
   Serial.println("Ambience Handler executed");
   Serial.println(ambience_status);

   if(ambience_status == "Dark"){
       digitalWrite(D2, HIGH);
       Serial.println("Led turns on");
       Serial.printlnf("%4d", __LINE__); delay(10);

       delay(1000);
   }
   else if(ambience_status == "Bright"){
       digitalWrite(D2, LOW);
       Serial.println("Led stays off");
       Serial.printlnf("%4d", __LINE__); delay(10);

       delay(1000);

   }
   else if(ambience_status == "Dim"){
       digitalWrite(D2, LOW);
       Serial.println("Led stays off");
       Serial.printlnf("%4d", __LINE__); delay(10);

       delay(1000);
   }
}


void setup() {
   
   pinMode(led1, OUTPUT);

   // HTML Temp and pressure gauge reading
   Particle.variable("temp", temp_reading);    
   Particle.variable("press", press_reading);    
   
   // iot_D8 Device MQTT subscribe to Ambience_C8
   Particle.subscribe("ambience_C8", myAmbienceHandler, MY_DEVICES); 
   
    if(Particle.connected()){
        Serial.println("Particle connected, auth");
        Blynk.begin(auth); 
    }
    else{
        Serial.println("Particle disconnected, auth");
    }
    

   Serial.begin(9600);
   while (!Serial);
   Serial.println("Serial is Running");
   Serial.println("Blynk is running. Ensure wifi connected on device and app are same");

   if (!bmp.begin()){
       Serial.println("Can't find the sensor BMP280");
       Serial.printlnf("%4d", __LINE__); delay(10);

   }

   if (bmp.begin()){
       Serial.println("DEBUG, starting the environment timer...");
       Serial.printlnf("%4d", __LINE__); delay(10);

   }
   
   else{
       Serial.println("WARN, Could not find a valid BMP280 sensor, check wiring!");
       Serial.printlnf("%4d", __LINE__); delay(10);

   }

}

void loop() {
   // Run Blynk App
    if(Particle.connected()){
        Serial.println("Particle connected, blynk online");
        Blynk.run();
    }
    else{
        Serial.println("particle disconnected, blynk offline");
    }
   
   temp_reading = bmp.readTemperature();
   press_reading = bmp.readPressure();
   
   double t_temp = bmp.readTemperature();
   double t_Pressure = bmp.readPressure();

   // Compare temp to env, if change, publish value
   if (t_temp >= env_temp + 0.1 || t_temp <= env_temp - 0.1){
       Particle.publish("temperature_D8", String(t_temp), PRIVATE);
       Serial.println("Temperature Request triggered");
       Serial.printlnf("%4d", __LINE__); delay(10);

   }
   
   if (t_Pressure >= env_Pressure + 5 || t_Pressure <= env_Pressure - 5){
       Particle.publish("pressure_D8", String(t_Pressure), PRIVATE);
       Serial.println("Pressure Request triggered");
       Serial.printlnf("%4d", __LINE__); delay(10);
       

   }
}


void checkEnvironment() {
   env_temp = bmp.readTemperature();
   env_Pressure = bmp.readPressure();
   Serial.printlnf("%4d", __LINE__); delay(10);

} 

Device 1 putty serial monitor output only (Device 2 photon off)
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 5
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 43
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Ambience Change
LDR Status = 5
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Ambience Change
LDR Status = 42
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 315
Ambience Status= Bright
Ambience Bright Request triggered
Particle connected, blynk online
Ambience Change
LDR Status = 41
Ambience Status= Dark
Ambience Dark Request triggered
Particle connected, blynk online
Particle connected, blynk online

Device 2 putty serial monitor output only (Device 1 photon off)
Temperature Request triggered
117
Pressure Request triggered
124
Particle connected, blynk online
Temperature Request triggered
117
Pressure Request triggered
124
Particle connected, blynk online
Temperature Request triggered
117
Pressure Request triggered
124
Particle connected, blynk online
Temperature Request triggered
117
Pressure Request triggered
124
Particle connected, blynk online
Temperature Request triggered
117
Pressure Request triggered
124
Particle connected, blynk online
Temperature Request triggered
117
Pressure Request triggered
124

Here is the device 1 serial monitor output with temp handler subscribed and publish ambience_c8, device 2 is on

From device 1 serial monitor, I noticed that the temp handler prints the output whenever the LDR threshold is met, then prints ambience_status and publishes ambienec_c8.

Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Ambience Change
LDR Status = 365
Ambience Status= Bright
Ambience Bright Request triggered
temperature_D8: <30.040001>
Temperature Handler executed, 30.040001°C
temperature_D8: <30.049999>
Temperature Handler executed, 30.049999°C
Particle connected, blynk online
Ambience Change
LDR Status = 60
Ambience Status= Dark
Ambience Dark Request triggered
temperature_D8: <30.030001>
Temperature Handler executed, 30.030001°C
temperature_D8: <30.020000>
Temperature Handler executed, 30.020000°C
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online
Particle connected, blynk online

Here’s my particle cloud event console. Seems like the LDR Threshold if statement inside the void loop() is not allowing the particle.subscribe(temp) and (pressure) to be read constantly.

I will re-write my code, replacing particle.publish/subscribe with MQTT.client publish.subscribe, use softaware timer functions and keep my void loop as clean as possible.

I said at the top of setup() not above setup :wink:

void setup() {
  Serial.printlnf("%4d <-- reference", __LINE__);
  ...

Hi ScruffR! Oops I guess i misread that! I’ve added the line to the top of void setup().

Taking a closer look, device 1 output repeats number 129, 121 and 102. Meanwhile, device 2 output repeats number 118 and 125. I assume these “numbers” are referring to the the code line number in respective code files which I’ve placed the Serial.printlnf("%4d", LINE); delay(10); at. However, I have no idea what this brute force crash detection does.

Heres the output of device1 serial monitor:

particle v0 connected
Particle display connecteed
Particle connected, blynk online
102
particle v0 connected
Particle display connecteed
Particle connected, blynk online
102
particle v0 connected
Particle display connecteed
Particle connected, blynk online
102
Ambience Change
LDR Status = 655
Ambience Status= Bright
Ambience Bright Request triggered
129
particle v0 connected
Particle display connecteed
temperature_D8: <30.020000>
Temperature Handler executed, 30.020000°C
Particle handler connected
Particle connected, blynk online
102
Ambience Change
LDR Status = 616
Ambience Status= Bright
Ambience Bright Request triggered
129
particle v0 connected
Particle display connecteed
Particle connected, blynk online
102
temperature_D8: <30.049999>
Temperature Handler executed, 30.049999°C
Particle handler connected
particle v0 connected
Particle display connecteed
Particle connected, blynk online
102
Ambience Change
LDR Status = 562
Ambience Status= Bright
Ambience Bright Request triggered
129
particle v0 connected
Particle display connecteed
temperature_D8: <30.059999>
Temperature Handler executed, 30.059999°C
Particle handler connected
Particle connected, blynk online
102
Ambience Change
LDR Status = 18
Ambience Status= Dark
Ambience Dark Request triggered
121
particle v0 connected
Particle display connecteed
temperature_D8: <30.070000>
Temperature Handler executed, 30.070000°C
Particle handler connected
Particle connected, blynk online
102
particle v0 connected
Particle display connecteed
temperature_D8: <30.059999>
Temperature Handler executed, 30.059999°C
Particle handler connected
temperature_D8: <30.059999>
Temperature Handler executed, 30.059999°C
Particle handler connected

device 2 output:

Particle connected, blynk online
Temperature Request triggered
118
Pressure Request triggered
125
Particle connected, blynk online
Temperature Request triggered
118
Pressure Request triggered
125
Particle connected, blynk online
Temperature Request triggered
118
Pressure Request triggered
125
Particle connected, blynk online
Temperature Request triggered
118
Pressure Request triggered
125
Particle connected, blynk online
Temperature Request triggered
118

That is correct, but you need to consider the offset between your line number in the editor and the line number reported.
For that you calculate the difference between the two numbers of the "reference" line.

In case of a crash you will see which line was the last one that could successfully be executed, indicating that one of the following lines is most likely the culprit.
Hence you want these lines before any potentially problematic code :wink: