Program lags when connected to blynk but there is no lag or delay in buttons, relay, switches when it is not connected to blynk

#include <BH1750.h>
#include <Adafruit_HDC1000.h>
#include <U8g2lib.h>
#include <EEPROM.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <OneWire.h>


U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);

const int NextButton = 25;
const int BackButton = 24;  // Pin for the "Back" button

int lastBackButtonState = HIGH;  // Declare and initialize lastBackButtonState

// Define the sensor objects
Adafruit_HDC1000 hdc1080;
BH1750 lightMeter;

#define ph_Pin A0  //pH meter Analog output to Arduino Analog Input 0
#define TdsSensorPin A1
int WaterTemp_sensor = 22;
OneWire ds(WaterTemp_sensor);
const int MoistureLevelPin1 = A2;  // Analog pin for the water level sensor
const int MoistureLevelPin2 = A3;
const int MoistureLevelPin3 = A4;
const int MoistureLevelPin4 = A5;
const int MoistureLevelPin5 = A6;
const int MoistureLevelPin6 = A7;

int SoilMoist1;
int SoilMoist2;
int SoilMoist3;
int SoilMoist4;
int SoilMoist5;
int SoilMoist6;
float SoilMoistAverage;

String PumpStatus;
String ShadeStatus;
String FanStatus;
float WaterTemp;
float TDS;
float EC;
float temperature;
float humidity;
float PPFD;
float PH;

float calibration_value = 21.2;
unsigned long int avgValue;  //Store the average value of the sensor feedback
int buf[10], temp;

#define VREF 4.9           // analog reference voltage(Volt) of the ADC
#define SCOUNT 30          // sum of sample point
int analogBuffer[SCOUNT];  // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0, copyIndex = 0;
float averageVoltage = 0, tdsValue = 0;

#define BLYNK_TEMPLATE_ID           "TMPL6nbINoFLa"
#define BLYNK_TEMPLATE_NAME         "SmartField Co"
#define BLYNK_AUTH_TOKEN            "VLzoDUg8OgnDUuK6se_YmTFxkOiVh3mF"
#include <ESP8266_Lib.h>
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <BlynkSimpleShieldEsp8266.h>
char auth[] = "VLzoDUg8OgnDUuK6se_YmTFxkOiVh3mF";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Coline";
char pass[] = "12345678";
// Hardware Serial on Mega, Leonardo, Micro...
#define EspSerial Serial1
// Your ESP8266 baud rate:
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);
BlynkTimer timer;
unsigned long lastConnectionAttempt = 0;
const unsigned long connectionInterval = 900000; // Reconnect every 15 minutes
bool isEspConnected;
//display



static const unsigned char image_Layer_18_bits[] U8X8_PROGMEM = { 0x10, 0x10, 0x38, 0x7c, 0x7c, 0x78, 0x7f, 0xff, 0xf8, 0xe0, 0x80 };
static const unsigned char image_Layer_19_bits[] U8X8_PROGMEM = { 0x10, 0x10, 0x38, 0x7c, 0x7c, 0x78, 0x7f, 0xff, 0xf8, 0xe0, 0x80 };
static const unsigned char image_display_brightness_bits[] U8X8_PROGMEM = { 0x80, 0x00, 0x84, 0x10, 0x08, 0x08, 0xc0, 0x01, 0x31, 0x46, 0x12, 0x24, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x12, 0x24, 0x31, 0x46, 0xc0, 0x01, 0x08, 0x08, 0x84, 0x10, 0x80, 0x00, 0x00, 0x00 };
static const unsigned char image_weather_temperature_bits[] U8X8_PROGMEM = { 0x38, 0x00, 0x44, 0x40, 0xd4, 0xa0, 0x54, 0x40, 0xd4, 0x1c, 0x54, 0x06, 0xd4, 0x02, 0x54, 0x02, 0x54, 0x06, 0x92, 0x1c, 0x39, 0x01, 0x75, 0x01, 0x7d, 0x01, 0x39, 0x01, 0x82, 0x00, 0x7c, 0x00 };
static const unsigned char image_weather_wind_bits[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x11, 0x20, 0x22, 0x20, 0x22, 0x00, 0x22, 0x00, 0x11, 0xff, 0x4c, 0x00, 0x00, 0xb5, 0x41, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x80, 0x04, 0x00, 0x03 };
static const unsigned char image_weather_sun_bits[] U8X8_PROGMEM = { 0x80, 0x00, 0x84, 0x10, 0x08, 0x08, 0xc0, 0x01, 0x31, 0x46, 0x12, 0x24, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x12, 0x24, 0x31, 0x46, 0xc0, 0x01, 0x08, 0x08, 0x84, 0x10, 0x80, 0x00, 0x00, 0x00 };
static const unsigned char image_weather_humidity_bits[] U8X8_PROGMEM = { 0x20, 0x00, 0x20, 0x00, 0x30, 0x00, 0x70, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfc, 0x01, 0x7e, 0x03, 0xfe, 0x02, 0xff, 0x06, 0xff, 0x07, 0xfe, 0x03, 0xfe, 0x03, 0xfc, 0x01, 0xf0, 0x00 };
static const unsigned char image_earth_bits[] U8X8_PROGMEM = { 0xe0, 0x03, 0x78, 0x0e, 0xe4, 0x1f, 0x86, 0x27, 0xc2, 0x27, 0xe1, 0x53, 0xf9, 0x6f, 0xfb, 0x41, 0xfb, 0x41, 0xc7, 0x43, 0x86, 0x2f, 0x0e, 0x2f, 0x8c, 0x1f, 0xd8, 0x0f, 0xe0, 0x03, 0x00, 0x00 };
static const unsigned char image_Clock_bits[] U8X8_PROGMEM = { 0xc0, 0x0f, 0x00, 0xf0, 0x3f, 0x00, 0xf8, 0x7f, 0x00, 0x1c, 0xe0, 0x00, 0xbe, 0xf7, 0x01, 0xbe, 0xf7, 0x01, 0xbf, 0xf7, 0x03, 0x7f, 0xfb, 0x03, 0xff, 0xfc, 0x03, 0xff, 0xfc, 0x03, 0x7f, 0xf9, 0x03, 0xbf, 0xf2, 0x03, 0x3e, 0xf5, 0x01, 0xbe, 0xf2, 0x01, 0x1c, 0xe0, 0x00, 0xf8, 0x7f, 0x00, 0xf0, 0x3f, 0x00, 0xc0, 0x0f, 0x00 };
static const unsigned char image_Voltage_bits[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0xc0, 0x01, 0xe0, 0x00, 0xf0, 0x07, 0x80, 0x03, 0xc0, 0x01, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const unsigned char image_menu_settings_gear_bits[] U8X8_PROGMEM = { 0xc0, 0x03, 0x48, 0x12, 0x34, 0x2c, 0x02, 0x40, 0xc4, 0x23, 0x24, 0x24, 0x13, 0xc8, 0x11, 0x88, 0x11, 0x88, 0x13, 0xc8, 0x24, 0x24, 0xc4, 0x23, 0x02, 0x40, 0x34, 0x2c, 0x48, 0x12, 0xc0, 0x03 };
// images from https://lopaka.app/
bool loadingComplete = false;
int progress = 0;  // progress of the progressbar
char buffer[32];   // helper buffer to construct a string to be displayed

enum State {
  LIGHT_VALUE,
  AMB_TEMP,
  AMB_HUM,
  PH_LVL,
  EC_LVL,
  TDS_LVL,
  SOIL_MOIST,
  ACT_STAT
};

State currentState = LIGHT_VALUE;
int buttonState = HIGH;
int lastButtonState = HIGH;
int PumpSwitch = 26;
int FanSwitch = 27;
#define ShadeNetSwitch 28
#define LimitSwitch1 30
#define LimitSwitch2 29
int RelayFan1 = 31;
int RelayFan2 = 32;
int RelayPump = 35;
#define EN2 6
#define INA2 7
#define INB2 8
#define PWM2 9
#define EN4 42
#define INA4 43
#define INB4 44
#define PWM4 45


bool isMotorRunning = false;
bool isLimitSwitch1Clicked = false;
bool isLimitSwitch2Clicked = false;
int ShadeNetSwitch_State;
bool isPumpRunning = false;
bool isFanAutomated = true;
bool isFanRunning = false;
bool isPumpAutomated = true;
bool isNetAutomated = true;
int FanSwitch_Iot = 1;
int PumpSwitch_Iot = 1;
int ShadeNetSwitch_Iot = 1;
int FanSwitch_State;
int PumpSwitch_State;



void TCA9548A(uint8_t bus) {
  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
}

void connectToWiFi()
{
  // Configure Blynk with Auth Token
  Blynk.config(wifi, BLYNK_AUTH_TOKEN, "sgp1.blynk.cloud", 80);

  // Set up WiFi connection
  Blynk.connectWiFi(ssid, pass);
  Blynk.connect();
    // Check connection status
  if (Blynk.connected())
  {
    isEspConnected = true;
    Serial.println("Connected to Blynk server.");
  }
  else
  {
    isEspConnected = false;
    Serial.println("Connection to Blynk server failed.");
  }
}

void SensorTimer()
{
  Blynk.virtualWrite(V1, temperature);
  Blynk.virtualWrite(V2, humidity);
  Blynk.virtualWrite(V3, EC);
  Blynk.virtualWrite(V4, TDS);
  Blynk.virtualWrite(V5, PPFD);
  Blynk.virtualWrite(V6, PH);
  Blynk.virtualWrite(V7, SoilMoistAverage);
}


BLYNK_WRITE(V8)
{
  ShadeNetSwitch_Iot = param.asInt(); // Get the state of the Button widget (0 or 1)
}

BLYNK_WRITE(V9)
{
  PumpSwitch_Iot = param.asInt(); // Get the state of the Button widget (0 or 1) 
}

BLYNK_WRITE(V10)
{
  FanSwitch_Iot = param.asInt(); // Get the state of the Button widget (0 or 1)
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  u8g2.begin();
  TCA9548A(0);  // Selecting Bus 0
  lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2);
  TCA9548A(1);
  hdc1080.begin(0x40);       //initialization
  pinMode(NextButton, INPUT_PULLUP);
  pinMode(BackButton, INPUT_PULLUP);
  pinMode(ShadeNetSwitch, INPUT);
  pinMode(LimitSwitch1, INPUT_PULLUP);
  pinMode(LimitSwitch2, INPUT_PULLUP);
  pinMode(MoistureLevelPin1, INPUT);
  pinMode(MoistureLevelPin2, INPUT);
  pinMode(MoistureLevelPin3, INPUT);
  pinMode(MoistureLevelPin4, INPUT);
  pinMode(MoistureLevelPin5, INPUT);
  pinMode(MoistureLevelPin6, INPUT);
  pinMode(ph_Pin, INPUT);
  pinMode(PWM2, OUTPUT);
  pinMode(INA2, OUTPUT);
  pinMode(INB2, OUTPUT);
  pinMode(EN2, OUTPUT);
  pinMode(PWM4, OUTPUT);
  pinMode(INA4, OUTPUT);
  pinMode(INB4, OUTPUT);
  pinMode(EN4, OUTPUT);
  pinMode(FanSwitch, INPUT);  // Set RelayPin as an INPUT pin
  pinMode(PumpSwitch, INPUT);
  pinMode(RelayPump, OUTPUT);
  pinMode(RelayFan1, OUTPUT);
  pinMode(RelayFan2, OUTPUT);
  digitalWrite(RelayPump, HIGH);
  digitalWrite(RelayFan1, HIGH);
  digitalWrite(RelayFan2, HIGH);
  digitalWrite(EN2, HIGH);
  digitalWrite(EN4, HIGH);
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  // Connect to WiFi and Blynk
  connectToWiFi();
  // You can also specify the server:
  // Blynk.begin(BLYNK_AUTH_TOKEN, wifi, ssid, pass, "blynk.cloud", 80);
  timer.setInterval(1000L, SensorTimer);
}

float luxToPPFD(float lux) {
  return lux * 0.0185;
}

void ReadLight() {
  TCA9548A(0);  // Selecting Bus 0
  float lux = lightMeter.readLightLevel();
  PPFD = luxToPPFD(lux);  // Convert lux to PPFD
}

void ReadHDC1080() {
  TCA9548A(1);
  temperature = hdc1080.readTemperature();
  humidity = hdc1080.readHumidity();
}

void ReadPH() {
  for (int i = 0; i < 10; i++) {  //Get 10 sample value from the sensor for smooth the value
    buf[i] = analogRead(ph_Pin);
    delay(10);
  }
  for (int i = 0; i < 9; i++) {  //sort the analog from small to large
    for (int j = i + 1; j < 10; j++) {
      if (buf[i] > buf[j]) {
        temp = buf[i];
        buf[i] = buf[j];
        buf[j] = temp;
      }
    }
  }
  avgValue = 0;
  for (int i = 2; i < 8; i++) avgValue += buf[i];  //take the average value of 6 center sample

  float phValue = (float)avgValue * 5.0 / 1024 / 6;  //convert the analog into millivolt
  PH = -5.70 * phValue + calibration_value;          //convert the millivolt into pH value
}

float getTemp() {
  // Returns the temperature from one DS18S20 in DEG Celsius

  byte data[12];
  byte addr[8];

  if (!ds.search(addr)) {
    // No more sensors on chain, reset search
    ds.reset_search();
    return -1000;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return -1000;
  }

  if (addr[0] != 0x10 && addr[0] != 0x28) {
    Serial.print("Device is not recognized");
    return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);  // Start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);  // Read Scratchpad

  for (int i = 0; i < 9; i++) {  // We need 9 bytes
    data[i] = ds.read();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB);  // Using two's complement
  float TemperatureSum = tempRead / 16;

  return TemperatureSum;
}

void ReadWaterTemp() {
  WaterTemp = getTemp();  // Read temperature from first sensor
}

void ReadTDS() {
  ReadWaterTemp();
  
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //every 40 milliseconds,read the analog value from the ADC
  {
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);  //read the analog value and store into the buffer
    analogBufferIndex++;
    if (analogBufferIndex == SCOUNT)
      analogBufferIndex = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0;                                                                                                   // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficient = 1.0 + 0.02 * (WaterTemp - 25.0);                                                                                                                  //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatge = averageVoltage / compensationCoefficient;                                                                                                             //temperature compensation
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5;
    TDS = tdsValue/1.8;
    EC = TDS*2;
  }
}
int getMedianNum(int bArray[], int iFilterLen) {
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}

void ReadSoilMoisture() {
  // Read the water level from the analog pin
  int MoistureLevel1 = analogRead(MoistureLevelPin1);
  int MoistureLevel2 = analogRead(MoistureLevelPin2);
  int MoistureLevel3 = analogRead(MoistureLevelPin3);
  int MoistureLevel4 = analogRead(MoistureLevelPin4);
  int MoistureLevel5 = analogRead(MoistureLevelPin5);
  int MoistureLevel6 = analogRead(MoistureLevelPin6);

  // Map the analog reading to a range (adjust these values based on your sensor and requirements)
  SoilMoist1 = map(MoistureLevel1, 372, 892, 100, 0);
  SoilMoist2 = map(MoistureLevel2, 386, 911, 100, 0);
  SoilMoist3 = map(MoistureLevel3, 400, 819, 100, 0);
  SoilMoist4 = map(MoistureLevel4, 380, 885, 100, 0);
  SoilMoist5 = map(MoistureLevel5, 385, 908, 100, 0);
  SoilMoist6 = map(MoistureLevel6, 383, 892, 100, 0);

  SoilMoistAverage = ((SoilMoist1 + SoilMoist2 + SoilMoist3 + SoilMoist4 + SoilMoist5 + SoilMoist6) / 6);
}

void ShadeNetManual() {
  int LimitSwitch1_State = digitalRead(LimitSwitch1);
  int LimitSwitch2_State = digitalRead(LimitSwitch2);
  ShadeNetSwitch_State = digitalRead(ShadeNetSwitch);

  if (((ShadeNetSwitch_State == HIGH && ShadeNetSwitch_Iot == HIGH) || (ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == LOW) || (ShadeNetSwitch_State == HIGH && ShadeNetSwitch_Iot == LOW)) && !isMotorRunning && isNetAutomated) 
  {
    ShadeStatus = "ACTIVE";
    OpenShadeNet();
    isMotorRunning = true;
    isNetAutomated = false;
    Serial.println("Shade Net is Opening");
  }

  if (((ShadeNetSwitch_State == HIGH && ShadeNetSwitch_Iot == HIGH) || (ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == LOW) || (ShadeNetSwitch_State == HIGH && ShadeNetSwitch_Iot == LOW)) && isMotorRunning && !isLimitSwitch1Clicked && LimitSwitch1_State == LOW && !isNetAutomated) 
  {
    // Limit switch 1 is clicked
    // Stop the motors and set switch 1 flag
    stopMotors();
    isNetAutomated = false;
    isLimitSwitch1Clicked = true;
    Serial.println("Limit switch 1 clicked, Motor Stops");
  }

  if (isLimitSwitch1Clicked && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH && !isLimitSwitch2Clicked && !isNetAutomated) {
    // Soil moisture is less than or equal to 30 and switch 1 is clicked
    // Rotate motors counterclockwise and set switch 2 flag
    CloseShadeNet();
    isNetAutomated = false;
    isLimitSwitch2Clicked = true;
    Serial.println("Shade Net Closing");
  }

  if (isMotorRunning && isLimitSwitch2Clicked && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH && LimitSwitch2_State == LOW && !isNetAutomated) {
    // Limit switch 2 is clicked
    // Stop the motors
    ShadeStatus = "INACTIVE";
    stopMotors();
    isMotorRunning = false;
    isLimitSwitch1Clicked = false;
    isLimitSwitch2Clicked = false;
    isNetAutomated = true;
    Serial.println("Limit switch 2 clicked, Motors stopped");
  }
}

void ShadeNetAutomation()
{
  int LimitSwitch1_State = digitalRead(LimitSwitch1);
  int LimitSwitch2_State = digitalRead(LimitSwitch2);

  if (PPFD > 200 && !isMotorRunning && isNetAutomated && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH) {
    // Turn on the motors and rotate clockwise
    OpenShadeNet();
    isMotorRunning = true;
    isNetAutomated = true;
    Serial.println("Shade Net is Opening");
  }

  if (isMotorRunning && !isLimitSwitch1Clicked && LimitSwitch1_State == LOW && isNetAutomated && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH) {
    // Limit switch 1 is clicked
    // Stop the motors and set switch 1 flag
    stopMotors();
    isLimitSwitch1Clicked = true;
    isNetAutomated = true;
    Serial.println("Limit switch 1 clicked, Motor Stops");
  }

  if (isLimitSwitch1Clicked && PPFD <= 200 && !isLimitSwitch2Clicked && isNetAutomated && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH) {
    // Soil moisture is less than or equal to 30 and switch 1 is clicked
    // Rotate motors counterclockwise and set switch 2 flag
    CloseShadeNet();
    isLimitSwitch2Clicked = true;
    isNetAutomated = true;
    Serial.println("Shade Net Closing");
  }

  if (isMotorRunning && isLimitSwitch2Clicked && LimitSwitch2_State == LOW && isNetAutomated && ShadeNetSwitch_State == LOW && ShadeNetSwitch_Iot == HIGH) {
    // Limit switch 2 is clicked
    // Stop the motors
    stopMotors();
    isNetAutomated = true;
    isMotorRunning = false;
    isLimitSwitch1Clicked = false;
    isLimitSwitch2Clicked = false;
    Serial.println("Limit switch 2 clicked, Motors stopped");
  }
}

void PumpManual() {
  PumpSwitch_State = digitalRead(PumpSwitch);
  if (!isPumpRunning && ((PumpSwitch_State == HIGH && PumpSwitch_Iot == HIGH) || (PumpSwitch_State == LOW && PumpSwitch_Iot == LOW) || (PumpSwitch_State == HIGH && PumpSwitch_Iot == LOW)) && !isPumpRunning && isPumpAutomated) {
    PumpStatus = "ACTIVE";
    digitalWrite(RelayPump, LOW);
    isPumpRunning = true;
    isPumpAutomated = false;
  }

  if (isPumpRunning && PumpSwitch_State == LOW && PumpSwitch_Iot == HIGH && isPumpRunning && !isPumpAutomated) {
    PumpStatus = "INACTIVE";
    digitalWrite(RelayPump, HIGH);
    isPumpRunning = false;
    isPumpAutomated = true;
  }
}

void PumpAutomation()
{
  PumpSwitch_State = digitalRead(PumpSwitch);

  if ((SoilMoist1 < 50 || SoilMoist2 < 50 || SoilMoist3 < 50 || SoilMoist4 < 50 || SoilMoist5 < 50 || SoilMoist6 < 50) && !isPumpRunning && isPumpAutomated && PumpSwitch_State == LOW && PumpSwitch_Iot == HIGH)
  {
    digitalWrite(RelayPump, LOW);
    isPumpRunning = true;
    PumpStatus = "ACTIVE";
  }
  

  if (SoilMoist1 > 65 && SoilMoist2 > 65 && SoilMoist3 > 65 && SoilMoist4 > 65 && SoilMoist5 > 65 && SoilMoist6 > 65 && isPumpRunning && isPumpAutomated && PumpSwitch_State == LOW && PumpSwitch_Iot == HIGH)
  {
    digitalWrite(RelayPump, HIGH);
    isPumpRunning = false;
    PumpStatus = "INACTIVE";
  }
}

void FanManual() {
  FanSwitch_State = digitalRead(FanSwitch);

  // Check if the fan is not running and the switch is pressed
  if (!isFanRunning && ((FanSwitch_State == HIGH && FanSwitch_Iot == HIGH) || (FanSwitch_State == LOW && FanSwitch_Iot == LOW || (FanSwitch_State == HIGH && FanSwitch_Iot == LOW)))) {
    FanStatus = "ACTIVE";
    digitalWrite(RelayFan1, LOW);
    digitalWrite(RelayFan2, LOW);
    isFanRunning = true;
    isFanAutomated = false; // Ensure automated mode is disabled
  }

  // Check if the fan is running and the switch is released
  if (isFanRunning && FanSwitch_State == LOW && FanSwitch_Iot == HIGH && !isFanAutomated) {
    FanStatus = "INACTIVE";
    digitalWrite(RelayFan1, HIGH);
    digitalWrite(RelayFan2, HIGH);
    isFanRunning = false;
    isFanAutomated = true; // Re-enable automated mode after manual operation
  }
}

void FanAutomation() {
  FanSwitch_State = digitalRead(FanSwitch);
  // Add delay to avoid interference between manual and automated control
  delay(100); // Adjust the delay time as needed
  
  if (temperature > 30 && !isFanRunning && isFanAutomated && FanSwitch_State == LOW && FanSwitch_Iot == HIGH) 
  {
    digitalWrite(RelayFan1, LOW);
    digitalWrite(RelayFan2, LOW);
    isFanRunning = true;
    FanStatus = "ACTIVE";
  }

  if (temperature <= 25 && isFanRunning && isFanAutomated && FanSwitch_State == LOW && FanSwitch_Iot == HIGH) 
  {
    digitalWrite(RelayFan1, HIGH);
    digitalWrite(RelayFan2, HIGH);
    isFanRunning = false;
    FanStatus = "INACTIVE";
  }
}

void loadingScreen() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.drawFrame(12, 21, 104, 20);
  u8g2.drawBox(14, 23, progress, 16);
  u8g2.setFont(u8g2_font_helvB08_tr);
  sprintf(buffer, "Progress: %d%%", progress);
  u8g2.drawStr(33, 53, buffer);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(5, 7, " SYSTEM  INITIALIZATION ");
  u8g2.drawLine(0, 9, 127, 9);
  u8g2.sendBuffer();
  delay(150);
  progress += 5;             // Increment progress by 5
  if (progress >= 100) {     // If progress reaches 100 or more
    progress = 0;            // Reset progress to 0
    loadingComplete = true;  // Set loadingComplete to true
  }
}


void displayLightValue() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(1, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(7, 16, "L I G H T  I N T E N S I T Y");
  u8g2.drawFrame(4, 5, 105, 15);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(20, 49);
  u8g2.print(PPFD);
  u8g2.drawLine(7, 37, 17, 27);
  u8g2.drawLine(17, 27, 108, 27);
  u8g2.drawLine(109, 27, 118, 36);
  u8g2.drawLine(7, 37, 7, 46);
  u8g2.drawLine(7, 47, 16, 56);
  u8g2.drawLine(17, 56, 109, 56);
  u8g2.drawLine(118, 36, 118, 47);
  u8g2.drawLine(118, 48, 110, 56);
  u8g2.drawXBMP(111, 5, 15, 16, image_display_brightness_bits);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(83, 46, "P P F D");
  u8g2.sendBuffer();
}

void displayAmbTemp() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(0, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(8, 23, "T E M P E R A T U R E");
  u8g2.drawFrame(5, 3, 93, 23);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(20, 51);
  u8g2.print(temperature);
  u8g2.print(" °C");
  u8g2.drawLine(7, 38, 16, 29);
  u8g2.drawLine(17, 29, 109, 29);
  u8g2.drawLine(110, 29, 118, 37);
  u8g2.drawLine(7, 38, 7, 47);
  u8g2.drawLine(7, 48, 16, 57);
  u8g2.drawLine(17, 57, 109, 57);
  u8g2.drawLine(118, 37, 118, 48);
  u8g2.drawLine(118, 49, 110, 57);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(23, 13, " A M B I E N T");
  u8g2.drawXBMP(104, 7, 16, 16, image_weather_temperature_bits);
  u8g2.sendBuffer();
}

void displayAmbHum() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(0, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(36, 23, "H U M I D I T Y");
  u8g2.drawFrame(31, 3, 65, 22);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(21, 50);
  u8g2.print(humidity);
  u8g2.print(" %");
  u8g2.drawLine(7, 37, 16, 28);
  u8g2.drawLine(17, 28, 109, 28);
  u8g2.drawLine(110, 28, 118, 36);
  u8g2.drawLine(7, 37, 7, 46);
  u8g2.drawLine(7, 47, 16, 56);
  u8g2.drawLine(17, 56, 109, 56);
  u8g2.drawLine(118, 36, 118, 47);
  u8g2.drawLine(118, 48, 110, 56);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(32, 13, " R E L A T I V E");
  u8g2.drawXBMP(101, 5, 15, 16, image_weather_wind_bits);
  u8g2.drawXBMP(11, 7, 15, 16, image_weather_sun_bits);
  u8g2.sendBuffer();
}

void displayPhLvl() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(0, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(33, 16, "P H  L E V E L");
  u8g2.drawFrame(25, 5, 70, 15);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(22, 49);
  u8g2.print(PH);
  u8g2.print("pH");
  u8g2.drawXBMP(9, 4, 11, 16, image_weather_humidity_bits);
  u8g2.drawXBMP(101, 4, 18, 18, image_Clock_bits);
  u8g2.drawLine(7, 37, 17, 27);
  u8g2.drawLine(17, 27, 108, 27);
  u8g2.drawLine(109, 27, 118, 36);
  u8g2.drawLine(7, 37, 7, 46);
  u8g2.drawLine(7, 47, 16, 56);
  u8g2.drawLine(17, 56, 109, 56);
  u8g2.drawLine(118, 36, 118, 47);
  u8g2.drawLine(118, 48, 110, 56);
  u8g2.sendBuffer();
}

void displayEcLvl() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(1, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(37, 16, "E C   L E V E L");
  u8g2.drawFrame(30, 5, 70, 15);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(16, 49);
  u8g2.print(EC);
  u8g2.drawXBMP(11, 5, 11, 16, image_weather_humidity_bits);
  u8g2.drawLine(7, 37, 17, 27);
  u8g2.drawLine(17, 27, 108, 27);
  u8g2.drawLine(109, 27, 118, 36);
  u8g2.drawLine(7, 37, 7, 46);
  u8g2.drawLine(7, 47, 16, 56);
  u8g2.drawLine(17, 56, 109, 56);
  u8g2.drawLine(118, 36, 118, 47);
  u8g2.drawLine(118, 48, 110, 56);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(76, 46, " u S/c m");
  u8g2.drawXBMP(103, 5, 16, 16, image_Voltage_bits);
  u8g2.sendBuffer();
}

void displayTdsLvl() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(1, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(33, 16, "T D S   L E V E L");
  u8g2.drawFrame(30, 5, 71, 15);
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.setCursor(23, 49);
  u8g2.print(TDS);
  u8g2.drawXBMP(11, 5, 11, 16, image_weather_humidity_bits);
  u8g2.drawLine(7, 37, 17, 27);
  u8g2.drawLine(17, 27, 108, 27);
  u8g2.drawLine(109, 27, 118, 36);
  u8g2.drawLine(7, 37, 7, 46);
  u8g2.drawLine(7, 47, 16, 56);
  u8g2.drawLine(17, 56, 109, 56);
  u8g2.drawLine(118, 36, 118, 47);
  u8g2.drawLine(118, 48, 110, 56);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(85, 45, " p p m");
  u8g2.drawXBMP(103, 5, 16, 16, image_Voltage_bits);
  u8g2.sendBuffer();
}

void displaySoilMoist() {
  u8g2.clearBuffer();
  u8g2.setBitmapMode(1);
  u8g2.setFontMode(1);
  u8g2.drawFrame(1, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(5, 14, "S O I L  M O I S T U R E");
  u8g2.drawLine(4, 15, 94, 15);
  u8g2.drawXBMP(98, 2, 11, 16, image_weather_humidity_bits);
  u8g2.drawXBMP(110, 3, 15, 16, image_earth_bits);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(6, 32, "S M 1");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(6, 45, "S M 2");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(6, 57, "S M 3");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(66, 32, "S M 4");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(66, 45, "S M 5");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(66, 57, "S M 6");
  u8g2.drawLine(5, 21, 124, 21);
  u8g2.drawLine(4, 21, 4, 59);
  u8g2.drawLine(4, 60, 123, 60);
  u8g2.drawLine(30, 21, 30, 59);
  u8g2.drawLine(91, 21, 91, 59);
  u8g2.drawLine(63, 22, 63, 59);
  u8g2.drawLine(124, 22, 124, 60);
  u8g2.drawLine(5, 34, 123, 34);
  u8g2.drawLine(5, 47, 124, 47);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.setCursor(34, 32); //sm1 -1ST -
  u8g2.print(SoilMoist1); //A2 - OK
  u8g2.print(" %");
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.setCursor(34, 57); //sm3 -5TH - 3RD 
  u8g2.print(SoilMoist4); //A3 -> A5
  u8g2.print(" %");
  u8g2.setCursor(95, 32); //SM4 - 2ND - 4TH 
  u8g2.print(SoilMoist6); //A4 -> A7
  u8g2.print(" %");
  u8g2.setCursor(95, 57); // SM6 -3RD - 6TH
  u8g2.print(SoilMoist5); //A5 -> A6
  u8g2.print(" %");
  u8g2.setCursor(34, 44); // SM2 -6TH -2ND
  u8g2.print(SoilMoist3); //A6 -> A4
  u8g2.print(" %");
  u8g2.setCursor(95, 44); // SM5 -4TH -5TH
  u8g2.print(SoilMoist2); //A7 ->  A3
  u8g2.print(" %");
  u8g2.sendBuffer();
}

void displayActuatorStatus() {
  u8g2.clearBuffer();
  u8g2.setFontMode(1);
  u8g2.setBitmapMode(1);
  u8g2.drawFrame(0, 0, 127, 64);
  u8g2.setFont(u8g2_font_haxrcorp4089_tr);
  u8g2.drawStr(36, 16, "");
  u8g2.setFont(u8g2_font_t0_13_tr);
  u8g2.drawStr(20, 15, "ACTUATOR STATUS");
  u8g2.drawXBMP(3, 2, 16, 16, image_menu_settings_gear_bits);
  u8g2.drawFrame(4, 21, 120, 40);
  u8g2.drawLine(21, 17, 122, 17);
  u8g2.drawLine(5, 34, 122, 34);
  u8g2.drawLine(4, 47, 122, 47);
  u8g2.drawLine(34, 23, 34, 59);
  u8g2.setFont(u8g2_font_t0_11_tr);
  u8g2.drawStr(10, 58, "NET");
  u8g2.drawStr(8, 45, "PUMP");
  u8g2.drawStr(7, 32, "FANS");
  u8g2.setCursor(54, 58);
  u8g2.print(ShadeStatus);
  u8g2.setCursor(54, 45);
  u8g2.print(PumpStatus);
  u8g2.setCursor(54, 32);
  u8g2.print(FanStatus);
  u8g2.sendBuffer();
}

void ReadSensors() 
{
  ReadLight();
  ReadHDC1080();
  ReadPH();
  ReadTDS();
  ReadSoilMoisture();
}

void Automation()
{
  FanAutomation();
  PumpAutomation();
  ShadeNetAutomation();
}

void Manual()
{
  PumpManual();
  FanManual();
  ShadeNetManual();
}

void updateState() {
  currentState = static_cast<State>((currentState + 1) % 8);  //CYCLE THROUGH 0-7
}

void backState() {
  currentState = static_cast<State>((currentState - 1 + 8) % 8);  // Ensure non-negative result
}

void Display() {
  int nextButtonState = digitalRead(NextButton);
  int backButtonState = digitalRead(BackButton);

  if (nextButtonState != lastButtonState || backButtonState != lastBackButtonState) {
    delay(20);  // Debounce delay
  }

  if (nextButtonState == LOW && lastButtonState == HIGH) {
    updateState();
  }

  if (backButtonState == LOW && lastBackButtonState == HIGH) {
    backState();
  }

  lastButtonState = nextButtonState;
  lastBackButtonState = backButtonState;

  switch (currentState) {
    case LIGHT_VALUE:
      displayLightValue();
      break;
    case AMB_TEMP:
      displayAmbTemp();
      break;
    case AMB_HUM:
      displayAmbHum();
      break;
    case PH_LVL:
      displayPhLvl();
      break;
    case EC_LVL:
      displayEcLvl();
      break;
    case TDS_LVL:
      displayTdsLvl();
      break;
    case SOIL_MOIST:
      displaySoilMoist();
      break;
    case ACT_STAT:
      displayActuatorStatus();
      break;
  }
}

void loop()
{
  if (!loadingComplete)
  {
    loadingScreen();
  }
  if (loadingComplete)
  {
    if (isEspConnected)
    {
    
      Display();
      ReadSensors();
      Automation();
      Manual();
      timer.run();
      Blynk.run();
    }
    if (!isEspConnected)
    {
      Display();
      ReadSensors();
      Automation();
      Manual();
      if (millis() - lastConnectionAttempt >= connectionInterval)
      {
       connectToWiFi();
       lastConnectionAttempt = millis();
      }
    }
  }
}

void OpenShadeNet() {

  digitalWrite(INA4, HIGH);
  digitalWrite(INB4, LOW);
  digitalWrite(EN4, HIGH);

  digitalWrite(INA2, LOW);
  digitalWrite(INB2, HIGH);
  digitalWrite(EN2, HIGH);

  analogWrite(PWM2, 155); 
  analogWrite(PWM4, 80);
}

void CloseShadeNet() {

  digitalWrite(INA4, LOW);
  digitalWrite(INB4, HIGH);
  digitalWrite(EN4, HIGH);

  digitalWrite(INA2, HIGH);
  digitalWrite(INB2, LOW);
  digitalWrite(EN2, HIGH);

  analogWrite(PWM2, 65);
  analogWrite(PWM4, 200);
}

void stopMotors() {

  digitalWrite(INA2, LOW);
  digitalWrite(INB2, LOW);
  digitalWrite(EN2, LOW);
  digitalWrite(INA4, LOW);
  digitalWrite(INB4, LOW);
  digitalWrite(EN4, LOW);
}

You should read this…

Pete.

You should also read this… :wink: