I want to create a climate control

Blynk+esp8266+HTU21D(si70)+relay2
Hello everyone, I want to create a climate control for my orchids, but I am new to working with Arduino IDE and Blynk. At the moment I have experience in creating a meteorological station on esp8266 and a Blynk as well as a Wi-Fi socket. I collected all this on the server blink.
But with the climate control I have trouble, I can’t write the project myself, so I found the one most suitable for my tasks and decided to modify it to fit my hardware. At the moment, the code is completely ready, but the hysteresis unit does not work for me (upon reaching setpoint does not work the relay) For 4 days I have been racking my brains and still can not understand why. I hope for your understanding and support

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <EEPROM.h>
#include <Adafruit_Si7021.h>
#include <SimpleTimer.h>

#define I2C_SCL 5  //d1    
#define I2C_SDA 4  //d2

bool metric = false;
float hum3,  temp5;

uint8_t temppin ; // LOW/HIGH
uint8_t eeprom_temp5 ; // Allow/Disallow
uint8_t min_temp5;
uint8_t max_temp5;
bool flag_temp5_off_state = true;
bool flag_temp5_on_state = true;
uint8_t lastsettemp5;

uint8_t hum3pin ; // LOW/HIGH
uint8_t eeprom_hum3 ; // Allow/Disallow
uint8_t min_hum3;
uint8_t max_hum3;
bool flag_fany_off_state = true;
bool flag_fany_on_state = true;
uint8_t lastm;
uint8_t lastbutton;
uint8_t lastp;
uint8_t lastsethum3;

char auth[] = "9babcd88889420000b8565574b3f1";
char ssid[] = "999";
char pass[] = "000";

Adafruit_Si7021 sensor;
SimpleTimer timer1; // sensor timer
SimpleTimer timer2;  // humcheck
SimpleTimer timer3;  // tempcheck

unsigned long timestamp3;

BLYNK_WRITE(V50) // reset
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0)
  {
    lastp = 0;
    ESP.reset();
  }
}

//---------------------TEMP---------------------------------
BLYNK_WRITE(V19) // write EEPROM temp
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_temp5 == 1)
  {
    lastp = 0;
    int EEaddress = 164;
    EEPROM.write(EEaddress, min_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, max_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, temppin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V25) // eeprom access temp
{
  int pinValue = param.asInt();
  eeprom_temp5 = pinValue;
}
BLYNK_WRITE(V26) // level temp
{
  int pinValue = param.asInt();
  temppin = pinValue;
}

BLYNK_WRITE(V20) // setup temp
{
  int pinValue = param.asInt();
  lastsettemp5 = pinValue;
}
BLYNK_WRITE(V21) // temp down
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_temp5 > 0)
    {
      lastp = 0;
      min_temp5--;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }

  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      max_temp5--;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
BLYNK_WRITE(V22) // temp up
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      min_temp5++;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }

  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 < 100)
    {
      lastp = 0;
      max_temp5++;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
//---------------------TEMP END-----------------------------

//---------------------HUM---------------------------------
BLYNK_WRITE(V13) // write EEPROM hum
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_hum3 == 1)
  {
    lastp = 0;
    int EEaddress = 161;
    EEPROM.write(EEaddress, min_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, max_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, hum3pin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V9) // eeprom access hum
{
  int pinValue = param.asInt();
  eeprom_hum3 = pinValue;
}
BLYNK_WRITE(V12) // level hum
{
  int pinValue = param.asInt();
  hum3pin = pinValue;
}

BLYNK_WRITE(V14) // setup hum
{
  int pinValue = param.asInt();
  lastsethum3 = pinValue;
}
BLYNK_WRITE(V15) // hum down
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_hum3 > 0)
    {
      lastp = 0;
      min_hum3--;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }

  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      max_hum3--;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
BLYNK_WRITE(V17) // hum up
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      min_hum3++;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }

  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 < 100)
    {
      lastp = 0;
      max_hum3++;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
//---------------------HUM END-----------------------------
void tempcheck()
{
  if (temp5 <= min_temp5 && flag_temp5_on_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(15, LOW); //  вкл
      Blynk.virtualWrite(V27, 1023); //  вкл
      Blynk.virtualWrite(V28, 0); //  выкл
    } else {
      digitalWrite(15, HIGH); //  выкл
      Blynk.virtualWrite(V27, 0); //  выкл
      Blynk.virtualWrite(V28, 1023); //  вкл
    }
    digitalWrite(15, LOW); //  вкл
    Blynk.virtualWrite(V10, 1023); //  вкл
    flag_temp5_on_state = false;
    flag_temp5_off_state = true;
  }

  if (temp5 >= max_temp5 && flag_temp5_off_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(15, HIGH); //  вкл
      Blynk.virtualWrite(V27, 0); //  вкл
      Blynk.virtualWrite(V28, 1023); //  выкл
    } else {
      digitalWrite(15, LOW); //  выкл
      Blynk.virtualWrite(V27, 1023); //  выкл
      Blynk.virtualWrite(V28, 0); //  выкл
    }

    digitalWrite(15, HIGH); //  выкл
    Blynk.virtualWrite(V10, 0); //  выкл
    flag_temp5_off_state = false;
    flag_temp5_on_state = true;
  }
}

void humcheck()
{
  if (hum3 <= min_hum3 && flag_fany_on_state)
  {
    if (hum3pin == 1 )
    {
      digitalWrite(13, LOW); //  вкл
      Blynk.virtualWrite(V10, 1023); //  вкл
      Blynk.virtualWrite(V11, 0); //  выкл
    } else {
      digitalWrite(13, HIGH); //  выкл
      Blynk.virtualWrite(V10, 0); //  выкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    }
    digitalWrite(13, LOW); // увлажнитель вкл
    Blynk.virtualWrite(V10, 1023); // увлажнитель вкл
    flag_fany_on_state = false;
    flag_fany_off_state = true;
  }

  if (hum3 >= max_hum3 && flag_fany_off_state)
  {
    if (hum3pin == 0 )
    {
      digitalWrite(13, HIGH); //  вкл
      Blynk.virtualWrite(V10, 0); //  вкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    } else {
      digitalWrite(13, LOW); //  выкл
      Blynk.virtualWrite(V10, 1023); //  выкл
      Blynk.virtualWrite(V11, 0); //  выкл
    }
    digitalWrite(13, HIGH); // увлажнитель выкл
    Blynk.virtualWrite(V10, 0); // увлажнитель выкл
    flag_fany_off_state = false;
    flag_fany_on_state = true;
  }
}

void sendSensor1()
{
  float temp5 = sensor.readTemperature();
  float hum3 = sensor.readHumidity();
  Blynk.virtualWrite(V3, hum3);
  Blynk.virtualWrite(V5, temp5);
}

void readEEPROM(int startAdr, int maxLength, char* dest)
{
  EEPROM.begin(256);
  delay(10);
  for (int i = 0; i < maxLength; i++)
  {
    dest[i] = char(EEPROM.read(startAdr + i));
  }
  EEPROM.end();
}
void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  Wire.begin(I2C_SDA, I2C_SCL);
  EEPROM.begin(256);
  min_hum3 = EEPROM.read(161);
  max_hum3 = EEPROM.read(162);
  hum3pin = EEPROM.read(163);
  min_temp5 = EEPROM.read(164);
  max_temp5 = EEPROM.read(165);
  temppin = EEPROM.read(166);

  timer1.setInterval(1500L, sendSensor1);
  timer2.setInterval(500L, humcheck);
  timer3.setInterval(500L, tempcheck);

  pinMode(13, OUTPUT); // увлажнитель
  digitalWrite(13, HIGH); // увлажнитель выкл
  pinMode(15, OUTPUT); //
  digitalWrite(15, HIGH); //

  Blynk.virtualWrite(V16, min_hum3);
  Blynk.virtualWrite(V18, max_hum3);
  Blynk.virtualWrite(V24, max_temp5);
  Blynk.virtualWrite(V23, min_temp5);

  if (min_hum3 <= 30 ||  min_hum3 >= 99 || max_hum3 <= 30 ||  max_hum3 >= 99) {
    min_hum3 = 45;
    max_hum3 = 50;
  }
  if (min_temp5 <= 0 ||  min_temp5 >= 99 || max_temp5 <= 0 ||  max_temp5 >= 99) {
    min_temp5 = 20;
    max_temp5 = 25;
  }
  if (!sensor.begin())
  {
    Serial.println("Couldn't find sensor!");
    while (1);
  }
}

void loop()
{
  timer1.run();
  timer2.run();
  timer3.run();
  Blynk.run();
}



Reduce this to one timer with three instances (each BlynkTimer can have up to 16)… better memory management and performance that way

Sorry, no idea on the hysteresis bit… that would take more thinking power then I have available right now :stuck_out_tongue:

1 Like

Just taking a quick glance at the code. This function is using temp5,

void tempcheck()
{
 if (temp5 <= min_temp5 && flag_temp5_on_state)
 {

but

void sendSensor1()
{
  float temp5 = sensor.readTemperature();
  float hum3 = sensor.readHumidity();
  Blynk.virtualWrite(V3, hum3);
  Blynk.virtualWrite(V5, temp5);
}

temp5 is declared as a local variable, not global.

Same for humidity.

Scratch that I see them declared as global at the top.

float hum3,  temp5;

Maybe remove the second declaration in the sendSensor1 function.

void sendSensor1()
{
   temp5 = sensor.readTemperature();
   hum3 = sensor.readHumidity();
  Blynk.virtualWrite(V3, hum3);
  Blynk.virtualWrite(V5, temp5);
}
1 Like

Гистерезис это хорошо, но в данной ситуации не вижу смысла его использовать когда можно просто увеличить время проверки температуры и влажности, потом одним if задать рамки включения. совет на будущее

1 Like

Yea, your advice helped solve the problem.
This is because shortage of experience in C :thinking:

looks like a good start, but have a think about incorporating “dewpoint” as an input as well as (or instead of) raw humidity…

Hi Dave1829.I read the paper that you laid out at the dew point. This is a really great idea that will help solve many problems. I also read code examples for my hardware (HTU21D), and I think that my skill is not enough to create such solutions. But I will set myself this task

my simple dew point calculation to all my climate code is this:

double dewPoint(double celsius, double humidity)
{
 // (1) Saturation Vapor Pressure = ESGG(T)
 double RATIO = 373.15 / (273.15 + celsius);
 double RHS = -7.90298 * (RATIO - 1);
 RHS += 5.02808 * log10(RATIO);
 RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO ))) - 1) ;
 RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
 RHS += log10(1013.246);

// factor -3 is to adjust units - Vapor Pressure SVP * humidity

double VP = pow(10, RHS - 3) * humidity;

// (2) DEWPOINT = F(Vapor Pressure)

double T = log(VP / 0.61078); // temp var
return (241.88 * T) / (17.558 - T);
}

so then add

          yourSensorName**DewPoint** = dewPoint(yourSensorName**Temp,** yourSensorName**Hum**);

into your

void sendSensor1()

function :slight_smile:

i think dewpoint function was originally ‘obtained’ from here: https://forum.arduino.cc/index.php?topic=333969.0

Hello guys. Thank you to everyone who helped me. At the moment it’s done: Fixed a bug with (float temp5) (Thanks to Toro_Blanco). Free Loop from timers (Thanks to Gunner). And in order to save your nerves, suffered a pin relay with gpio15 to gpio12. In the near future, I plan to add a time relay for the light and the cooler (if it works out with the schedule for the week :crazy_face:) and also think about how to rewrite the code under the dew point (Thanks to Dave)

#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <EEPROM.h>
#include <Adafruit_Si7021.h>
#include <SimpleTimer.h>

#define I2C_SCL 5  //d1    
#define I2C_SDA 4  //d2
#define relay1 13
#define relay2 12

bool metric = false;

float hum3, temp5;
uint8_t temppin ; // LOW/HIGH
uint8_t eeprom_temp5 ; // Allow/Disallow
uint8_t min_temp5;
uint8_t max_temp5;
bool flag_temp5_off_state = true;
bool flag_temp5_on_state = true;
uint8_t lastsettemp5;

uint8_t hum3pin ; // LOW/HIGH
uint8_t eeprom_hum3 ; // Allow/Disallow
uint8_t min_hum3;
uint8_t max_hum3;
bool flag_fany_off_state = true;
bool flag_fany_on_state = true;
uint8_t lastm;
uint8_t lastbutton;
uint8_t lastp;
uint8_t lastsethum3;

char auth[] = "9babcd14a5f9423fb00000000";
char ssid[] = "MK0000";
char pass[] = "fre0004";//

unsigned long timestamp3;

Adafruit_Si7021 sensor;
BlynkTimer timer;

BLYNK_WRITE(V50) // reset
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0)
  {
    lastp = 0;
    ESP.reset();
  }
}
//---------------------TEMP---------------------------------
BLYNK_WRITE(V19) // write EEPROM temp
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_temp5 == 1)
  {
    lastp = 0;
    int EEaddress = 164;
    EEPROM.write(EEaddress, min_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, max_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, temppin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V25) // eeprom access temp
{
  int pinValue = param.asInt();
  eeprom_temp5 = pinValue;
}
BLYNK_WRITE(V26) // level temp
{
  int pinValue = param.asInt();
  temppin = pinValue;
}

BLYNK_WRITE(V20) // setup temp
{
  int pinValue = param.asInt();
  lastsettemp5 = pinValue;
}
BLYNK_WRITE(V21) // temp down
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_temp5 > 0)
    {
      lastp = 0;
      min_temp5--;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }
  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      max_temp5--;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
BLYNK_WRITE(V22) // temp up
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      min_temp5++;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }
  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 < 100)
    {
      lastp = 0;
      max_temp5++;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
//---------------------TEMP END-----------------------------

//---------------------HUM---------------------------------
BLYNK_WRITE(V13) // write EEPROM hum
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_hum3 == 1)
  {
    lastp = 0;
    int EEaddress = 161;
    EEPROM.write(EEaddress, min_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, max_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, hum3pin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V9) // eeprom access hum
{
  int pinValue = param.asInt();
  eeprom_hum3 = pinValue;
}
BLYNK_WRITE(V12) // level hum
{
  int pinValue = param.asInt();
  hum3pin = pinValue;
}

BLYNK_WRITE(V14) // setup hum
{
  int pinValue = param.asInt();
  lastsethum3 = pinValue;
}
BLYNK_WRITE(V15) // hum down
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_hum3 > 0)
    {
      lastp = 0;
      min_hum3--;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }
  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      max_hum3--;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
BLYNK_WRITE(V17) // hum up
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      min_hum3++;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }
  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 < 100)
    {
      lastp = 0;
      max_hum3++;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
//---------------------HUM END-----------------------------
void tempcheck()
{
  if (temp5 <= min_temp5 && flag_temp5_on_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(12, LOW); //  вкл
      Blynk.virtualWrite(V27, 1023); //  вкл
      Blynk.virtualWrite(V28, 0); //  выкл
    } else {
      digitalWrite(12, HIGH); //  выкл
      Blynk.virtualWrite(V27, 0); //  выкл
      Blynk.virtualWrite(V28, 1023); //  вкл
    }
    //digitalWrite(12, LOW); //  вкл
    //Blynk.virtualWrite(V10, 1023); //  вкл
    flag_temp5_on_state = false;
    flag_temp5_off_state = true;
  }
  if (temp5 >= max_temp5 && flag_temp5_off_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(12, HIGH); //  вкл
      Blynk.virtualWrite(V27, 0); //  вкл
      Blynk.virtualWrite(V28, 1023); //  выкл
    } else {
      digitalWrite(12, LOW); //  выкл
      Blynk.virtualWrite(V27, 1023); //  выкл
      Blynk.virtualWrite(V28, 0); //  выкл
    }

    //digitalWrite(12, HIGH); //  выкл
    //Blynk.virtualWrite(V10, 0); //  выкл
    flag_temp5_off_state = false;
    flag_temp5_on_state = true;
  }
}

void humcheck()
{
  if (hum3 <= min_hum3 && flag_fany_on_state)
  {
    if (hum3pin == 1 )
    {
      digitalWrite(13, LOW); //  вкл
      Blynk.virtualWrite(V10, 1023); //  вкл
      Blynk.virtualWrite(V11, 0); //  выкл
    } else {
      digitalWrite(13, HIGH); //  выкл
      Blynk.virtualWrite(V10, 0); //  выкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    }
    //digitalWrite(13, LOW); // увлажнитель вкл
    //Blynk.virtualWrite(V10, 1023); // увлажнитель вкл
    flag_fany_on_state = false;
    flag_fany_off_state = true;
  }
  if (hum3 >= max_hum3 && flag_fany_off_state)
  {
    if (hum3pin == 1 )
    {
      digitalWrite(13, HIGH); //  вкл
      Blynk.virtualWrite(V10, 0); //  вкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    } else {
      digitalWrite(13, LOW); //  выкл
      Blynk.virtualWrite(V10, 1023); //  выкл
      Blynk.virtualWrite(V11, 0); //  выкл
    }
    //digitalWrite(13, HIGH); // увлажнитель выкл
    //Blynk.virtualWrite(V10, 0); // увлажнитель выкл
    flag_fany_off_state = false;
    flag_fany_on_state = true;
  }
}

void sendSensor1()
{
  temp5 = sensor.readTemperature();
  hum3 = sensor.readHumidity();
  Blynk.virtualWrite(V3, hum3);
  Blynk.virtualWrite(V5, temp5);
}

void readEEPROM(int startAdr, int maxLength, char* dest)
{
  EEPROM.begin(256);
  delay(10);
  for (int i = 0; i < maxLength; i++)
  {
    dest[i] = char(EEPROM.read(startAdr + i));
  }
  EEPROM.end();
}
void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  Wire.begin(I2C_SDA, I2C_SCL);
  EEPROM.begin(256);
  min_hum3 = EEPROM.read(161);
  max_hum3 = EEPROM.read(162);
  hum3pin = EEPROM.read(163);
  min_temp5 = EEPROM.read(164);
  max_temp5 = EEPROM.read(165);
  temppin = EEPROM.read(166);

  timer.setInterval(333L, sendSensor1);
  timer.setInterval(500L, humcheck);
  timer.setInterval(444L, tempcheck);

  pinMode(13, OUTPUT); // увлажнитель
  digitalWrite(13, LOW); // 
  pinMode(12, OUTPUT); // нагреватель
  digitalWrite(12, LOW); //

  Blynk.virtualWrite(V16, min_hum3);
  Blynk.virtualWrite(V18, max_hum3);
  Blynk.virtualWrite(V24, max_temp5);
  Blynk.virtualWrite(V23, min_temp5);

  if (min_hum3 <= 30 ||  min_hum3 >= 99 || max_hum3 <= 30 ||  max_hum3 >= 99) {
    min_hum3 = 45;
    max_hum3 = 50;
  }
  if (min_temp5 <= 0 ||  min_temp5 >= 99 || max_temp5 <= 0 ||  max_temp5 >= 99) {
    min_temp5 = 20;
    max_temp5 = 25;
  }
  if (!sensor.begin())
  {
    Serial.println("Couldn't find sensor!");
    while (1);
  }
}

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

And lastly, I do not know whether to close the topic or leave, since the project is not over yet?

1 Like

Hello guys, I gradually study the time entry widget for lighting, and thanks to the information on the forum, there are almost no questions. Today I would like to ask for help what would be the best way to use and to run the cooler every 30 minutes for 10 minutes. Do I need to use the timer for a millise or is there something more correct?

На твоё усмотрение, но мне лично нравиться задать таймер в 1 секунду и функция в которой switch(i++), позволяет легко задавать временные рамки по переменной i с помощью case, кода мало читать легко.

1 Like

Hi guys, for a long time while I was engaged in the practical study of gardening. I am a little behind in learning programming. But now I have started working hard on the code. I added a control for temperature decrease . During the testing process, the code was found to hang, and I decided to add WDT but have not yet tested it. Thanks to @Costas for EziSchedulerV2 added timers for lighting and basic devices.
Nb Now I have a small farm on which I test my code and hardware. The idea of ​​climate control is growing into something new for me.
Now, because of my small experience in the code, I have a few questions. My “void fantempcheck ()” algorithm sometimes does not work correctly. This is expressed in the fact that temp5 in comparison is stuck at an approximate value to that specified. For example, 25.01 and the relay remains on. I have little experience with timers, and I think that this is the problem.
I also want to understand and learn how to save the state // Scheduler # n Time Input widget after reset
I understand that this forum is not for beginners and was not created for teaching the basics of "C"but I want to understand and I do not have a good mentor. Thank you for your support.

#define BLYNK_PRINT Serial
#define I2C_SCL 5  //d1    
#define I2C_SDA 4  //d2
#define humidifier 13
#define Heater 3
#define Fan 2 
#define Light 0
#define Pump 14 
#define Aero 12

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <EEPROM.h>
#include <Adafruit_Si7021.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <WidgetRTC.h>


WidgetRTC rtc;
BlynkTimer timer;

char currentTime[9];  
bool clockSync = false; 
bool pinValue32;
bool pinValue35;
bool pinValue38;
bool pinValue41;
bool metric = false;

float hum3, temp5;
uint8_t temppin ; // LOW/HIGH
uint8_t eeprom_temp5 ; // Allow/Disallow
uint8_t min_temp5;
uint8_t max_temp5;
bool flag_temp5_off_state = true;
bool flag_temp5_on_state = true;
uint8_t lastsettemp5;

uint8_t hum3pin ; // LOW/HIGH
uint8_t eeprom_hum3 ; // Allow/Disallow
uint8_t min_hum3;
uint8_t max_hum3;
bool flag_fany_off_state = true;
bool flag_fany_on_state = true;
uint8_t lastm;
uint8_t lastbutton;
uint8_t lastp;
uint8_t lastsethum3;

char auth[] = "9babcd14a5f9423fxxxxxxxxxxxx";
char ssid[] = "Tool36";//MKC50
char pass[] = "frekf123";//frekf314

Adafruit_Si7021 sensor;
SimpleTimer timer1; // sensor timer
SimpleTimer timer2;  // humcheck
SimpleTimer timer3;  // tempcheck
SimpleTimer timer4;  // fantempcheck

unsigned long timestamp3;


WidgetTerminal terminal(V51);

BLYNK_WRITE(V50) // reset
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0)
  {
    lastp = 0;
    ESP.reset();
  }
}


//-------------Timer pin-----------
BLYNK_WRITE(V32)
{
  int pinValue32 = param.asInt();
  digitalWrite(Light, pinValue32);
}

BLYNK_WRITE(V35)
{
  int pinValue35 = param.asInt();
  digitalWrite(Fan, pinValue35);
}

BLYNK_WRITE(V38)
{
  int pinValue38 = param.asInt();
  digitalWrite(Pump, pinValue38);
}

BLYNK_WRITE(V41)
{
  int pinValue41 = param.asInt();
  digitalWrite(Aero, pinValue41);
}
//---------------Timer pin end-----------------------------

//---------------------TEMP---------------------------------
BLYNK_WRITE(V19) // write EEPROM temp
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_temp5 == 1)
  {
    lastp = 0;
    int EEaddress = 164;
    EEPROM.write(EEaddress, min_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, max_temp5);
    EEaddress++;
    EEPROM.write(EEaddress, temppin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V25) // eeprom access temp
{
  int pinValue = param.asInt();
  eeprom_temp5 = pinValue;
}
BLYNK_WRITE(V26) // level temp
{
  int pinValue = param.asInt();
  temppin = pinValue;
}

BLYNK_WRITE(V20) // setup temp
{
  int pinValue = param.asInt();
  lastsettemp5 = pinValue;
}
BLYNK_WRITE(V21) // temp down
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_temp5 > 0)
    {
      lastp = 0;
      min_temp5--;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }

  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      max_temp5--;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
BLYNK_WRITE(V22) // temp up
{
  int pinValue = param.asInt();
  if (lastsettemp5 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 - min_temp5 > 1)
    {
      lastp = 0;
      min_temp5++;
      Blynk.virtualWrite(V23, min_temp5);
    }
  }

  if (lastsettemp5 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_temp5 < 100)
    {
      lastp = 0;
      max_temp5++;
      Blynk.virtualWrite(V24, max_temp5);
    }
  }
}
//---------------------TEMP END-----------------------------

//---------------------HUM---------------------------------
BLYNK_WRITE(V13) // write EEPROM hum
{
  int pinValue = param.asInt();
  if (pinValue != lastp && pinValue > 0 && eeprom_hum3 == 1)
  {
    lastp = 0;
    int EEaddress = 161;
    EEPROM.write(EEaddress, min_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, max_hum3);
    EEaddress++;
    EEPROM.write(EEaddress, hum3pin);
    EEPROM.commit();
    //ESP.reset();
  }
}
BLYNK_WRITE(V9) // eeprom access hum
{
  int pinValue = param.asInt();
  eeprom_hum3 = pinValue;
}
BLYNK_WRITE(V12) // level hum
{
  int pinValue = param.asInt();
  hum3pin = pinValue;
}

BLYNK_WRITE(V14) // setup hum
{
  int pinValue = param.asInt();
  lastsethum3 = pinValue;
}
BLYNK_WRITE(V15) // hum down
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && min_hum3 > 0)
    {
      lastp = 0;
      min_hum3--;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }

  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      max_hum3--;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
BLYNK_WRITE(V17) // hum up
{
  int pinValue = param.asInt();
  if (lastsethum3 == 1)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 - min_hum3 > 1)
    {
      lastp = 0;
      min_hum3++;
      Blynk.virtualWrite(V16, min_hum3);
    }
  }

  if (lastsethum3 == 0)
  {
    if (pinValue != lastp && pinValue > 0 && max_hum3 < 100)
    {
      lastp = 0;
      max_hum3++;
      Blynk.virtualWrite(V18, max_hum3);
    }
  }
}
//---------------------HUM END-----------------------------
void tempcheck()
{
  if (temp5 <= min_temp5 && flag_temp5_on_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(3, LOW); //  вкл
      Blynk.virtualWrite(V27, 1023); //  вкл
      Blynk.virtualWrite(V28, 0); //  выкл
    } else {
      digitalWrite(3, HIGH); //  выкл
      Blynk.virtualWrite(V27, 0); //  выкл
      Blynk.virtualWrite(V28, 1023); //  вкл
    }
    flag_temp5_on_state = false;
    flag_temp5_off_state = true;
  }

  if (temp5 >= max_temp5 && flag_temp5_off_state)
  {
    if (temppin == 1 )
    {
      digitalWrite(3, HIGH); //  вкл
      Blynk.virtualWrite(V27, 0); //  вкл
      Blynk.virtualWrite(V28, 1023); //  выкл
    } else {
      digitalWrite(3, LOW); //  выкл
      Blynk.virtualWrite(V27, 1023); //  выкл
      Blynk.virtualWrite(V28, 0); //  выкл
    }
    flag_temp5_off_state = false;
    flag_temp5_on_state = true;
  }
}

void humcheck()
{
  if (hum3 <= min_hum3 && flag_fany_on_state)
  {
    if (hum3pin == 1 )
    {
      digitalWrite(13, LOW); //  вкл
      Blynk.virtualWrite(V10, 1023); //  вкл
      Blynk.virtualWrite(V11, 0); //  выкл
    } else {
      digitalWrite(13, HIGH); //  выкл
      Blynk.virtualWrite(V10, 0); //  выкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    }
    flag_fany_on_state = false;
    flag_fany_off_state = true;
  }


  if (hum3 >= max_hum3 && flag_fany_off_state)
  {
    if (hum3pin == 1 )
    {
      digitalWrite(13, HIGH); //  вкл
      Blynk.virtualWrite(V10, 0); //  вкл
      Blynk.virtualWrite(V11, 1023); //  выкл
    } else {
      digitalWrite(13, LOW); //  выкл
      Blynk.virtualWrite(V10, 1023); //  выкл
      Blynk.virtualWrite(V11, 0); //  выкл
    }
    flag_fany_off_state = false;
    flag_fany_on_state = true;
  }
}
//-----------------auto Fan-----------------
void fantempcheck()
{
  if (temp5 >= max_temp5 && flag_temp5_on_state) // 
  {
    if (temppin == 1 )
    {
      digitalWrite(2, LOW); //  вкл
      Blynk.virtualWrite(V42, 1023); //  вкл
      Blynk.virtualWrite(V43, 0); //  выкл
    } else {
      digitalWrite(2, HIGH); //  выкл
      Blynk.virtualWrite(V42, 0); //  выкл
      Blynk.virtualWrite(V43, 1023); //  вкл
    }
    flag_temp5_on_state = false;
    flag_temp5_off_state = true;
    terminal.print("autoFan On ");
    terminal.print(temp5);
  }

  if (temp5 <= max_temp5 && flag_temp5_off_state) // 
  {
    if (temppin == 1 )
    {
      digitalWrite(2, HIGH); //  вкл
      Blynk.virtualWrite(V42, 0); //  вкл
      Blynk.virtualWrite(V43, 1023); //  выкл
    } else {
      digitalWrite(2, LOW); //  выкл
      Blynk.virtualWrite(V42, 1023); //  выкл
      Blynk.virtualWrite(V43, 0); //  выкл
    }
    flag_temp5_off_state = false;
    flag_temp5_on_state = true;
    terminal.print("autoFan Off ");
    terminal.print(currentTime);
  }
  terminal.flush();
}
//----------------- end auto Fan-----------------
void sendSensor1()
{
  temp5 = sensor.readTemperature();
  hum3 = sensor.readHumidity();
  Blynk.virtualWrite(V3, hum3);
  Blynk.virtualWrite(V5, temp5);
}

void readEEPROM(int startAdr, int maxLength, char* dest)
{
  EEPROM.begin(256);
  delay(10);
  for (int i = 0; i < maxLength; i++)
  {
    dest[i] = char(EEPROM.read(startAdr + i));
  }
  EEPROM.end();
}
void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  Wire.begin(I2C_SDA, I2C_SCL);
  ESP.wdtDisable();
  ESP.wdtEnable(WDTO_8S);
  EEPROM.begin(256);
  min_hum3 = EEPROM.read(161);
  max_hum3 = EEPROM.read(162);
  hum3pin = EEPROM.read(163);
  min_temp5 = EEPROM.read(164);
  max_temp5 = EEPROM.read(165);
  temppin = EEPROM.read(166);

  pinMode(13, OUTPUT); // увлажнитель
  digitalWrite(13, LOW); // 
  pinMode(3, OUTPUT); // нагреватель
  digitalWrite(3, LOW); //
  pinMode(Light, OUTPUT);// свет
  digitalWrite(Light, HIGH);
  Blynk.virtualWrite(V32, HIGH);
  pinMode(Fan, OUTPUT);// вентилятор
  digitalWrite(Fan, LOW);
  Blynk.virtualWrite(V35, HIGH);
  pinMode(Pump, OUTPUT);//помпа воды
  digitalWrite(Pump, HIGH);
  Blynk.virtualWrite(V38, HIGH);
  pinMode(Aero, OUTPUT);//аэратор воды
  digitalWrite(Aero, HIGH);
  Blynk.virtualWrite(V41, HIGH);
      
  timer.setInterval(60000L, activetoday);  // check every 60s if ON / OFF trigger time has been reached
  timer.setInterval(1000L, clockDisplay);  // check every second if time has been obtained from the server
  timer.setInterval(457L, sendSensor1);
  timer.setInterval(435L, humcheck);
  timer.setInterval(428L, tempcheck);
  timer.setInterval(308L, fantempcheck);

  Blynk.virtualWrite(V16, min_hum3);
  Blynk.virtualWrite(V18, max_hum3);
  Blynk.virtualWrite(V24, max_temp5);
  Blynk.virtualWrite(V23, min_temp5);

  if (min_hum3 <= 30 ||  min_hum3 >= 99 || max_hum3 <= 30 ||  max_hum3 >= 99) {
    min_hum3 = 45;
    max_hum3 = 50;
  }
  if (min_temp5 <= 0 ||  min_temp5 >= 99 || max_temp5 <= 0 ||  max_temp5 >= 99) {
    min_temp5 = 20;
    max_temp5 = 25;
  }
  if (!sensor.begin())
  {
    Serial.println("Couldn't find sensor!");
    while (1);
  }
}

BLYNK_CONNECTED() {
  rtc.begin();
}
//----------------------------Timer------------------------------
void activetoday(){         // check if schedule should run today
  if(year() != 1970){
    Blynk.syncVirtual(V30);
    Blynk.syncVirtual(V33);
    Blynk.syncVirtual(V36);
    Blynk.syncVirtual(V39);// sync scheduler #
  }
}

void clockDisplay(){  // only needs to be done once after time sync
  if((year() != 1970) && (clockSync == false)){ 
    sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
    Serial.println(currentTime);
    terminal.println(currentTime);
    clockSync = true;
    terminal.flush();
  } 
}    

BLYNK_WRITE(V30) {   // Scheduler #1 Time Input widget  
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  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  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Light, OUTPUT);
      digitalWrite(Light, LOW);
      Blynk.virtualWrite(V31, 1023);  // turn on virtual LED
      Serial.println("Schedule 1 started");
      terminal.println("Schedule 1 started");
      terminal.println(currentTime);
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Light, OUTPUT);
      digitalWrite(Light, HIGH);
      Blynk.virtualWrite(V31, 1);   // turn OFF virtual LED
      Serial.println("Schedule 1 finished");
      terminal.println("Schedule 1 finished");
      terminal.println(currentTime);
    }
    terminal.flush();               
  }
}

/*BLYNK_WRITE(V33) {   // Scheduler #2 Time Input widget  
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  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  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Fan, OUTPUT);
      digitalWrite(Fan, LOW);
      Blynk.virtualWrite(V34, 1023);  // turn on virtual LED
      Serial.println("Schedule 2 started");
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Fan, OUTPUT);
      digitalWrite(Fan, HIGH);
      Blynk.virtualWrite(V34, 1);   // turn OFF virtual LED
      Serial.println("Schedule 2 finished");
    }               
  }
}
*/
BLYNK_WRITE(V36) {   // Scheduler #3 Time Input widget  
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  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  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Pump, OUTPUT);
      digitalWrite(Pump, LOW);
      Blynk.virtualWrite(V37, 1023);  // turn on virtual LED
      Serial.println("Schedule 3 started");
      terminal.println("Schedule 3 started");
      terminal.println(currentTime);
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Pump, OUTPUT);
      digitalWrite(Pump, HIGH);
      Blynk.virtualWrite(V37, 1);   // turn OFF virtual LED
      Serial.println("Schedule 3 finished");
      terminal.println("Schedule 3 finished");
      terminal.println(currentTime);
    }
    terminal.flush();               
  }
}

BLYNK_WRITE(V39) {   // Scheduler #4 Time Input widget  
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  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  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Aero, OUTPUT);
      digitalWrite(Aero, LOW);
      Blynk.virtualWrite(V40, 1023);  // turn on virtual LED
      Serial.println("Schedule 4 started");
      terminal.println("Schedule 4 started");
      terminal.println(currentTime);
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      pinMode(Aero, OUTPUT);
      digitalWrite(Aero, HIGH);
      Blynk.virtualWrite(V40, 1);   // turn OFF virtual LED
      Serial.println("Schedule 4 finished");
      terminal.println("Schedule 4 finished");
      terminal.println(currentTime);
    }               
  }
}

//-------------------------timer end--------------------
void loop() {
  if(Blynk.connected()){ 
    Blynk.run();        
  }                      
  timer.run();
  ESP.wdtFeed();
}

i cant see where the temp5 is declared as a variable? i never use EEPROM though so im just asking…

i declare all my temperatures variables as float variable so they can be fractions of whole numbers like 25.03 instead of 25

these are happening too fast.

you dont need to check things every half second.

30 seconds is much better… so: timer.setInterval(30L * 1000L, fantempcheck);


Hi Dave, the screen shows what I’m talking about. The actual temperature is 24.5 but the relay is working
To be properly understood

how do you know the actual temp is 24.5?


I see the actual temperature from the readings of my sensor. float is announced above at the beginning of the code. Or did I not understand the question correctly?

OK, it IS a float.

so you are asking why is terminal print of temp5 is 25.01 but the blynk vpin is 24.09?

No, I asked not about it. I want to understand why an error occurs in the void fantempcheck () and the relay does not turn off when the temperature is less than max_temp5. And this does not happen regularly