Help with Troubleshooting Blynk Garage Door Monitor

Hi All,

This is my first post in this forum. I bought my dad an NodeMCU (ESP8266) for Christmas last year so he can mess around with learning C++ and microcontrollers. He has a long history with programming back to the beginning of computers, but hasn’t touched it in a few decades.

His first project was to use a NodeMCU to read the open/close state of two garage doors and write the state with a timestamp to Blynk. We got this working months ago.

He recently decided he wanted to add temperature and humidity sensing to the code as well. We selected a SHT31-D temperature sensor breakout board from Adafruit (https://www.adafruit.com/product/2857). Using their sample code, he was able to read temp and humidity over I2C successfully and print it to the serial port.

He ran into a wall when he tried to merge the two pieces of code. For some reason, the merged code crashes the NodeMCU whenever it tries to read the temp or humidity. This did not happen with Adafruit’s sample code.

Is there some reason a NodeMCU/ESP8266 cannot communicate with Blynk at the same time as communicating over I2C? Why would this crash the NodeMCU?

Edit: Trying to figure out how to attach my code

Please excuse if the code is a bit messy. I am trying to let him figure out the troubleshooting on his own.

Appreciate any feedback you can provide!

Here is the original garage door program that has been running fine for months.


// Plug Micro USB into NodeMCU

// To upload program:  Need to connect Pin D3 (FLash / GPIO0) to GND. Disconnect after upload.

// May need to press RST to run program after upload



#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>

#include <BlynkSimpleEsp8266.h>

#include <TimeLib.h>

#include <WidgetRTC.h>



char auth[] = xxx

char ssid[] = xxx

char pass[] = xxx


/*

Variables

-V4: TRC Open Door Status (From Micro)

-V5: TRC Closed Door Status (From Micro)

-V6: CAM Open Door Status (From Micro)

-V7: CAM Closed Door Status (From Micro)

-V8: Current time

-V9: Current time

-V10: Current time

-V11: Current time

*/



String sthr = "";

String stmin = "";

String stsec = "";

String currentDateTime = "No Data";



int TRCcounter = 0;

int TRCstate = 0;

int TRClaststate = 0;

int CAMcounter = 0;

int CAMstate = 0;

int CAMlaststate = 0;



WidgetRTC rtc;

WidgetLED led14open (V4);  //open

WidgetLED led14close (V5);  //close

WidgetLED led13open (V6);  //open

WidgetLED led13close (V7);  //close



void clockDisplay() {

   if(hour()<10) { sthr="0"+String(hour()); }

   if(hour()>9) { sthr=String(hour()); }

   if(minute()<10) { stmin="0"+String(minute()); }

   if(minute()>9) { stmin=String(minute()); }

   if(second()<10) { stsec="0"+String(second()); }

   if(second()>9) { stsec=String(second());}



   currentDateTime = sthr + ":" + stmin + ":" + stsec;



}



void TRCdooropen () {

      clockDisplay();

      Blynk.virtualWrite(V9, currentDateTime);

      Blynk.notify("TRC Door is Open");

      led14open.on();

      led14close.off();

}



void TRCdoorclose () {

      clockDisplay();

      Blynk.virtualWrite(V8, currentDateTime);

      Blynk.notify("TRC Door is Closed");

      led14open.off();

      led14close.on();

}

   

void CAMdooropen () {

      clockDisplay();

      Blynk.virtualWrite(V11, currentDateTime);

      Blynk.notify("CAM Door is Open");

      led13open.on();

      led13close.off();

}



void CAMdoorclose () {

      clockDisplay();

      Blynk.virtualWrite(V10, currentDateTime);

      Blynk.notify("CAM Door is Closed");

      led13open.off();

      led13close.on();

}



BLYNK_CONNECTED() { rtc.begin(); }



void setup() {

   Serial.begin(9600);



   Blynk.begin(auth, ssid, pass);



   pinMode(14, INPUT_PULLUP);

   pinMode(13, INPUT_PULLUP);



   Blynk.setProperty(V4,"color","#ff0000");  //red - hex code of RGB value for color

   Blynk.setProperty(V5,"color","#39ff14");  //neon green - hex code of RGB value for color

   Blynk.setProperty(V6,"color","#ff0000");  //red - hex code of RGB value for color

   Blynk.setProperty(V7,"color","#39ff14");  //neon green - hex code of RGB value for color

  

   setSyncInterval(10 * 60);  //update Node clock chip from server every 10 minutes



}  //end void setup



void loop() {

  

  Blynk.run();



   if ((digitalRead(14) == HIGH) && (TRCcounter < 50)) { TRCcounter ++; }



   if ((digitalRead(14) == LOW) && (TRCcounter > 0)) { TRCcounter --; }  

 

   if (TRCcounter == 50) { TRCstate = 1; }



   if (TRCcounter == 0) { TRCstate = 0; }

   

   if (TRCstate != TRClaststate) {

      TRClaststate = TRCstate;



         if (TRCstate == 1) { TRCdooropen (); }

         if (TRCstate == 0) { TRCdoorclose (); }    



   }  //end if not equal



   if ((digitalRead(13) == HIGH) && (CAMcounter < 50)) { CAMcounter ++; }



   if ((digitalRead(13) == LOW) && (CAMcounter > 0)) { CAMcounter --;  }  



   if (CAMcounter == 50) { CAMstate = 1; }



   if (CAMcounter == 0) { CAMstate = 0; }



   if (CAMstate != CAMlaststate) {

      CAMlaststate = CAMstate;



      if (CAMstate == 1) { CAMdooropen (); }



      if (CAMstate == 0) { CAMdoorclose (); }    

   

   }  //end if not equal



}  //end void loop

Here is the Adafruit sample code that worked to read the temp and humidity sensor

  This is an example for the SHT31-D Humidity & Temp Sensor

  Designed specifically to work with the SHT31-D sensor from Adafruit
  ----> https://urldefense.com/v3/__https://www.adafruit.com/products/2857__;!!JhrIYaSK6lFZ!5vm-z6C12EK7OZ2QDCK41nLWtCDafFmdAXAAvGPjjOSdjeiC4x16KluE8Fe40QdVqqw$ 

  These sensors use I2C to communicate, 2 pins are required to  
  interface
 ****************************************************/
 
#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"

bool enableHeater = false;
uint8_t loopCnt = 0;
unsigned long tstart = millis();
unsigned long tnow = 0;

Adafruit_SHT31 sht31 = Adafruit_SHT31();

void setup() {
  Serial.begin(9600);

  while (!Serial)
    delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("SHT31 test");
  if (! sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }

  Serial.print("Heater Enabled State: ");
  if (sht31.isHeaterEnabled())
    Serial.println("ENABLED");
  else
    Serial.println("DISABLED");
}

void loop() {
  
  if ((millis() - tstart) > 1000) {   // Use millis loop instead of delay 
    
  tstart=millis();

  float t = sht31.readTemperature();
  t=(1.8*t)+32;  // convert to *F
  float h = sht31.readHumidity();

  if (! isnan(t)) {   // check if 'is not a number'
    Serial.print("Temp *F = "); Serial.print(t); Serial.print("\t\t");
  } else { 
    Serial.println("Failed to read temperature");
  }
  
  if (! isnan(h)) {  // check if 'is not a number'
    Serial.print("Hum. % = "); Serial.println(h);
  } else { 
    Serial.println("Failed to read humidity");
  }

  // delay(1000);
  
  // Toggle heater enabled state every 30 seconds
  // An ~3.0 degC temperature increase can be noted when heater is enabled
  if (++loopCnt == 30) {
    enableHeater = !enableHeater;
    sht31.heater(enableHeater);
    Serial.print("Heater Enabled State: ");
    if (sht31.isHeaterEnabled())
      Serial.println("ENABLED");
    else
      Serial.println("DISABLED");

    loopCnt = 0;
  }
}
}

And here is the merged program that doesn’t work.

// Set Board to Node MCU 1.0 in Tools

// Plug Micro USB into NodeMCU

// To upload program:  Need to connect Pin D3 (Flash / GPIO0) to GND. Disconnect after upload.

// May need to press RST to run program after upload



#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>

#include <BlynkSimpleEsp8266.h>

#include <TimeLib.h>

#include <WidgetRTC.h>



// following includes are for SHT31 temp sensor

#include <Arduino.h>

#include <Wire.h>

#include "Adafruit_SHT31.h"



char auth[] = xxx

char ssid[] = xxx

char pass[] = xxx


/*

Variables Used:

-V4: TRC Open Door Status (From Micro)

-V5: TRC Closed Door Status (From Micro)

-V6: CAM Open Door Status (From Micro)

-V7: CAM Closed Door Status (From Micro)

-V8: Current time TRC closed

-V9: Current time TRC open

-V10: Current time CAM closed

-V11: Current time CAM open

-V12: SHT31 Temperature

-V13: SHT31 Relative Humidity

*/



String sthr = "";

String stmin = "";

String stsec = "";

String currentDateTime = "No Data";



int TRCcounter = 0;

int TRCstate = 0;

int TRClaststate = 0;

int CAMcounter = 0;

int CAMstate = 0;

int CAMlaststate = 0;



// following declarations are for SHT31



unsigned long tstart = millis();

bool enableHeater = false;  //heater used to eliminate condensation

uint8_t loopCnt = 0;



Adafruit_SHT31 sht31 = Adafruit_SHT31();



WidgetRTC rtc;

WidgetLED led14open (V4);  // open LED TRC

WidgetLED led14close (V5);  // close LED TRC

WidgetLED led13open (V6);  // open LED CAM

WidgetLED led13close (V7);  // close LED CAM



void clockDisplay() {

   if(hour()<10) { sthr="0"+String(hour()); }

   if(hour()>9) { sthr=String(hour()); }

   if(minute()<10) { stmin="0"+String(minute()); }

   if(minute()>9) { stmin=String(minute()); }

   if(second()<10) { stsec="0"+String(second()); }

   if(second()>9) { stsec=String(second());}



   currentDateTime = sthr + ":" + stmin + ":" + stsec;



}



void TRCdooropen () {

      clockDisplay();

      Blynk.virtualWrite(V9, currentDateTime);

      Blynk.notify("TRC Door is Open");

      led14open.on();

      led14close.off();

}



void TRCdoorclose () {

      clockDisplay();

      Blynk.virtualWrite(V8, currentDateTime);

      Blynk.notify("TRC Door is Closed");

      led14open.off();

      led14close.on();

}

   

void CAMdooropen () {

      clockDisplay();

      Blynk.virtualWrite(V11, currentDateTime);

      Blynk.notify("CAM Door is Open");

      led13open.on();

      led13close.off();

}



void CAMdoorclose () {

      clockDisplay();

      Blynk.virtualWrite(V10, currentDateTime);

      Blynk.notify("CAM Door is Closed");

      led13open.off();

      led13close.on();

}



BLYNK_CONNECTED() { rtc.begin(); }



void setup() {

  

   Serial.begin(9600);



// NEED FOLLOWING???

   while (!Serial)

   delay(10);     // will pause Zero, Leonardo, etc until serial console opens



   Blynk.begin(auth, ssid, pass);

   

   pinMode(14, INPUT_PULLUP);  // TRC door - pin D5 / GPIO14

   pinMode(13, INPUT_PULLUP);  // CAM door - pin D7 / GPIO13



   Blynk.setProperty(V4,"color","#ff0000");  //red - hex code of RGB value for color

   Blynk.setProperty(V5,"color","#39ff14");  //neon green - hex code of RGB value for color

   Blynk.setProperty(V6,"color","#ff0000");  //red - hex code of RGB value for color

   Blynk.setProperty(V7,"color","#39ff14");  //neon green - hex code of RGB value for color

  

   setSyncInterval(10 * 60);  //update Node clock chip from server every 10 minutes



// Following for SHT31



/*

   Serial.println("SHT31 test");

   

   if (! sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr

     Serial.println("Couldn't find SHT31");

     while (1) delay(1);

   }



   Serial.print("Heater Enabled State: ");

   

   if (sht31.isHeaterEnabled())

     Serial.println("ENABLED");

   else

     Serial.println("DISABLED");

*/



}  //end void setup



void loop() {



   Blynk.run();



   if ((digitalRead(14) == HIGH) && (TRCcounter < 50)) { TRCcounter ++; }

   if ((digitalRead(14) == LOW) && (TRCcounter > 0)) { TRCcounter --; }  

 

   if (TRCcounter == 50) { TRCstate = 1; }

   if (TRCcounter == 0) { TRCstate = 0; }

   

   if (TRCstate != TRClaststate) { 

    

      TRClaststate = TRCstate;



      if (TRCstate == 1) { TRCdooropen (); }

      if (TRCstate == 0) { TRCdoorclose (); }    



   }  // end if not equal



   if ((digitalRead(13) == HIGH) && (CAMcounter < 50)) { CAMcounter ++; }

   if ((digitalRead(13) == LOW) && (CAMcounter > 0)) { CAMcounter --;  }  



   if (CAMcounter == 50) { CAMstate = 1; }

   if (CAMcounter == 0) { CAMstate = 0; }



   if (CAMstate != CAMlaststate) { 

    

      CAMlaststate = CAMstate;



      if (CAMstate == 1) { CAMdooropen (); }

      if (CAMstate == 0) { CAMdoorclose (); }    

   

   }  // end if not equal



// following is for SHT31



   if ((millis() - tstart) > 2000) {   // Use millis loop instead of delay 



   tstart =  millis();

  

     float t = sht31.readTemperature();  // disconnects Blynk!

 

     t = (1.8 * t) + 32;  // convert temperature to *F

 

     float h = sht31.readHumidity();  // disconnects Blynk!

     

   if (! isnan(t)) {   // check if 'is not a number'

    

     Serial.print("Temp *F = "); Serial.print(t); Serial.print("\t\t");

    

     Blynk.virtualWrite(V12, t);

      

   } else { 

    

     Serial.println("Failed to read temperature");

    

     }

 

   if (! isnan(h)) {  // check if 'is not a number'

    

     Serial.print("Hum. % = "); Serial.println(h);

    

     Blynk.virtualWrite(V13, h);

    

   } else { 

    

     Serial.println("Failed to read humidity");



     }



/*

   delay(1000);

  

// Toggle heater enabled state every 30 seconds 

// A ~3.0 degC temperature increase can be noted when heater is enabled



   if (++loopCnt == 30) {

     enableHeater = !enableHeater;

     sht31.heater(enableHeater);

     Serial.print("Heater Enabled State: ");



   if (sht31.isHeaterEnabled())

     Serial.println("ENABLED");

   else

     Serial.println("DISABLED");



   loopCnt = 0;

   }

*/



   }  // end if millis()



}  // end void loop

Sorry about the mess of code. If anyone can tell me how to better format the text, I’d appreciate it.

@macardoso please edit your posts, using the pencil icon at the bottom of each one, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Pete.

Thanks Pete! I tried a few code block tags but couldn’t figure out how to get it to render correctly. That looks much better :slight_smile:

You should start by reading this:

Then restructure your code so that you get rid of all the delays and millis comparisons and use BlynkTimers instead.

In the combined code, the SHT31 initialisation is commented-out in void setup. Why is this?

Pete.

Pete,

Thanks again for the response. Unsure why the SHT31.begin is commented out, I will make sure it is added back into the program.

We will work on restructuring the code and see if that helps. EDIT: we need debounce so HW interrupts are not usable - removed previous question.

You can denounce hardware interrupts, but it’s probably easier to have a timed routine that polls the contact states at say 100ms intervals. No normal contact bounce is going to last that long, so it in effect auto debounces the contacts.

Pete.

Well, guess what… it works!

The culprit was the commented out section of sht31.begin().

I’m guessing that if the temperature is read without the communications being started, it hangs waiting for a timeout. This starves the blynk.run(). Fixing just that got everything working.

We are going to restructure the code anyways to make it cleaner. Thanks for the help!

1 Like