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
-
Changing the subscribe handler delay from 1000ms to 10000ms, eventually device 1 still crashes after 2 minutes.
-
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();
}