Heating Controller with Scheduler. (Temperature sensor ds18b20)

Hi mates!
I have done a small project to replace the “Elro KT100 Thermostat” and use Blynk instead for a friend of mine.

This is the ugly device to be replaced:

image

The controller works together with two different schedulers (Monday-Friday and Saturday-Sunday).

The main tab is like this:

In this tab you can see the two schedulers. My colleague will be able to activate/deactivate them or press the On/Off button to run the system manually without any scheduler.

The system remembers the last choice when you pressed Manual/Auto button so once you leave the system in “Auto” again, there’s no need to select the schedulers.

The On/Off button is the new “Styled button” so it changes according temperature and status:

-Scheduler is ON and the Relay is activated (the temperature is low):

image

-Scheduler is ON and the Relay is deactivated (the temperature is high):

image

-Scheduler is OFF and the Relay is deactivated. The system is waiting for a new “day”:

image

-System is Off (On/Off button has been pressed)

image

-System is in Manual mode and Relay is activated (the temperature is low):

image

-System is in Manual mode and Relay is deactivated (the temperature is high):

image

Using the setup “tab” my colleague will be be able to adjust the sensor to modify its values (rudimentary calibration), fix the temperature he wants at home, adjust the hysteresis to turn on-off the heater and fix a temperature in which the system will send a notification to advise the temperature is low than “x” degrees.
At the same time, there’s a label showing that the Sensor is OK or not according its status (3 “bad” readings and the system is stopped automatically…safety first!)

Other “tab” to Reboot the ESP if needed.

The board I’m using for this purpose is the Lolin NodeMCU 1.0, the temperature sensor is the well-known ds18b20 and a small Relay board:

The ds18b20 goes to Pin D7 and the Relay to Pin D1

The code is the next one:
(Remember, I’m NOT a coder… the code can be improved but to be honest I’m quite happy as it is right now)

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <ArduinoOTA.h>       // for local OTA updates
#define TestLED 5                 // on board LED pin assignment
#define BLYNK_GREEN     "#23C48E"
#define BLYNK_BLUE      "#04C0F8"
#define BLYNK_YELLOW    "#ED9D00"
#define BLYNK_RED       "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
BlynkTimer timer;

//********************* CLOCK DETAILS *********************************************
#include <WidgetRTC.h>//Blynk
WidgetRTC rtc;

//*********************************************************************************

//********************* ds18b20 DETAILS ******************************************
#include <OneWire.h> //ds18b20 Temp
#include <DallasTemperature.h> //ds18b20 Temp
#define Pin D7//  pin DATA ds18b20
OneWire oneWire(Pin); // OneWire PIN DATA
DallasTemperature sensors(&oneWire); // DallasTemperature library

//*******************************************************************************


//********************* SECTION TO COMPLETE WITH YOUR DETAILS *************
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char ssid[] = "xxxxxxxxxxxx";
char pass[] = "xxxxxxxxxxxxxxxxx";
char cloudserver[16] = "blynk-cloud.com";
char localserver[16] = "xxx.xxx.xxx.xxx";   
char OTAhost[] = "OTA-Heater";              // Optional, but very useful
//*********************************************************************************

//********************** variables*************************************************
long startsecondswd;            // weekday start time in seconds
long stopsecondswd;             // weekday stop  time in seconds
long nowseconds;                // time now in seconds
bool isFirstConnect = true;
String displaycurrenttimepluswifi;
int wifisignal;
int manual=0;
int manualpoweron;
int oldstatus;
int mondayfriday;
int saturdaysunday;
int mon_fri_relay = 0;
int sat_sun_relay = 0;
int mondayfridayactive;
int saturdaysundayactive;
int warning=0;
int stopsystem=0; 
int low_notify=0;
unsigned int myServerTimeout  =  3500;  //  3.5s server connection timeout (SCT)
unsigned int myWiFiTimeout    =  7500;  //  3.2s WiFi connection timeout   (WCT)
unsigned int functionInterval =  7500;  //  7.5s function call frequency   (FCF)
unsigned int blynkInterval    = 25000L;  // 25.0s check server frequency    (CSF)
float temp;
float adjustment;
float newtemp;
float desiredtemp;
float hysteresis;
float limitinf;// histéresis inferior
float limitsup;// histéresis superior
float notification_temperature;
String displaycurrenttime;
char Date[16];
char Time[16];
//*********************************************************************************


void setup()
{
  pinMode(TestLED, OUTPUT);
  digitalWrite(TestLED, LOW); // set LED OFF
  Serial.begin(115200);
  Serial.println("\n Starting");
  if(WiFi.status() == 6){
  Serial.println("\tWiFi not connected yet.");
  }

 timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval
 timer.setInterval(1000L, activetoday);  // check every 1s if schedule should run today 
 timer.setInterval(5000L, clockvalue);  // check value for time
 timer.setInterval(5000L, sendWifi);    // Wi-Fi singal
 timer.setInterval(4000L, CheckTemp);    // Check Temperature
 timer.setInterval(4000L, Heartbeat);    // Heartbeat
 timer.setInterval(20000L, CheckSensorTemp); //Check Sensor Temp
 
 
  unsigned long startWiFi = millis();
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED){
    delay(2000);
    if(millis() > startWiFi + myWiFiTimeout){
      Serial.println("\tCheck the WiFi router. ");
      break;
      } 
   Blynk.config(auth, localserver,8080);
   checkBlynk();
   } 
 rtc.begin(); //RTC CLOCK BEGIN
 sensors.begin();// Sensor ds18b20
 ArduinoOTA.setHostname(OTAhost);              // for local OTA updates
 ArduinoOTA.begin();  // for local OTA updates
}

void reconnectBlynk() {
  if (!Blynk.connected()) {
    if(Blynk.connect()) {
     BLYNK_LOG("Reconnected");
     Blynk.syncVirtual(V4,V5,V6,V7);
     delay(50);
     Blynk.syncVirtual(V1,V2,V8,V9);
     delay(50);
     Blynk.syncVirtual(V12,V14,V15,V16);
     delay(50);    
    } else {
      BLYNK_LOG("Not reconnected");
    }
  }
}

BLYNK_CONNECTED() 
{
  if (isFirstConnect) {
  timer.setTimeout(100, notify_start);
  isFirstConnect = false;
}
}

void notify_start ()
{ 
   Blynk.notify("Heater Starting!!");
   Blynk.virtualWrite(V8, "     ");
   Blynk.virtualWrite(V20, "     ");
   Blynk.syncVirtual(V4,V5,V6,V7);
   delay(50);
   Blynk.syncVirtual(V1,V2,V8,V9);
   delay(50);
   Blynk.syncVirtual(V12,V14,V15);
   delay(50);
   Blynk.syncVirtual(V16,V21);
   delay(50);
}


BLYNK_WRITE(V10)
{
  adjustment = param.asFloat();
}

BLYNK_WRITE(V16)
{
 hysteresis = param.asFloat();
 limitinf = (desiredtemp-hysteresis);
 Blynk.virtualWrite(V14, limitinf);
 delay(20); 
 limitsup = (desiredtemp+hysteresis);
 Blynk.virtualWrite(V15, limitsup);
}

BLYNK_WRITE(V12)
{
 desiredtemp = param.asFloat();
 Blynk.virtualWrite(V22, desiredtemp);
 limitinf = (desiredtemp-hysteresis);
 Blynk.virtualWrite(V14, limitinf);
 delay(20); 
 limitsup = (desiredtemp+hysteresis);
 Blynk.virtualWrite(V15, limitsup);
}

BLYNK_WRITE(V1)  // Manual/Auto selection
{
  if (param.asInt()==1) {
    manual=1;
    checklastbuttonpressed ();
    mondayfriday=0;
    saturdaysunday=0;
    Blynk.setProperty (V2,"offLabel", "OFF");
    Blynk.setProperty (V2,"offBackColor","#ED9D00") ; //Yellow color 
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V7, 0);
    
  } else {
    restorelastbuttonpressed ();
    manual=0;
    Blynk.setProperty (V2,"offLabel", "OFF");
    Blynk.setProperty (V2,"offBackColor","#ED9D00") ; //Yellow color 
    Blynk.virtualWrite(V2, 0);
    digitalWrite(TestLED, LOW); // set LED OFF
    Blynk.virtualWrite(V21, 0);
}
}

BLYNK_WRITE(V2)  // ON-OFF Manual 
{
    if (param.asInt()==1) {  // On/off button  
     manualpoweron=1;
     Blynk.setProperty (V2,"onLabel", "ON");
     Blynk.setProperty (V2,"onBackColor","#ED9D00") ; //Yellow color 
     
        if (manual==0){      //Automatic mode     
         checklastbuttonpressed ();
         manual=1;
         mondayfriday=0;
         saturdaysunday=0;

         Blynk.virtualWrite(V1, 1);
         Blynk.virtualWrite(V5, 0);
         Blynk.virtualWrite(V7, 0);
         Blynk.virtualWrite(V2, 1);   //Turn ON Button Widget
         
         } else {             //Manual Mode
         mondayfriday=0;
         saturdaysunday=0;
         Blynk.virtualWrite(V1, 1);
         Blynk.virtualWrite(V5, 0);
         Blynk.virtualWrite(V7, 0);
         Blynk.virtualWrite(V2, 1);   //Turn ON Button Widget
         }   
                                 
    }else { 
        manualpoweron=0;   
        if (manual==0){      //Automatic mode
        Blynk.setProperty (V2,"offLabel", "OFF");
        Blynk.setProperty (V2,"offBackColor","#ED9D00") ; //Yellow color 
         checklastbuttonpressed ();
         manual=1;
         mondayfriday=0;
         saturdaysunday=0;
         Blynk.virtualWrite(V1, 1);
         Blynk.virtualWrite(V5, 0);
         Blynk.virtualWrite(V7, 0);
         digitalWrite(TestLED, LOW); // set LED OFF
         Blynk.virtualWrite(V2, 0);   //Turn OFF Button Widget
         Blynk.virtualWrite(V21, 0);
         } else { 
         Blynk.setProperty (V2,"offLabel", "OFF");
         Blynk.setProperty (V2,"offBackColor","#ED9D00") ; //Yellow color  
         mondayfriday=0;
         saturdaysunday=0; 
         Blynk.virtualWrite(V1, 1);
         Blynk.virtualWrite(V5, 0);
         Blynk.virtualWrite(V7, 0);
         digitalWrite(TestLED, LOW); // set LED OFF
         Blynk.virtualWrite(V2, 0);   //Turn OFF Button Widget
         Blynk.virtualWrite(V21, 0);
         }  
         }
}

BLYNK_WRITE(V5)  // Monday-Friday selected
{
  if (param.asInt()==1) { 
  timer.setTimeout(20, resetManual);
  timer.setTimeout(20, checklastbuttonpressed);
   mondayfriday=1;
    
  } 
  else {
  mondayfriday=0;
  timer.setTimeout(20, resetManual);
}
}

BLYNK_WRITE(V7)  // Saturday-Sunday selected
{
  if (param.asInt()==1) {
   timer.setTimeout(20, resetManual);
   timer.setTimeout(20, checklastbuttonpressed);
   saturdaysunday=1;
  } else {
   saturdaysunday=0;
   timer.setTimeout(20, resetManual);
}
}

void resetManual()
{
  manual=0;
  Blynk.virtualWrite(V1, 0);   //Turn OFF Manual Mode Widget
  Blynk.virtualWrite(V2, 0);   //Turn OFF Button Widget Device
  digitalWrite(TestLED, LOW); // set LED OFF
  Blynk.virtualWrite(V21, 0);
}

void Heartbeat() 
{
  Blynk.virtualWrite(V18,"\xE2\x97\x89"); //Heartbeat at VPIN 18  
  timer.setTimeout(2000L,[](){Blynk.virtualWrite(V18,"\xE2\x97\x8E");});
}


void CheckSensorTemp() 
{
  sensors.requestTemperatures(); //Read sensor temp
  float sensortemp = sensors.getTempCByIndex(0);
  if(sensortemp >= 0.0) {
  warning =0;
  stopsystem=0;
  Serial.println("Sensor OK. NO Warnings");
  Blynk.virtualWrite(V20, "Sensor OK. NO Warnings");
  }
 if(sensortemp <= 0.0) {
   if(warning==0){ 
    Blynk.notify("Sensor failed. First Warning");
    Serial.println("Sensor failed. First Warning"); 
    Blynk.virtualWrite(V20, "Sensor failed. First Warning");
    }
  
  if(warning==1){
    Blynk.notify("Sensor failed. Second Warning");
    Serial.println("Sensor failed. Second Warning"); 
    Blynk.virtualWrite(V20, "Sensor failed. Second Warning");
    }
  if(warning==2){
    stopsystem=1;
    Blynk.notify("Stopping System");
    Serial.println("Stopping System");
    Blynk.virtualWrite(V1, 0);
    Blynk.virtualWrite(V2, 0);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V7, 0);
    mondayfriday=0;
    saturdaysunday=0;
    manual=0;
    digitalWrite(TestLED, LOW); 
    Blynk.virtualWrite(V17, "--.--");
    Blynk.virtualWrite(V20, "Sensor failed. System stopped");
    }
  if (warning <= 2) {warning++;}
  else warning = 3;// Warning sequence = 3 so system is locked.
 }
}

void CheckTemp() 
{
 sensors.requestTemperatures(); //Read sensor temp
 temp = sensors.getTempCByIndex(0);
 newtemp = temp+adjustment;
 if (warning == 3) {Blynk.virtualWrite(V17, "--:--");}
 else {Blynk.virtualWrite(V17, newtemp);}

 if((stopsystem==0) && (manual==0) && (newtemp >= limitsup) && (mondayfriday==1) && (mon_fri_relay==1)){
 Serial.println("Cooling");
 Blynk.virtualWrite(V2, 1);
 Blynk.setProperty (V2,"onLabel", "ON > Cooling");
 Blynk.setProperty (V2,"onBackColor","#04C0F8") ; //Blue color "#04C0F8"
 digitalWrite(TestLED, LOW);
 Blynk.virtualWrite(V21, 0);
 }

 if((stopsystem==0) && (manual==0) && (newtemp <= limitinf) && (mondayfriday==1) && (mon_fri_relay==1)) {
 Serial.println("Heating");
 Blynk.virtualWrite(V2, 1);
 Blynk.setProperty (V2,"onLabel", "ON > Heating");
 Blynk.setProperty (V2,"onBackColor","#D3435C") ; //Red color
 digitalWrite(TestLED, HIGH); 
 Blynk.virtualWrite(V21, 1);
  }

 if((stopsystem==0) && (manual==0) && (newtemp >= limitsup) && (saturdaysunday==1) && (sat_sun_relay==1)){
 Serial.println("Cooling");
 Blynk.virtualWrite(V2, 1);
 Blynk.setProperty (V2,"onLabel", "ON > Cooling");
 Blynk.setProperty (V2,"onBackColor","#04C0F8") ; //Blue color "#04C0F8"
 digitalWrite(TestLED, LOW);
 Blynk.virtualWrite(V21, 0);
 }

 if((stopsystem==0) && (manual==0) && (newtemp <= limitinf) && (saturdaysunday==1) && (sat_sun_relay==1)) {
 Serial.println("Heating");
 Blynk.virtualWrite(V2, 1);
 Blynk.setProperty (V2,"onLabel", "ON > Heating");
 Blynk.setProperty (V2,"onBackColor","#D3435C") ; //Red color
 digitalWrite(TestLED, HIGH);
 Blynk.virtualWrite(V21, 1); 
  }

 if((stopsystem==0) && (manual==0) && (mon_fri_relay==0) && (mondayfridayactive==1) && (mondayfriday==1)){
 Serial.println("Waiting");
 Blynk.virtualWrite(V2, 0);
 Blynk.setProperty (V2,"offLabel", "OFF > Waiting");
 Blynk.setProperty (V2,"offBackColor","#5F7CD8") ; //Dark blue color 
 digitalWrite(TestLED, LOW);
 Blynk.virtualWrite(V21, 0);
 }

 if((stopsystem==0) && (manual==0) && (sat_sun_relay==0) && (saturdaysundayactive==1) && (saturdaysunday==1)){
 Serial.println("Waiting");
 Blynk.virtualWrite(V2, 0);
 Blynk.setProperty (V2,"offLabel", "OFF > Waiting");
 Blynk.setProperty (V2,"offBackColor","#5F7CD8") ; //Dark blue color 
 digitalWrite(TestLED, LOW);
 Blynk.virtualWrite(V21, 0);
 }

 if((stopsystem==0) && (manual==1) && (manualpoweron==1) && (newtemp <= limitinf)){
 Serial.println("Manual Heating");
 Blynk.setProperty (V2,"onLabel", "Manual > Heating");
 Blynk.setProperty (V2,"onBackColor","#D3435C") ; //Red color
 digitalWrite(TestLED, HIGH); 
 Blynk.virtualWrite(V21, 1);
  }

 if((stopsystem==0) && (manual==1) && (manualpoweron==1) && (newtemp >= limitsup)){
 Serial.println("Manual Cooling");
 Blynk.setProperty (V2,"onLabel", "Manual > Cooling");
 Blynk.setProperty (V2,"onBackColor","#04C0F8") ; //Blue color "#04C0F8"
 digitalWrite(TestLED, LOW);
 Blynk.virtualWrite(V21, 0);
  } 

 if ((newtemp <= notification_temperature) && (low_notify==0)){
 timer.setTimeout(500L, [](){Blynk.notify("Low temperature at home!!");});
 low_notify=1;
 }

 if ((newtemp > (notification_temperature + 0.25)) && (low_notify==1)){  //adding small hysteresis to avoid multiple messages
 low_notify=0;
 }
}

BLYNK_WRITE(V19)
{
 notification_temperature = param.asFloat();
low_notify=0;
}

void checkBlynk()
{
 if (WiFi.status() == WL_CONNECTED)  
  {
    unsigned long startConnecting = millis();    
    while(!Blynk.connected()){
      Blynk.connect();  
      if(millis() > startConnecting + myServerTimeout){
        Serial.print("Unable to connect to server. ");
        break;
      }
    }
  }
  if (WiFi.status() != 3) {
    Serial.print("\tNo WiFi. ");
  } 
  Serial.printf("\tChecking again in %is.\n", blynkInterval /1000);
  Serial.println(); 
}

void sendWifi()
{
  wifisignal = map(WiFi.RSSI(), -105, -40, 0, 100);
  Blynk.virtualWrite(V3, wifisignal);
}

void clockvalue() // Digital clock display of the time
{
 int gmthour = hour();
  if (gmthour == 24){
     gmthour = 0;
  }
  String displayhour =   String(gmthour, DEC);
  int hourdigits = displayhour.length();
  if(hourdigits == 1){
    displayhour = "0" + displayhour;
  }
  String displayminute = String(minute(), DEC);
  int minutedigits = displayminute.length();  
  if(minutedigits == 1){
    displayminute = "0" + displayminute;
  }  
 displaycurrenttime = displayhour + ":" + displayminute;
 Blynk.virtualWrite(V13, displaycurrenttime); 
}

BLYNK_WRITE(V9)  // Reset
{
  if (param.asInt()==1) {
  timer.setTimeout(2000, reset_esp);  
  } 
}

void reset_esp()
{
  Blynk.virtualWrite(V8, "Rebooting");
  delay(3000);
  ESP.restart();
  delay(5000);
}

void activetoday()    // check if schedule should run today
{        
  if(year() != 1970){

   if (mondayfriday==1) {  
    Blynk.syncVirtual(V4); // sync timeinput widget  
   }
   if (saturdaysunday==1) { 
    Blynk.syncVirtual(V6); // sync timeinput widget  
   }
  }
}

void checklastbuttonpressed ()
{
  if((mondayfriday==1)&&(saturdaysunday==0)){ oldstatus=1; }
  if((mondayfriday==0)&&(saturdaysunday==1)){ oldstatus=2; }
  if((mondayfriday==1)&&(saturdaysunday==1)){ oldstatus=3; }
  if((mondayfriday==0)&&(saturdaysunday==0)){ oldstatus=4; }
}

void restorelastbuttonpressed ()
{
  if(oldstatus==1){ mondayfriday=1; saturdaysunday=0; Blynk.virtualWrite(V5, 1); Blynk.virtualWrite(V7, 0); }
  if(oldstatus==2){ mondayfriday=0; saturdaysunday=1; Blynk.virtualWrite(V5, 0); Blynk.virtualWrite(V7, 1); }
  if(oldstatus==3){ mondayfriday=1; saturdaysunday=1; Blynk.virtualWrite(V5, 1); Blynk.virtualWrite(V7, 1); }
  if(oldstatus==4){ mondayfriday=0; saturdaysunday=0; Blynk.virtualWrite(V5, 0); Blynk.virtualWrite(V7, 0); }
}

BLYNK_WRITE(V4)//Monday-Friday
{  
  if (mondayfriday==1) {         
    sprintf(Date, "%02d/%02d/%04d",  day(), month(), year());
    sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
  
    TimeInputParam t(param);
    
    Serial.print("M-F Checked schedule at: ");
    Serial.println(Time);

    int dayadjustment = -1;  
    if(weekday() == 1){
      dayadjustment =  6; // needed for Sunday, Time library is day 1 and Blynk is day 7
    }
    if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
    Serial.println("Monday-Friday ACTIVE today");
    mondayfridayactive=1;
    if (t.hasStartTime()) // Process start time
    {
      Serial.println(String("Start: ") + t.getStartHour() + ":" + t.getStartMinute());
    }
    if (t.hasStopTime()) // Process stop time
    {
      Serial.println(String("Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
    }
    // Display timezone details, for information purposes only 
   Serial.println(String("Time zone: ") + t.getTZ()); // Timezone is already added to start/stop time 
  
     for (int i = 1; i <= 7; i++) {  // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
        if (t.isWeekdaySelected(i)) {
        Serial.println(String("Day ") + i + " is selected");
        }
      } 
    nowseconds = ((hour() * 3600) + (minute() * 60) + second());
    startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    //Serial.println(startsecondswd);  // used for debugging
    if(nowseconds >= startsecondswd){    
      Serial.print("Monday-Friday STARTED at");
      Serial.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
      if(nowseconds <= startsecondswd + 90){    // 90s on 60s timer ensures 1 trigger command is sent
         mon_fri_relay=1;
        // code here to switch the relay ON
      }      
    }
    else{
      Serial.println("Monday-Friday Device NOT STARTED today");
      mondayfridayactive=0;
      mon_fri_relay=0;
    }
    stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
    //Serial.println(stopsecondswd);  // used for debugging
    if(nowseconds >= stopsecondswd){
     mon_fri_relay=0;
     Serial.print("Monday-Friday STOPPED at");
     Serial.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
     
    if(nowseconds <= stopsecondswd + 90){   // 90s on 60s timer ensures 1 trigger command is sent
     mon_fri_relay=0;
       // code here to switch the relay OFF
      }              
    }
    else{
      if(nowseconds >= startsecondswd){  
        mon_fri_relay=1;
        Serial.println("Monday-Friday is ON");    
      }          
    }
  }
  else{
    Serial.println("Monday-Friday INACTIVE today");
    mondayfridayactive=0;
    // nothing to do today, check again in 30 SECONDS time    
  }
  Serial.println();
}
}


 BLYNK_WRITE(V6) //Saturday-Sunday
 {  
  if (saturdaysunday==1) { 
    sprintf(Date, "%02d/%02d/%04d",  day(), month(), year());
    sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
  
    TimeInputParam t(param);
  
    Serial.print("S-S Checked schedule at: ");
    Serial.println(Time);
    
    int dayadjustment = -1;  
    if(weekday() == 1){
    dayadjustment =  6; // needed for Sunday, Time library is day 1 and Blynk is day 7
   }
    if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
    Serial.println("Saturday-Sunday ACTIVE today");
    
    if (t.hasStartTime()) // Process start time
    {
      Serial.println(String("Start: ") + t.getStartHour() + ":" + t.getStartMinute());
    }
    if (t.hasStopTime()) // Process stop time
    {
      Serial.println(String("Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
    }
    // Display timezone details, for information purposes only 
    Serial.println(String("Time zone: ") + t.getTZ()); // Timezone is already added to start/stop time 
 
     for (int i = 1; i <= 7; i++) {  // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
        if (t.isWeekdaySelected(i)) {
        Serial.println(String("Day ") + i + " is selected");
        }
      } 
    nowseconds = ((hour() * 3600) + (minute() * 60) + second());
    startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    if(nowseconds >= startsecondswd){    
      Serial.print("Saturday-Sunday STARTED at");
      Serial.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
      if(nowseconds <= startsecondswd + 90){    // 90s on 60s timer ensures 1 trigger command is sent
        sat_sun_relay=1;
        // code here to switch the relay ON
      }      
    }
    else{
      Serial.println("Saturday-Sunday NOT STARTED today"); 
      sat_sun_relay=0;
      
    }
    stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
    //Serial.println(stopsecondswd);  // used for debugging
    if(nowseconds >= stopsecondswd){
      sat_sun_relay=0;
      Serial.print("Saturday-Sunday STOPPED at");
      Serial.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
      if(nowseconds <= stopsecondswd + 90){   // 90s on 60s timer ensures 1 trigger command is sent
      sat_sun_relay=0;
        // code here to switch the relay OFF
      }              
    }
    else{
      if(nowseconds >= startsecondswd){  
        sat_sun_relay=1;
        Serial.println("Saturday-Sunday is ON");  
      }          
    }
  }
  else{
    Serial.println("Saturday-Sunday INACTIVE today");
    // nothing to do today   
  }
  Serial.println();
}
}

void loop()
{
  if (Blynk.connected()) {
    Blynk.run();
  }
  timer.run();
  ArduinoOTA.handle();       // for local OTA updates
}

QR:

image

That’s all, hope you like it!!

Regards!

Edit:

Small improvement added to amend notification when temperature is low at home.

NEW EDIT: Changing the QR to a new one

11 Likes

Dear @psoro,
looking at your code above I am wondering why you start the same times twice?
Very interesting project though!

timer.setInterval(5000L, clockvalue);  // check value for time
 timer.setInterval(10000L, sendWifi);    // Wi-Fi singal
 timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval
 timer.setInterval(1000L, activetoday);  // check every 1s if schedule should run today 
 timer.setInterval(5000L, clockvalue);  // check value for time
 timer.setInterval(5000L, sendWifi);    // Wi-Fi singal
 timer.setInterval(4000L, CheckTemp);    // Check Temperature
 timer.setInterval(4000L, Heartbeat);    // Heartbeat
 timer.setInterval(20000L, CheckSensorTemp); //Check Sensor Temp
 
1 Like

Hi Mike!
Ups, small mistake at the code! :sweat_smile: Let me amend it!

Thanks for pointing me out!

Edit:

Done! I’m sure this is not the last mistake!

Regards

1 Like

Nice project, I’m working on something similar but then a bit bigger in scale. Its nice to see that you made roughly the same choices as I did in the project.

Thank you for sharing!

edit: going through your code trying to catch new ideas I noticed this:

void reconnectBlynk() {
  if (!Blynk.connected()) {
    if(Blynk.connect()) {
     BLYNK_LOG("Reconnected");
     Blynk.syncVirtual(V4,V5,V6,V7);
     delay(50);
     Blynk.syncVirtual(V1,V2,V8,V9);
     delay(50);
     Blynk.syncVirtual(V12,V14,V15,V16);
     delay(50);    
    } else {
      BLYNK_LOG("Not reconnected");
    }
  }
}

BLYNK_CONNECTED() 
{
  if (isFirstConnect) {
  timer.setTimeout(100, notify_start);
  isFirstConnect = false;
}
}

that is a bit weird, not wrong but unconventional. The usual method is:

void reconnectBlynk() {
  if (!Blynk.connected()) {
    if(Blynk.connect()) {
     BLYNK_LOG("Reconnected");
	 isFirstConnect = true;
	 } else {
      BLYNK_LOG("Not reconnected");
    }
  }
}

BLYNK_CONNECTED() 
{
	 Blynk.syncVirtual(V4,V5,V6,V7);
	 delay(50);
	 Blynk.syncVirtual(V1,V2,V8,V9);
	 delay(50);
	 Blynk.syncVirtual(V12,V14,V15,V16);
	 delay(50);    

  if (isFirstConnect) {
  timer.setTimeout(100, notify_start);
  isFirstConnect = false;
}
}

note that I have no clue what the consequences are, but the blynk_connected is meant for the resync of values. If it works: don’t change is, its more so you know.

///////

I’m curious, can you tell me what this is:
Blynk.virtualWrite(V18,"\xE2\x97\x89"); //Heartbeat at VPIN 18

/////

 if (warning <= 2) {warning++;}
  else {warning = 3;}// Warning sequence = 3 so system is locked.

I didn’t initially know too, but one line statements do not require {} so

 if (warning <= 2) warning++;
  else warning = 3;// Warning sequence = 3 so system is locked.

however, might I suggest:

 warning = min(3, warning++);

Hi @wolph42, thanks for your comments!

Yeap! This is my second surname! :wink:

The syncVirtual pins are also covered at Blynk_connected():

void notify_start ()
{ 
   Blynk.notify("Heater Starting!!");
   Blynk.virtualWrite(V8, "     ");
   Blynk.syncVirtual(V4,V5,V6,V7);
   delay(50);
   Blynk.syncVirtual(V1,V2,V8,V9);
   delay(50);
   Blynk.syncVirtual(V12,V14,V15);
   delay(50);
   Blynk.syncVirtual(V16,V21);
   delay(50);
}

Anyway, I will study in detail your recomendation looking for improvements :slightly_smiling_face:

This is just me playing a bit with unicode characters in Bytes (UTF-8), you can achieve the same thing using the simple Led widget.

image

You are right again… Good catch!

Regards

Nice work.
I see you have a lot of delays in your reset_esp function. Blynk normally isn’t happy with to much delays, but here it’s ok as you are restarting the device. In my projects with reset buttons I have a delay, so that the reset code is not executed unless I press the button for a predefined time, normally 1 sec. That’s a good thing because if I accidentaly touches the button, nothing happens. In your project it will be something like this:

  BLYNK_WRITE(V12) {    
      if (param.asInt()) {
        //button pressed
        start = millis();
      } else {
        //button released    
        if (millis() - start > 1000) {
        Blynk.virtualWrite(V8, "Rebooting");
        ESP.restart();
        delay(5000);
        Blynk.virtualWrite(V8, "");
        }
      }
    }

actually, without the delays you have a great chance that the unit bricks (until hard power cycle!!).

1 Like

Hi, very nice project :+1:, I don’t want to connect with local server, I want to connect with blynk server.
Blynk.config (auth, cloudserver, 8442); Is it enough to change?

Hello Guys
Is there someone of you who already developed this code (even with less functions) to check 3 different rooms temperature and control their relays?

Hi psoro,
what values should be entered in "localserver[16]=“xxx.xxx.xxx.xxx”

@blyank1 That is for the IP address of your Local Server. If you do not know this, then you are not using a Local Server and need not use that method and just stick with the Cloud Server…

char cloudserver[16] = "blynk-cloud.com";
2 Likes

Thanks Gunner

Good morning, wonderful project. How can I replace the sensor with dht22?

//********************* DHT DETAILS ******************************************
#include “DHTesp.h”
#ifdef ESP32
#pragma message(THIS EXAMPLE IS FOR ESP8266 ONLY!)
#error Select ESP8266 board.
#endif

DHTesp dht;

//add the following line in setup
dht.setup(7, DHTesp::DHT22); // Connect DHT sensor to GPIO 7

//and the following in temp functions
delay(dht.getMinimumSamplingPeriod());
float humidity = dht.getHumidity();
float temperature = dht.getTemperature();

// modify the rest of the code to match the changes

//*******************************************************************************

And download library from:

1 Like

Hello !
sorry but you couldn’t help me with the code. I have a very similar code and I need a scheduled hysteresis on and off from yours

Hi @ilia, I was not aware you asked me for help…:sweat_smile:

The hysteresis is included in the code, managed by V16…

Hello, thank you for sharing this great project with us.
I have one question, I do not see in the sketch where the Relay pin is declared.

Pin D1 = GPIO5, to the relay is called TestLED in the code.

Pete.

1 Like

Thank you very much, i thought so but i wasn’t sure.
Greetings:clinking_glasses: