Device keeps going offline every few minutes, but goes back online right away

Hi all,

I recently connected my ESP32 dev board to the Blynk IoT using Edgent library. The ESP32 controls a relay (which turns ON/OFF an LED strip) and also have a physical switch. There is also a temp sensor on Onewire. All of these components are inside an ABS IP67 enclosure. The enclosure is just outside of my house, where the wifi strength is still pretty good (so I think). Ever since deploying the device, I get many notifications that the device went offline - about every 15 min or so. When I check in Blynk, it seems that it is back online right away, so it doesn’t seem like it was offline for long. I have several other ESP32 based devices around my house and none of them are going offline so frequently. Why is this happening so much and how can I fix it?

I’m using latest Blynk library 1.2.0. Below is my sketch in case the issue is coming from poor coding (which I do sometimes :wink: ).

Finally note that I have probably done something incorrect… I added a loop that gets entered only once at first run to initialize some of the virtual signals. I find that I cannot seem to get the initial values set properly, so I attempted to make this loop, controlled by flag_initial… Any comments on that would be appreciated also. Maybe there is a better way?

Cheers,
MathPi

#define BLYNK_TEMPLATE_ID "REMVOED"
#define BLYNK_TEMPLATE_NAME "REMOVED"
#define BLYNK_FIRMWARE_VERSION "0.0.1"
#define BLYNK_PRINT Serial
#define APP_DEBUG
//#define USE_ESP32_DEV_MODULE
#include "BlynkEdgent.h" 

#include <OneWire.h>
#include <DallasTemperature.h>

#define pin_switch 27  // Pin at which the switch is attached
#define pin_relay 32   // Pin which controls relay
#define ONE_WIRE_BUS 2 // Pin at which the temp data is passed

BlynkTimer timer; // Announcing the timer

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of DS18B20
uint8_t sensor1[8] = {0x28, 0x0B, 0xE4, 0x07, 0xD6, 0x01, 0x3C, 0xB4};
int LED_status;
int LED_status_previous;
int buttonState;
int buttonState_previous;
int virtualLEDButton;
unsigned long ON_timer;
double ON_timer_hrs;  
int flag = 0;
int flag_initial = 0;

BLYNK_WRITE(V4) {
  // integer value for virtual LED ON/OFF button
  virtualLEDButton = param.asInt();
}

BLYNK_WRITE(V5) {
  // user-set off-timer value
  ON_timer_hrs = param.asDouble() * 60.0 * 60.0 * 1000.0;
}

void setup() {
  sensors.begin();

  BlynkEdgent.begin();

  pinMode(pin_relay, OUTPUT);
  pinMode(pin_switch, INPUT_PULLUP); 
  Serial.begin(9600);

  Blynk.virtualWrite(V3, 0); // Set LEDs initially to off
  Blynk.virtualWrite(V4, 0); // Set virtual button state initially to off
  Blynk.virtualWrite(V5, 2); // Set On time in hrs default

  timer.setInterval(5L, data_transfer);
}

void loop() {
  BlynkEdgent.run();
  timer.run(); 

  // Initialize
  if (flag_initial == 0) {
    flag = 0;
    flag_initial = 1;
    Blynk.virtualWrite(V3, 0); // Set LEDs initially to off
    Blynk.virtualWrite(V4, 0); // Set virtual button state initially to off
    Blynk.virtualWrite(V5, 2); // Set On time in hrs default
  }
}

void data_transfer(){
  // Read button state
  buttonState = digitalRead(pin_switch);


  // Timer logic first, then, If either physical or virtual button state has changed, flip flop LED_status
  if (((millis() - ON_timer) >= ON_timer_hrs)&&(flag == 1)) {                                              
    flag = 0;  // reset timer triger flag
    
    LED_status          = 0;
    LED_status_previous = LED_status;
    virtualLEDButton    = LED_status;
    Blynk.virtualWrite(V4, LED_status); // Need to update the virtual button
  } else if (buttonState != buttonState_previous) {
    if (LED_status_previous == 0) {
      LED_status = 1;
    } else if (LED_status_previous == 1) {
      LED_status = 0;
      flag = 0;
    }
    Blynk.virtualWrite(V4, LED_status); // Need to update the virtual button
    virtualLEDButton = LED_status;
  } else if (virtualLEDButton == 1) {
    LED_status = 1;
  } else if (virtualLEDButton == 0) {
    LED_status = 0;
    flag = 0;
  }

  // Timer to turn off LED. If previously off and then on
  if ((LED_status == 1)&&(flag == 0)) {
    ON_timer = millis();
    flag = 1;
  }

  // Update how much time is left on the timer, if ON
  if (flag == 1) {
    Blynk.virtualWrite(V6, (ON_timer_hrs - millis() + ON_timer) / (1000.0 * 60.0 * 60.0)); // Upload how much time is left
  } else {
    Blynk.virtualWrite(V6, 0); // Upload how much time is left
  }

  // Update the relay
  digitalWrite(pin_relay, LED_status);  

  // Update state to cloud
  Blynk.virtualWrite(V3, LED_status); 
 // Blynk.virtualWrite(V4, LED_status); 


  // Temp in C
  sensors.requestTemperatures();
  printTemperature(sensor1);


  // Save to previous states
  LED_status_previous  = LED_status;
  buttonState_previous = buttonState;
}

void printTemperature(DeviceAddress deviceAddress){
  float tempC = sensors.getTempC(deviceAddress);
  Blynk.virtualWrite(V0, tempC); 
  Serial.print("Temp: ");
  Serial.print(tempC);
  Serial.println(" C");
}

you can’t call data transfert every 5 ms, try 5000 or more

Thanks I will try that and update this post once I have some results.

I am curious, can the Timer not handle every 5ms? 5000ms seems quite slow. If the user flips the switch, it can add a 5s delay until the relays turns on. Maybe I can try 1s instead… Any thoughts?

Timer can handle 5ms, but your data_transfert needs more than 5ms, and Dallas sensor needs more than 500 ms

1 Like

Ah yes, Excellent point! Thanks

1 Like

TBH, your code structure is a mess.

You should be using BlynkTimer instead of all this millis comparison stuff…

and in reality thers no need for any of this if you use the sketch builder example…

or use an interrupt attached to your switch pin.

Also, you shouldn’t be doing this in your void loop…

you should be using BLYNK_CONNECTED() instead.

Pete.

1 Like

Great tips! I’ll look at each of them one by one and update my sketch. Cheers :slight_smile:

So I found the issue that was causing the device to go offline frequently… turns out the USB port on the ESP32 dev board did not have a good connection. The power kept getting turned on and off. After a week of that it was completely off. When I went to debug the hardware issue the USB port actually came completely off! To fix the issue I had to physically bypass the USB port and directly feed 5V to the 5V pin. Now it seems to be working.

Thanks all for the help.