Water Geyser(Boiler) thermostat

Hi.

I need some help with my Boiler thermostat project. I am quite new to programming but not a complete beginner.

I am using a ESP-01 module, DS18B20 Temp sensor and relay. (Blynk server)

The code I’m using I got from the net and it switch a relay with a Blynk input timer and 2 Blynk buttons, Auto(Timer) and Manual. I modified the code to show Temperature data from the DS18B20 sensor. The code works with Temp data and I can switch the relay with max and min Temperatures. My problem is that if the Temperature switch the relay then I can not use the buttons coz the Temperature holds the relay.

What I want it to do is if I switch the relay manually, or auto with timer, and the Boiler gets to the Max Temp it should switch off, but I also want the manual button to still switch the relay manually so that I can switch off the boiler completely. I want the Max Temp only to be like a safety switch so that the boiler does not go over the set threshold. Here is my code and in lines 90 to 101 is the sendTemps function for the Temp sensor.

#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

#define EEPROM_STATE_ADDRESS_1 128
#define EEPROM_STATE_ADDRESS_2 144
#define relayLed 2
#define relayPin 0
#define SimpleTimer BlynkTimer

float temp = 0.0;
float maxTemp = 28;
float minTemp = 26;

int oneWireBus = 2;
int geyserTemp;

OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

BlynkTimer timer;
WidgetRTC rtc;
WidgetTerminal terminal(V3);
WidgetLED led1(V4);
WidgetLED led2(V5);

char Date[16];
char Time[16];
char auth[] = "";
char ssid[] = "";
char pass[] = "";
long startsecondswd;
long stopsecondswd;
long nowseconds;
bool isFirstConnect = true;

String displaycurrenttimepluswifi;
int wifisignal;
int manual = 0;
int oldstatus;
int automode;

char ledstate = 0;
char schestate = 0;
bool check = true;
bool check2 = true;
bool check3 = true;

void setup() {
  pinMode(relayLed, OUTPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayLed, LOW); // set LED OFF
  Serial.begin(115200);
  Serial.println("Starting");
  Blynk.begin(auth, ssid, pass);
  int mytimeout = millis() / 1000;
  while (Blynk.connect() == false) { // try to connect to server for 10 seconds
    if ((millis() / 1000) >
        mytimeout + 8) { // try local server if not connected within 9 seconds
      break;
    }
  }

  sensors.begin();
  sensors.setResolution(10);

  EEPROM.begin(512);
  ledstate = EEPROM.read(EEPROM_STATE_ADDRESS_1) == 1 ? 1 : 0;
  schestate = EEPROM.read(EEPROM_STATE_ADDRESS_2) == 1 ? 1 : 0;
  ledonstart();

  rtc.begin();
  timer.setInterval(
      10000L,
      activetoday); // check every 10 SECONDS if schedule should run today
  timer.setInterval(
      30000L, reconnectBlynk); // check every 30s if still connected to server
  timer.setInterval(5000L, clockvalue); // check value for time
  timer.setInterval(5000L, sendWifi);   // Wi-Fi singal
  timer.setInterval(1000L, check_status);
  timer.setInterval(1000L, check_sche);
  timer.setInterval(1000L, sendTemps);
}

void sendTemps() {
  sensors.requestTemperatures();
  geyserTemp = sensors.getTempCByIndex(0);
  Blynk.virtualWrite(1, geyserTemp);

  /*if (geyserTemp <= minTemp) {
    digitalWrite(relayPin, HIGH);
  }

  if (geyserTemp >= maxTemp) {
    digitalWrite(relayPin, LOW);
  }*/
}

void ledonstart() {
  if (ledstate == 1) {
    digitalWrite(relayLed, 1);
    Blynk.virtualWrite(V2, 1);
  } else {
    digitalWrite(relayLed, 0);
    Blynk.virtualWrite(V2, 0);
  }

  if (schestate == 1) {
    Blynk.virtualWrite(V11, 1);
    led1.on();
    led2.off();

    if ((schestate == 1) && (check3 == true)) {
      timer.setTimeout(50, resetTerminal);
      timer.setTimeout(50, checklastbuttonpressed);
      automode = 1;
      schestate = 1;
      check3 = false;
    }
  } else {
    Blynk.virtualWrite(V11, 0);
    led1.off();
    led2.on();
  }
}

void check_status() {
  if (digitalRead(relayLed) == HIGH) {
    ledstate = 1;
    if (check == true) {
      EEPROM.write(EEPROM_STATE_ADDRESS_1, ledstate);
      EEPROM.commit();
      Serial.println("EEPROM Write ledstate ON 1");
    }
    check = false;
  } else {
    ledstate = 0;
    if (check == false) {
      EEPROM.write(EEPROM_STATE_ADDRESS_1, ledstate);
      EEPROM.commit();
      Serial.println("EEPROM Write ledstate OFF 1");
    }
    check = true;
  }
}

void check_sche() {
  if (automode == 1) {
    schestate = 1;
    if (check2 == true) {
      EEPROM.write(EEPROM_STATE_ADDRESS_2, schestate);
      EEPROM.commit();
      Serial.println("EEPROM Write schestate ON 1");

      led1.on();
      led2.off();
    }
    check2 = false;
  } else {
    schestate = 0;
    if (check2 == false) {
      EEPROM.write(EEPROM_STATE_ADDRESS_2, schestate);
      EEPROM.commit();
      Serial.println("EEPROM Write schestate OFF 1");

      led1.off();
      led2.on();
    }
    check2 = true;
  }
}

BLYNK_CONNECTED() {
  if (isFirstConnect) {
    Blynk.syncAll();
    Blynk.notify("TIMER STARTING!!!!");
    isFirstConnect = false;
  }
}

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

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;
  }

  displaycurrenttimepluswifi =
      "                                          Clock:  " + displayhour + ":" +
      displayminute + "               Signal:  " + wifisignal + " %";
  Blynk.setProperty(V3, "label", displaycurrenttimepluswifi);
}

void activetoday() { // check if schedule should run today
  if (year() != 1970) {
    if (automode == 1) {
      Blynk.syncVirtual(V10); // sync timeinput widget
    }
  }
}

void checklastbuttonpressed() {
  if (automode == 1) {
    oldstatus = 1; // 5
  } else {
    oldstatus = 2; // 6
  }
}

void restorelastbuttonpressed() {
  if (oldstatus == 1) {
    automode = 1;
    Blynk.virtualWrite(V11, 1);
  } else {
    automode = 0;
    Blynk.virtualWrite(V11, 0);
  }
}

void resetTerminal() {
  terminal.println();
  terminal.println();
  terminal.println();
  terminal.println("AUTO Mode has been selected");
  terminal.println("Wait for update (10 seconds as maximum)");
  terminal.println();
  terminal.println();
  terminal.println();
  terminal.flush();
}

BLYNK_WRITE(V2) // ON-OFF Manual 
                        
{
  if (param.asInt() == 1) { // boton encendido
    terminal.println();
    terminal.println();
    terminal.println();
    terminal.println("Manual MODE is ON");
    terminal.println("Press ON/OFF button if required");
    terminal.println("Device is ON");
    terminal.println();
    terminal.println();
    terminal.flush();

    if (manual == 0) { // está en modo automático
      checklastbuttonpressed();
      manual = 1;
      automode = 0;
      Blynk.virtualWrite(V11, 0);
      digitalWrite(relayLed, HIGH); // set LED ON
      digitalWrite(relayPin, HIGH); // set relay ON
      Blynk.virtualWrite(V2, 1);    // Turn ON Button Widget

    }else { // está en modo manual
      automode = 0;
      Blynk.virtualWrite(V11, 0);
      digitalWrite(relayLed, HIGH); // set LED ON
      digitalWrite(relayPin, HIGH); // set raly ON
      Blynk.virtualWrite(V2, 1);    // Turn ON Button Widget
    }

   } else {

    terminal.println();
    terminal.println();
    terminal.println();
    terminal.println("Manual MODE is ON");
    terminal.println("Press ON/OFF button if required");
    terminal.println("Device is OFF");
    terminal.println();
    terminal.println();
    terminal.flush();

    if (manual == 0) { // modo automático
      checklastbuttonpressed();
      manual = 1;
      automode = 0;
      Blynk.virtualWrite(V11, 0);
      digitalWrite(relayLed, LOW); // set LED OFF
      digitalWrite(relayPin, LOW); // set relay OFF
      Blynk.virtualWrite(V2, 0);   // Turn OFF Button Widge
    } else {
      automode = 0;
      Blynk.virtualWrite(V11, 0);
      digitalWrite(relayLed, LOW); // set LED OFF
      digitalWrite(relayPin, LOW); // set relay OFF
      Blynk.virtualWrite(V2, 0);   // Turn OFF Button Widget
    }
  }
}

BLYNK_WRITE(V11) // Up to you selected 
                         
{
  if (param.asInt() == 1) {
    timer.setTimeout(50, resetTerminal);
    timer.setTimeout(50, checklastbuttonpressed);
    automode = 1;
    schestate = 1;
  } else {
    automode = 0;
    schestate = 0;
  }
}

BLYNK_WRITE(V10) // Up to you 
                         
{
  if (automode == 1) {
    sprintf(Date, "%02d/%02d/%04d", day(), month(), year());
    sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());

    TimeInputParam t(param);

    terminal.print("Auto Mode Checked schedule at: ");
    terminal.println(Time);
    terminal.flush();
    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
      terminal.println("Auto Mode ACTIVE today");
      terminal.flush();
      if (t.hasStartTime()) // Process start time
      {
        terminal.println(String("Start: ") + t.getStartHour() + ":" +
                         t.getStartMinute());
        terminal.flush();
      }
      if (t.hasStopTime()) // Process stop time
      {
        terminal.println(String("Stop : ") + t.getStopHour() + ":" +
                         t.getStopMinute());
        terminal.flush();
      }
      // Display timezone details, for information purposes only
      terminal.println(
          String("Time zone: ") +
          t.getTZ()); // Timezone is already added to start/stop time
      terminal.println("At least ONE day MUST be selected");
      // terminal.println(String("Time zone offset: ") + t.getTZ_Offset()); //
      // Get timezone offset (in seconds)
      terminal.flush();

      for (int i = 1; i <= 7;
           i++) { // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
        if (t.isWeekdaySelected(i)) {
          terminal.println(String("Day ") + i + " is selected");
          terminal.flush();
        }
      }
      nowseconds = ((hour() * 3600) + (minute() * 60) + second());
      startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
      // Serial.println(startsecondswd);  // used for debugging
      if (nowseconds >= startsecondswd) {
        terminal.print("Auto Mode STARTED at");
        terminal.println(String(" ") + t.getStartHour() + ":" +
                         t.getStartMinute());
        terminal.flush();
        if (nowseconds <=
            startsecondswd +
                90) { // 90s on 60s timer ensures 1 trigger command is sent
          digitalWrite(relayLed, HIGH); // set LED ON
          Blynk.virtualWrite(V2, 1);
          // code here to switch the relay ON
          digitalWrite(relayPin, HIGH); // set relay ON
        }
      } else {
        digitalWrite(relayLed, LOW); // set LED OFF
        Blynk.virtualWrite(V2, 0);
        terminal.println("Auto Mode Device NOT STARTED today");
        terminal.flush();
      }
      stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
      // Serial.println(stopsecondswd);  // used for debugging
      if (nowseconds >= stopsecondswd) {
        digitalWrite(relayLed, LOW); // set LED OFF
        Blynk.virtualWrite(V2, 0);
        terminal.print("Auto Mode STOPPED at");
        terminal.println(String(" ") + t.getStopHour() + ":" +
                         t.getStopMinute());
        terminal.flush();
        if (nowseconds <=
            stopsecondswd +
                90) { // 90s on 60s timer ensures 1 trigger command is sent
          digitalWrite(relayLed, LOW); // set LED OFF
          Blynk.virtualWrite(V2, 0);
          // code here to switch the relay OFF
          digitalWrite(relayPin, LOW); // set relay OFF
        }
      } else {
        if (nowseconds >= startsecondswd) {
          digitalWrite(relayLed, HIGH); // set LED ON
          Blynk.virtualWrite(V2, 1);
          terminal.println("Auto Mode is ON");
          terminal.flush();
        }
      }
    } else {
      terminal.println("Auto Mode INACTIVE today");
      terminal.flush();
      // nothing to do today, check again in 30 SECONDS time
    }
    terminal.println();
  }
}

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

void loop() {
  if (Blynk.connected()) {
    Blynk.run();
  }
  timer.run();
}

/*void tempSwitchOn() {
  if (geyserTemp <= minTemp) {
    digitalWrite(relayPin, HIGH);
  }
}

void tempSwitchOff() {
  if (geyserTemp >= maxTemp) {
    digitalWrite(relayPin, LOW);
    terminal.println("OFF");
  }
}*/

At the end of the code is some functions, tempSwichOn & Off, that I tried to call from the BLYNK_WRITE(V2) button but it did not work I even tried to call it from the Timer function.

Hope someone can help.
Thank you.

You will need nested if statements with the first one answering the switch conditions.

int switchFlag;        //declare globally 

if(switchFlag == 1)
{
   if(temperature < setpoint)
   {
       boiler on


//in the BLYNK_WRITE function 

switchFlag = param.asInt     //do not redfine as int switchFlag!!!!

Will not work unless you have a sensor that feeds back the relay state. Or as an alternative I would suggest a momentary switch to another GPIO pin and record that state in your code.

Hello.

Thank you for the reply daveblynk . I just had to go figure out how the nested If statements work, but it is working now I can work with it like this.

Thank you.