Relay master switch and Blynk Offline problem

Hi, I wonder if someone could give me as a noob some advice, please. I have 2 questions.

  1. My ESP32 goes offline after ± 30s on the Blynk app and website, but it still shows connected to my wifi router. Is there something that I am missing in my code?

  2. Is there a way that I can code a master switch for my relay? So if it is ON via my IF Statement, I can switch it OFF via the switch that I already have in my code?

Thank you in advance.

Code Below:

#define BLYNK_TEMPLATE_ID "#######"
#define BLYNK_DEVICE_NAME "######"
#define BLYNK_AUTH_TOKEN "#######"

#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>


char auth[] = "########";

char ssid[] = "####";  // type your wifi name
char pass[] = "######";  // type your wifi password

BlynkTimer timer;

//DHT11 LIB
#include "DHT.h"
#define DHTPIN 14 
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float t, h;

//DS18B20 LIB
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float Soiltemp;

//Relay Pin
#define RelayPin 13

//Buzzer Pin
#define BuzzerPin 27

//Variables
int RelayTempHigh=26;
int RelayTempLow=21;
int BuzzerTempHigh=30;
int SoilTempHigh=30;

void sendSensor()
{
  //DHT11 Air Temperature and Humidity
  h = dht.readHumidity();
  t = dht.readTemperature();  
  Blynk.virtualWrite(V0, t);
  Blynk.virtualWrite(V1, h);

  if (isnan(h) || isnan(t)) {
    Serial.println("No Reading from DHT sensor!");
    return;
  }

  //Soil Tempreture
  DS18B20.requestTemperatures();
  Serial.print(DS18B20.getTempCByIndex(0));
  Soiltemp = DS18B20.getTempCByIndex(0);
  Serial.println(Soiltemp); 
  Blynk.virtualWrite(V2, Soiltemp);

  //Heat Mat relay on and off with DS18B20
  pinMode(RelayPin, OUTPUT);
  //Relay ON
  if(Soiltemp < RelayTempLow){
    digitalWrite(RelayPin, HIGH);
    Serial.println("Heat Mat ON!");
    Blynk.logEvent("heat_mat_on", "Soil Temperature is under 21°C, Heat Mat is ON!");
  }

  //Relay OFF
  if(Soiltemp > RelayTempHigh){
    digitalWrite(RelayPin, LOW);
    Serial.println("Heat Mat OFF!");
    Blynk.logEvent("heat_mat_off", "Soil Temperature is over 26°C, Heat Mat is OFF!");
  }

  //Heat Mat Relay Blynk Switch
  Blynk.virtualWrite(V3, RelayPin);

  //Air & Soil Temperature High Buzzer
  pinMode(BuzzerPin, OUTPUT);

  if(t > BuzzerTempHigh){
    digitalWrite(BuzzerPin, HIGH);
    delay(3500);
    digitalWrite(BuzzerPin, LOW);
    delay(300000);
    Serial.println("Air Temperature is over 30°C, Air Greenhouse!");
    Blynk.logEvent("air_temp_high", "Air Temperature is over 30°C, Air Greenhouse!");
  }

  if(Soiltemp > SoilTempHigh){
    digitalWrite(BuzzerPin, HIGH);
    delay(3500);
    digitalWrite(BuzzerPin, LOW);
    delay(120000);
    Serial.println("Soil Temperature is over 30°C, Air Greenhouse!");
    Blynk.logEvent("soil_temp_high", "Soil Temperature is over 30°C, Air Greenhouse!");
  }
}

void setup()
{   
  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  DS18B20.begin();
  delay(2000);
  timer.setInterval(1000L, sendSensor);
 
  }

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
}

Those blocking delays are probably what’s causing the Blynk disconnects.

Pete.

Blocking dalays?

Should I put the delays as int?

Pete.

Thank you Pete. I will have a read and try to figure it out.
Any advise on the master switch for the relay?

The term Master Switch is confusing me.
Do you mean a manual override switch? If so then this also gets a mention in the timer tutorial I linked you to.

If not then you need to elaborate.

Pete.

Hi Pete, If you do not mind. Will you please have a look at my code again and see if I did understand your blocking delays correctly or should the delays be completely removed?

#define BLYNK_TEMPLATE_ID "######"
#define BLYNK_DEVICE_NAME "######"
#define BLYNK_AUTH_TOKEN "#####"

#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>


char auth[] = "######";

char ssid[] = "####";  // type your wifi name
char pass[] = "#####";  // type your wifi password

BlynkTimer timer;
BlynkTimer airtempbuzhigh;
BlynkTimer soiltempbuzhigh;

//DHT11 LIB
#include "DHT.h"
#define DHTPIN 14 
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float t, h;

//DS18B20 LIB
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float Soiltemp;

//Relay Pin
#define RelayPin 13

//Buzzer Pin
#define BuzzerPin 27

//Variables
int RelayTempHigh=26;
int RelayTempLow=21;
int AirTempHigh=30;
int SoilTempHigh=30;


void sendSensor()
{
  //DHT11 Air Temperature and Humidity
  h = dht.readHumidity();
  t = dht.readTemperature();  
  Blynk.virtualWrite(V0, t);
  Blynk.virtualWrite(V1, h);

  if (isnan(h) || isnan(t)) {
    Serial.println("No Reading from DHT sensor!");
    return;
  }

  //Soil Tempreture
  DS18B20.requestTemperatures();
  Serial.print(DS18B20.getTempCByIndex(0));
  Soiltemp = DS18B20.getTempCByIndex(0);
  Serial.println(Soiltemp); 
  Blynk.virtualWrite(V2, Soiltemp);

  //Heat Mat relay on and off with DS18B20
  pinMode(RelayPin, OUTPUT);
  //Relay ON
  if(Soiltemp < RelayTempLow){
    digitalWrite(RelayPin, HIGH);
    Serial.println("Heat Mat ON!");
    Blynk.logEvent("heat_mat_on", "Soil Temperature is under 21°C, Heat Mat is ON!");
  }

  //Relay OFF
  if(Soiltemp > RelayTempHigh){
    digitalWrite(RelayPin, LOW);
    Serial.println("Heat Mat OFF!");
    Blynk.logEvent("heat_mat_off", "Soil Temperature is over 26°C, Heat Mat is OFF!");
  }

  //Heat Mat Relay Blynk Switch
  Blynk.virtualWrite(V3, RelayPin);

}

void air_temp_buz_high()
{
  //Air Temperature High Buzzer
  pinMode(BuzzerPin, OUTPUT);

  if(t > AirTempHigh){
    digitalWrite(BuzzerPin, HIGH);
    delay(3500);
    digitalWrite(BuzzerPin, LOW);
    delay(300000);
    Serial.println("Air Temperature is over 30°C, Air Greenhouse!");
    Blynk.logEvent("air_temp_high", "Air Temperature is over 30°C, Air Greenhouse!");
  }
}

void soil_temp_buz_high()
{
  //Soil Temperature High Buzzer
  pinMode(BuzzerPin, OUTPUT);
  
  if(Soiltemp > SoilTempHigh){
    digitalWrite(BuzzerPin, HIGH);
    delay(3500);
    digitalWrite(BuzzerPin, LOW);
    delay(120000);
    Serial.println("Soil Temperature is over 30°C, Air Greenhouse!");
    Blynk.logEvent("soil_temp_high", "Soil Temperature is over 30°C, Air Greenhouse!");
  }
}

void setup()
{   
  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  DS18B20.begin();
  delay(2000);
  timer.setInterval(1000L, sendSensor);
  airtempbuzhigh.setInterval(1000L, air_temp_buz_high);
  soiltempbuzhigh.setInterval(1000L, soil_temp_buz_high);
 
  }

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
  airtempbuzhigh.run();
  soiltempbuzhigh.run();
}

You clearly didn’t read the bit of my tutorial that explained that one timer object is sufficient for 16 timers.

Blynk won’t work if you use delays. The Blynk library requires constant communication with the Blynk server and the delay() command blocks code execution. Stop using them.

If you need a non-blocking timer then you can use a timeout timer, as described in my tutorial.

You also need to sort-out your logEvent notifications.
You should read this…

Pete.

Thank you, Pete I understand the 16-timer function now.

As a noob, I just can’t wrap my head around how to use the timeout timer in an IF Statement.

Is this correct or am I still not getting it?

void air_temp_buz_high()
{
  //Air Temperature High Buzzer
  pinMode(BuzzerPin, OUTPUT);

  
  timer.setTimeout(3500L, []()
  {
  if(t > AirTempHigh){
    digitalWrite(BuzzerPin, HIGH);
    Serial.println("Air Temperature is over 30°C, Air Greenhouse!");
    Blynk.logEvent("air_temp_high", String("Air Temperature is over ") + t, String("Air Greenhouse!");
  }
  });

  timer.setTimeout(300000L , []()
  {
    digitalWrite(BuzzerPin, LOW);
  });
}

All pinMode statements should be in your void setup. They only need to run once at startup.

Your previous code had the if statement, with a blocking delay inside it…

You’ve now decided to have a timeout timer with an if statement inside it, which makes no sense…

And you haven’t addressed the logEvent issue I mentioned.

Pete.

Am I getting closer?

#define BLYNK_TEMPLATE_ID "#####"
#define BLYNK_DEVICE_NAME "#####"
#define BLYNK_AUTH_TOKEN "#####"

#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>


char auth[] = "######";

char ssid[] = "#####";  // type your wifi name
char pass[] = "####";  // type your wifi password

BlynkTimer timer;

//DHT11 LIB
#include "DHT.h"
#define DHTPIN 14 
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float t, h;

//DS18B20 LIB
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float Soiltemp;

//Relay Pin
#define RelayPin 13

//Buzzer Pin
#define BuzzerPin 27

//Variables
int RelayTempHigh=26;
int RelayTempLow=21;
int AirTempHigh=30;
int SoilTempHigh=30;
bool alert_sent = false;


void sendSensor()
{
  //DHT11 Air Temperature and Humidity
  h = dht.readHumidity();
  t = dht.readTemperature();  
  Blynk.virtualWrite(V0, t);
  Blynk.virtualWrite(V1, h);

  if (isnan(h) || isnan(t)) {
    Serial.println("No Reading from DHT sensor!");
    return;
  }

  //Soil Tempreture
  DS18B20.requestTemperatures();
  Serial.print(DS18B20.getTempCByIndex(0));
  Soiltemp = DS18B20.getTempCByIndex(0);
  Serial.println(Soiltemp); 
  Blynk.virtualWrite(V2, Soiltemp);

  //Heat Mat relay on and off with DS18B20

  //Relay ON
  if(Soiltemp < RelayTempLow && alert_sent == false)
  {
    digitalWrite(RelayPin, HIGH);
    Serial.println("Heat Mat ON!");
    Blynk.logEvent("heat_mat_on", String("Heat Mat is ON!, Soil Temperature is under ") + Soiltemp);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(Soiltemp >= RelayTempLow && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New low-temperature events will trigger a new alert notification");
    Serial.println();
  }

  //Relay OFF
  if(Soiltemp > RelayTempHigh && alert_sent == false)
  {
    digitalWrite(RelayPin, LOW);
    Serial.println("Heat Mat OFF!");
    Blynk.logEvent("heat_mat_off", String("Heat Mat is OFF!, Soil Temperature is over ") + Soiltemp);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(Soiltemp <= RelayTempHigh && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New high-temperature events will trigger a new alert notification");
    Serial.println();
  }

  //Heat Mat Relay Blynk Switch
  Blynk.virtualWrite(V3, RelayPin);

}

void air_temp_buz_high()
{
  //Air Temperature High Buzzer
  
  if(t > AirTempHigh && alert_sent == false)
  {
    Blynk.logEvent("air_temp_high", String("Air Greenhouse!, Air Temperature is over ") + t);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(t <= AirTempHigh && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New high-temperature events will trigger a new alert notification");
    Serial.println();
  }

  timer.setTimeout(3500L, []()
  {
    digitalWrite(BuzzerPin, HIGH);
  });

  timer.setTimeout(300000L , []()
  {
    digitalWrite(BuzzerPin, LOW);
  });
}

void soil_temp_buz_high()
{
  //Soil Temperature High Buzzer
  
  if(Soiltemp > SoilTempHigh && alert_sent == false)
  {
    Blynk.logEvent("soil_temp_high", String("Air Greenhouse!, Soil Temperature is over ") + t);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(Soiltemp <= SoilTempHigh && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New high-temperature events will trigger a new alert notification");
    Serial.println();
  }

  timer.setTimeout(3500L, []()
  {
    digitalWrite(BuzzerPin, HIGH);
  });

  timer.setTimeout(120000L , []()
  {
    digitalWrite(BuzzerPin, LOW);
  });
}

void setup()
{   
  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  DS18B20.begin();
  delay(2000);
  pinMode(RelayPin, OUTPUT);
  pinMode(BuzzerPin, OUTPUT);
  timer.setInterval(1000L, sendSensor);
  timer.setInterval(1000L, air_temp_buz_high);
  timer.setInterval(1000L, soil_temp_buz_high);
 
  }

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
  
}

I’m guessing that your buzzer doesn’t work as expected?

I guess you missed this part of my tutorial…

Note that with timeout timers, the code execution is not paused until the timer ends. If you place a Lambda timer in a piece of code then the code execution will ‘step over’ the Lambda timer and continue to execute, until the timer expires.

For example, This code:

  Serial.println("Location A");

  timer.setTimeout(5000L, []() 
  {  
    // When the timer completes, any code here will be executed
    Serial.println("The timer has completed");
  }); 

  Serial.println("Location B");
  Serial.println("Location C");

would produce this output in the serial monitor:

Location A
Location B
Location C
The timer has completed

Pete.

1 Like

So would it be correct if I say I must take out the second timeout timer?

void air_temp_buz_high()
{
  //Air Temperature High Buzzer
  
  if(t > AirTempHigh && alert_sent == false)
  {
    Blynk.logEvent("air_temp_high", String("Air Greenhouse!, Air Temperature is over ") + t);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(t <= AirTempHigh && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New high-temperature events will trigger a new alert notification");
    Serial.println();
  }

  timer.setTimeout(3500L, []()
  {
    digitalWrite(BuzzerPin, HIGH);
  });
}

Or is it like this?

void air_temp_buz_high()
{
  //Air Temperature High Buzzer
  
  if(t > AirTempHigh && alert_sent == false)
  {
    digitalWrite(BuzzerPin, HIGH);
    Blynk.logEvent("air_temp_high", String("Air Greenhouse!, Air Temperature is over ") + t);
    alert_sent = true;
    Serial.println("Blynk Alert Notification Sent!");
    Serial.println();
  }
  else if(t <= AirTempHigh && alert_sent == true)
  {
    alert_sent = false;
    Serial.println("Temperature is now equal to or below the threshold");
    Serial.println("New high-temperature events will trigger a new alert notification");
    Serial.println();
  }

  timer.setTimeout(3500L, []()
  {
    digitalWrite(BuzzerPin, LOW);
  });
}

You need to have nested timeout timers…

timer.setTimeout(x_millis, []()
{
  // when x_mills has passed ang code here will execute
  // and you can start a new nested timer..
  timer.setTimeout(y_millis, []()
  {
    // when y_millis hae passed any code here will execute
  }
  });
{
});

Pete.

1 Like

Hi Pete, Thank you very much for all the assistance.

It looks like my disconnecting and going Offline problem is sorted out, with the new timeout timer code and logEvent code. I also am happy how the buzzer is working at this point.

Thank you very much for not spoon feeding me and made we work till I have the correct code and is happy with the outcome of the code.

Just one last question, It looks like the logEvent code also plays a part in the disconnecting and going offline if the code is not correct?

Not something I’ve experienced.

Pete.

Once again, thank you for being a great teacher. Much appreciated.

1 Like