No disconnects when BLYNK_DEBUG is enabled

Hi,

I have some while loops that cause disconnects (I know while loops are not recommended). I tried to debug using BLYNK_DEBUG, but I was surprised that these disconnects didn’t happen. So did lots of tests and i can confirm when BLYNK_DEBUG is enabled the same functions/loops run without causing any disconnects at all.
Has anyone noticed this before? if yes, any idea what the reason is? Knowing the reason might help me to resolve the disconnects issue I am having.

Please post your code

Hi vhymanskyy, here is my code, please note I removed a big part of the code as it exceeded the max number of characters:
The disconnects happen in AutoTopOff and changeWater function when the debug is disable. They work fine when debug is enabled.

#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG        // Optional, this enables more detailed prints

#include<stdlib.h>
#include <SPI.h> //for Ethernet
#include <Ethernet.h> //for Ethernet
#include <BlynkSimpleEthernet.h> //for Ethernet
#include <SimpleTimer.h>//for Blynk
#include <OneWire.h> //for temp sensor
#include <DallasTemperature.h> //for temp sensor
SimpleTimer timer; //simple timer for Blynk
SimpleTimer timer1; //simple timer for Blynk
#define ONE_WIRE_BUS 24 //pin 8 is for temp sensor
#define BLYNK_MAX_SENDBYTES 1200
OneWire oneWire(ONE_WIRE_BUS); //for temp sensor
DallasTemperature sensors(&oneWire); //for temp sensor
const int floodSensorMin = 0;     // flood sensor minimum
const int floodSensorMax = 1024;  // flood sensor maximum

//STARTwater flow sensor-------------------------------------------

// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 26
//#define TONE_PIN 6 // buzzer output is pin 6
#define PIN_UPTIME V6
// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);

  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }

  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
}
void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}
//END water flow sensor--------------------------------------------------------------

float tempC; //temperature value from sensor
float maxTemp = 0; //max value for temp, gets reset when the report is generated
float minTemp = 0; //min value for temp, gets reset when the report is generated
float averageTemp; //average value for temp, gets reset when the report is generated
float tempStability; //stability value for temp, gets reset when the report is generated
int tempNotificationSent = 0; // temp alar notification flag 1=sent 0=not sent gets reset when temp is back to desired range
int selectedwateramount = 0; //for wc
int wcinp = 0; // water change in process
int waterChangeAmount = 0; //water change amount that goes to the wc function
int skimmer = 44;
int returnPump = 45;
int reactors = 46;
int ATO = 41;
int wcDrainPump = 40;
int wcFillPump = 49;
int heater = 32;
int chiller = 33;
int powerHead = 36;
int feeder = 28;
int wcFloatSwitchpin = 43;
int wcSwFloatSwitchpin = 31;
int wcFloatSwitchstatus;
int feshWaterFloatSwitchStatus;
int feshWaterFloatSwitchpin = 37;
int atoFloatSwitchStatusH;
int atoFloatSwitchStatusHpin = 38;
int atoFloatSwitchStatusL;
int atoFloatSwitchStatusLpin = 39;
int cancleWC = 0; //flag for cancelling water
int tonePin = 27;
int previousskimmerstate;
int previousreturnPumpstate;
int previousreactorsstate;
int previouswcFillPumpstate;
int previouswcDrainPumpstate;
int previousPowerHeadstate;
int previousATOstate;
int previousHeaterstate;
int previousChillerstate;
int previousFeederstate;
int secondsSinceATOPumpOn;
int maxTimeForContATORun = 15;
int previousatoFloatSwitchStatusLState;
int previousatoFloatSwitchStatusHState;
int previouswcFloatSwitchAtatusState;
int previousfeshWaterFloatSwitchStatusState;
int alarmsflag = 1;
int skimmerSwitchedOn = 0;
int feedingCompleted;
int previousPowerHeadstateForFeeding;

//---configuration-------------------
int absMinTemp = 24; // min temp for alarm
int absMaxTemp = 26;// max temp for alarm
float heaterStartTemp = 24.7; // temp to start heater
float heaterStopTemp = 24.9; // temp to stop heater
float chillerStartTemp = 25.3; //temp to start chiller
float chillerStopTemp = 25.1; //temp to stop chiller
int timeBetweenWcMsgs = 2000; //delay for wc status messages
int wcPumpfailureCheckTime = 10000; //stop draining water after this time if no flow has been detected
//---configuration-------------------


unsigned long pumpsOnTime = 0; //time of switching on pumps, used for determining when to switch on skimmer
unsigned long reportRunTimeLast; //capturing millis of when report last ran
unsigned long feederStartTime; //feeder time to determine when to switch on powerheads
const long skimmerDelay = 20 * 1000; //seconds to wait before swithcing skimmer
const long feedingPowerHeadsOff = 20 * 1000; //seconds to wait before swithcing skimmer
float liters = 0; //water amount drained
String enteredstring; //used to capture water amount form terminal string
String wcamount;
String wccommandString; //wc terminal string
long previousMillis = 0; //for temp sensor to read every n second
char auth[] = "xxxxxxxxxxxxxxxxx";//Blynk auth code
char ph_data[20];
byte ph_string_received = 0;
byte ph_received_from_sensor = 0;
String inputstring = "";                              //a string to hold incoming data from the PC
String sensorstring = "";                             //a string to hold the data from the Atlas Scientific product
boolean input_string_complete = false;                //have we received all the data from the PC
boolean sensor_string_complete = false;               //have we received all the data from the Atlas Scientific product
float pH;   //used to hold a floating point number that is the pH
float maxpH = 0; // to capture max pH
float minpH = 0; // to capture min pH
float averagepH; // to capture average pH
float pHStability;
int pHNotificationSent = 0; // flag to see if notificaton has been sent


WidgetTerminal terminal(V5); //terminal virtual pin
WidgetLED returnpumpled(V21);
WidgetLED reactorpumpled(V22);
WidgetLED skimmerpumpled(V20);
WidgetLED powerHeadled(V29);
WidgetLED addwaterpumpled(V23);
WidgetLED drainwaterpumpled(V24);
WidgetLED atopumpled(V25);
WidgetLED FloatSwitchStatusLled(V26);
WidgetLED FloatSwitchStatusHled(V27);
WidgetLED wcFloatSwitchled(V28);
WidgetLED feshWaterFloatSwitchled(V30);
WidgetLED wcSwFloatSwitchled(V31);
WidgetLED feederled(V32);

//++++++++++++++++++++++++++++++++++++++++++++++++++START SETUP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void setup()
{

  Serial.begin(9600);
  Serial3.begin(9600); //PH serial
  Blynk.begin(auth);
  pinMode(skimmer, OUTPUT);
  pinMode(returnPump, OUTPUT);
  pinMode(reactors, OUTPUT);
  pinMode(wcDrainPump, OUTPUT);
  pinMode(wcFillPump, OUTPUT);
  pinMode(ATO, OUTPUT);
  pinMode(powerHead, OUTPUT);
  pinMode(heater, OUTPUT);
  pinMode(chiller, OUTPUT);
  pinMode(wcFloatSwitchpin, INPUT);
  pinMode(feshWaterFloatSwitchpin, INPUT);
  pinMode(atoFloatSwitchStatusHpin, INPUT);
  pinMode(atoFloatSwitchStatusLpin, INPUT);
  pinMode(wcSwFloatSwitchpin, INPUT);
  pinMode(feeder, OUTPUT);

  digitalWrite(wcDrainPump, HIGH); //reversed
  digitalWrite(wcFillPump, HIGH);//reversed
  digitalWrite(ATO, HIGH);//reversed
  digitalWrite(heater, HIGH);//reversed
  digitalWrite(chiller, HIGH);//reversed
  digitalWrite(powerHead, LOW);//reversed
  digitalWrite(skimmer, HIGH);//reversed
  digitalWrite(feeder, HIGH);//reversed
  pumpsOn();
  //Blynk.virtualWrite(6, runTime);

  inputstring.reserve(10);                          //PH - set aside some bytes for receiving data from the PC
  sensorstring.reserve(30);                         //PH - set aside some bytes for receiving data from Atlas Scientific product
  sensors.begin();//Start Temperature sensor


  pinMode(FLOWSENSORPIN, INPUT);
  digitalWrite(FLOWSENSORPIN, HIGH);
  lastflowpinstate = digitalRead(FLOWSENSORPIN);
  useInterrupt(true);

  //--------------Functions timers-------------------------
  timer.setInterval(5100L, sendTempToGraphBlynk);
  timer.setInterval(7500L, sendPHToGraphBlynk);
  timer.setInterval(1900L, updatePinState);
  timer.setInterval(30800L, temperatureConroller);
  timer.setInterval(5200L, temperatureConrollerStatusUpdate);
  timer.setInterval(10000L, pHtempCompensation);
  timer.setInterval(6300L, tempAlarm);
  timer.setInterval(4300L, pHAlarm);
  timer.setInterval(86400000L, stabilityReport);
  timer.setInterval(60600L, AutoTopOff);
  timer1.setInterval(2700L, floodDetector);
  timer1.setInterval(5250L, floodPrevention);
  timer1.setInterval(3200L, updateFloatSwitchesState);
  timer1.setInterval(3600000L, switchOnAlarms);
  timer1.setInterval(1600L, skimmerOn);
  timer1.setInterval(1400L, powerheadsOnAfterFeeding);
  //--------------Functions timers-------------------------
}

//++++++++++++++++++++++++++++++++++++++++++++++++++END SETUP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void serialEvent3() {                                 //if the hardware serial port_3 receives a PH reading
  sensorstring = Serial3.readStringUntil(13);         //read the string until we see a <CR>
  sensor_string_complete = true;                      //set the flag used to tell if we have received a completed string from the PH sensor
}

//++++++++++++++++++++++++++++++++++++++++++++++++++START VOID LOOP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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

//++++++++++++++++++++++++++++++++++++++++++++++++++END VOID LOOP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@functions@@@@@@@@@


//-------------START send temp Blynk------------//
void sendTempToGraphBlynk()
{
  GetTemperature();
  Serial.println(tempC);
  Blynk.virtualWrite(2, tempC);
}
//-------------END send temp Blynk graph------------//


//-------------START send pH on Blynk graph------------//
void sendPHToGraphBlynk()
{
  GetPH();
  Serial.println(pH);
  Blynk.virtualWrite(3, pH);
}
//-------------END send pH on Blynk  graph------------//


//-------------Start Get Temperature Function------------//
void GetTemperature()
{
  Blynk.run(); // run Blynk process
  sensors.requestTemperatures(); // Send the command to get temperatures
  tempC =  sensors.getTempCByIndex(0);
  if (maxTemp == 0 && minTemp == 0 )
  {
    maxTemp = tempC;
    minTemp = tempC;
  }
  if (tempC < minTemp)
  {
    minTemp = tempC;
  }
  if (tempC > maxTemp)
  {
    maxTemp = tempC;
  }

}
//-------------End Get Temperature Function------------//


//----------START---------Receive command from Blynk terminal and excute accordingly----------------------------------
BLYNK_WRITE(V5)
{
  enteredstring = param.asStr();
  wcamount = enteredstring.substring(13);
  wccommandString = enteredstring.substring(0, 12);
  waterChangeAmount = wcamount.toInt();
  if (String("water change") == wccommandString) {
    changeWater(waterChangeAmount);
  }
  else if (String("hi") == param.asStr())
  {
    terminal.print("Hi Haidar enter a command please");
  }

  else if (String("help") == param.asStr())
  {
    terminal.println("You can enter the following commands:");
    terminal.println("- water change #");
    terminal.println("- cancle wc");
    terminal.println("- reset wc status");
    terminal.println("- pumps off");
    terminal.println("- pumps on");
    terminal.println("- all pumps off");
    terminal.println("- all pumps on");
    terminal.println("- powerheads on");
    terminal.println("- powerheads off");
    terminal.println("- alarms off");
    terminal.println("- alarms on");
    terminal.println("- feeding");
    terminal.println("- report");
    terminal.println("- clear cal");
    terminal.println("- reset ph");
    terminal.println("- cal ph 7");
    terminal.println("- cal ph 4");
    terminal.println("- cal ph 10");
    terminal.println("- cont ph reading on");
    terminal.println("- cont ph reading off");

  }
  else if (String("pumps off") == param.asStr())
  {
    pumpsOff();
  }

  else if (String("all pumps off") == param.asStr())
  {
    pumpsOff();
    powerheadsOff();
  }

  else if (String("cancle wc") == param.asStr())
  {
    cancleWC = 1;
  }
  else if (String("alarms off") == param.asStr())
  {
    switchOffAlarms();

  }
  else if (String("feeding") == param.asStr())
  {
    feeding();

  }
  else if (String("alarms on") == param.asStr())
  {
    switchOnAlarms();

  }
  else if (String("reset wc status") == param.asStr())
  {
    wcinp = 0;
    terminal.println("Water change status has been reset");
  }
  else if (String("report") == param.asStr())
  {
    stabilityReport();
  }
  else if (String("pumps on") == param.asStr())
  {
    pumpsOn();
  }

  else if (String("all pumps on") == param.asStr())
  {
    pumpsOn();
    powerheadsOn();
  }

  else if (String("powerheads on") == param.asStr())
  {
    powerheadsOn();
  }

  else if (String("powerheads off") == param.asStr())
  {
    powerheadsOff();
  }

  else if (String("ph temp") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("t,25\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("cal ph 7") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("Cal,mid,7.00\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("cal ph 4") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("Cal,low,4.00\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("cal ph 10") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("Cal,high,10.00\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("clear cal") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("Cal,clear\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("reset ph") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("Factory\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("cont ph reading on") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("c,1\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }

  else if (String("cont ph reading off") == param.asStr())
  {
    for (int a = 0; a < 2; a++)
    {
      Serial3.print("c,0\r");
      delay(500);
    }
    if (Serial3.find("OK")) {
      terminal.println("RECEIVED: OK");
    }
  }
  else {

    terminal.write(param.getBuffer(), param.getLength());
    terminal.print(" is not a valid command, enter help to see available options");
    terminal.println();
  }
  terminal.flush();
}
//----------END---------Receive command from Blynk terminal and excute accordingly----------------------------------

//------START Water change function---------------------
void changeWater (int selectedwateramount)

{
  if (digitalRead(wcSwFloatSwitchpin) == HIGH)
  {
    terminal.println(selectedwateramount);
    cancleWC = 0;
    pulses = 0; //added code witout testing
    liters = 0; //added code witout testing

    if (selectedwateramount > 0) {
      terminal.print("System will change ") ;
      terminal.print(waterChangeAmount);
      terminal.println(" liters") ;

      tone(tonePin, 300, 300);
      pumpsOff(); //switch of all pumps except powerheads
      digitalWrite(ATO, HIGH);//reversed // switch of ATO in case was running
      wcinp = 1;

      terminal.println("Water change started...") ;
      terminal.flush();
      addwaterpumpled.off();
      drainwaterpumpled.on();

      unsigned long drainingwaterTerminalPrint = millis();
      unsigned long drainingWaterStartTime = millis();
      unsigned long previousDrainingWaterPointInTime = millis();
      float previousLiters = liters;
      while (liters < selectedwateramount) {

        if (millis() - previousDrainingWaterPointInTime >= wcPumpfailureCheckTime || cancleWC == 1)
        {
          if (liters == previousLiters)
          {
            terminal.println("Draining pump stopped");
            terminal.println("Water change aborted");
            terminal.flush();
            digitalWrite(wcDrainPump, HIGH);//reversed
            drainwaterpumpled.off();
            wcinp = 0;
            Blynk.run(); // run Blynk process
            break;
          }
          else {
            previousDrainingWaterPointInTime = millis();
            previousLiters = liters;
          }
        }
        Blynk.run(); // run Blynk process
        liters = pulses; //flow sensor
        liters /= 7.5; //flow sensor
        liters /= 60.0; //flow sensor
        //Serial.print(liters); Serial.println(" Liters");
        if (millis() - drainingwaterTerminalPrint >= timeBetweenWcMsgs)
        {
          terminal.print("Draining water. ");
          terminal.print(liters);
          terminal.print(" ltr ");
          terminal.print(liters / selectedwateramount * 100);
          terminal.println("% completed");
          terminal.flush();
          drainingwaterTerminalPrint = millis();
          terminal.flush();
        }

        //switch on sump pump

        digitalWrite(wcFillPump, HIGH);//reversed
        digitalWrite(wcDrainPump, LOW);//reversed
      }
      wcFloatSwitchstatus = digitalRead(wcFloatSwitchpin);


      unsigned long addingwaterTerminalPrint = millis();

      while (liters >= selectedwateramount && wcFloatSwitchstatus == LOW) {
        if (digitalRead(wcSwFloatSwitchpin) == HIGH)
        {
          if (cancleWC == 0)
          {
            Blynk.run(); // run Blynk process
            wcFloatSwitchstatus = digitalRead(wcFloatSwitchpin);

            if (millis() - addingwaterTerminalPrint >= timeBetweenWcMsgs)
            {
              terminal.println("Adding water");
              terminal.flush();
              addingwaterTerminalPrint = millis();
              addwaterpumpled.on();
              drainwaterpumpled.off();
              terminal.flush();
            }
            //switch on res pump
            digitalWrite(wcFillPump, LOW);//reversed
            digitalWrite(wcDrainPump, HIGH);//reversed

            //blinking adding water text
            //delay(500);
          }
          if (wcFloatSwitchstatus == HIGH) {
            //delay(2000); to eliminate sensor sensitivity should be added later somehow
            Blynk.run(); // run Blynk process
            Blynk.virtualWrite(100, liters);
            tone(tonePin, 1000, 300);
            tone(tonePin, 500, 300);
            tone(tonePin, 1000, 300);
            String wcMailMessage = "A water change of ";
            wcMailMessage += liters;
            wcMailMessage += " liters has been performed in ";
            wcMailMessage += (millis() - drainingWaterStartTime) / 60000;
            wcMailMessage += " minutes.";
            Blynk.email("haidar23@gmail.com", "Water Change Completed", wcMailMessage);
            pulses = 0;
            liters = 0;
            selectedwateramount = 0;
            digitalWrite(wcFillPump, HIGH);//reversed
            digitalWrite(wcDrainPump, HIGH);//reversed
            addwaterpumpled.off();
            drainwaterpumpled.off();
            //Blynk.run(); // run Blynk process
            pumpsOn();
            terminal.println("Water change completed");
            terminal.flush();
            wcinp = 0;
            //Blynk.run(); // run Blynk process
          }
          else if ( cancleWC == 1)
          {
            digitalWrite(wcFillPump, HIGH);//reversed
            digitalWrite(wcDrainPump, HIGH);//reversed
            addwaterpumpled.off();
            drainwaterpumpled.off();
            wcinp = 0;
            terminal.println("Water change cancelled");
            terminal.flush();
            Blynk.run(); // run Blynk process
            break;
          }
        }
        else
        {
          digitalWrite(wcFillPump, HIGH);//reversed
          digitalWrite(wcDrainPump, HIGH);//reversed
          addwaterpumpled.off();
          drainwaterpumpled.off();
          wcinp = 0;
          terminal.println("Insufficient salt water, please prepare salt water mix and try again");
          terminal.flush();
          Blynk.run(); // run Blynk process
          break;
        }
      }
    }
    else
    {
      terminal.println("Please enter a valid amount");
      terminal.flush();
    }
  }
  else
  {
    terminal.println("Insufficient salt water, please prepare salt water mix and try again");
    terminal.flush();
  }
}

//------END Water change function---------------------


//------Start ATO function---------------------
void AutoTopOff()
{
  secondsSinceATOPumpOn = 0;
  feshWaterFloatSwitchStatus = digitalRead(feshWaterFloatSwitchpin);
  atoFloatSwitchStatusH = digitalRead(atoFloatSwitchStatusHpin);
  atoFloatSwitchStatusL = digitalRead(atoFloatSwitchStatusLpin);

  if (wcinp == 0 && feshWaterFloatSwitchStatus == HIGH && (digitalRead(returnPump) == LOW))//reversed  //if water change not in process and fresh water switch is on /enought fresh water/
  {
    unsigned long ATOStartTime = millis();
    while (atoFloatSwitchStatusL == LOW && feshWaterFloatSwitchStatus == HIGH)
    {
      if (Blynk.connected())
      {
        Blynk.run(); // run Blynk process
      }
      atoFloatSwitchStatusH = digitalRead(atoFloatSwitchStatusHpin);
      atoFloatSwitchStatusL = digitalRead(atoFloatSwitchStatusLpin);
      feshWaterFloatSwitchStatus = digitalRead(feshWaterFloatSwitchpin);
      wcFloatSwitchstatus = digitalRead(wcFloatSwitchpin);
      //terminal.println("ATO in progress");
      if (atoFloatSwitchStatusL == LOW && atoFloatSwitchStatusH == LOW)
      {
        digitalWrite(ATO, LOW);//reversed

        if (millis() - ATOStartTime >= 1000)
        {
          secondsSinceATOPumpOn = secondsSinceATOPumpOn + 1;
          terminal.print("Time since ATO started (sec): ");
          terminal.println(secondsSinceATOPumpOn);
          atopumpled.on();
          ATOStartTime = millis();
          terminal.flush();
        }

        if (secondsSinceATOPumpOn > maxTimeForContATORun)
        {
          if (Blynk.connected())
          {
            Blynk.run(); // run Blynk process
          }
          digitalWrite(ATO, HIGH);//reversed
          Blynk.virtualWrite(99, secondsSinceATOPumpOn); //send ATO run time to graph
          atopumpled.off();
          terminal.print("ATO ran for more than ");
          terminal.print(maxTimeForContATORun);
          terminal.println(" seconds");
          Blynk.notify("ATO ran for a long time and was stopped");
          terminal.flush();

          break;
        }
      }
      if (atoFloatSwitchStatusH == HIGH && atoFloatSwitchStatusL == LOW)
      {
        digitalWrite(ATO, HIGH);//reversed
        Blynk.virtualWrite(99, secondsSinceATOPumpOn); //send ATO run time to graph
        atopumpled.off();
        terminal.println("Lower ATO sump float switch is not working");
        terminal.flush();
        Blynk.notify("Lower ATO sump float switch is not working");
        Blynk.email("haidar23@gmail.com", "ATO float switch is broken", "Fresh water not sufficient for ATO, please consider adding fresh water as soon as possible");
        Blynk.run(); // run Blynk process
        break;
      }

      if (wcFloatSwitchstatus == HIGH && (digitalRead(returnPump) == LOW) && (atoFloatSwitchStatusL == LOW || atoFloatSwitchStatusH == LOW))//reversed
      {
        digitalWrite(ATO, HIGH);//reversed
        Blynk.virtualWrite(99, secondsSinceATOPumpOn); //send ATO run time to graph
        atopumpled.off();
        terminal.println("ATO pumped excessive amount of water and it was switched of for safety, check lower and upper ATO float switches");
        terminal.flush();
        Blynk.notify("ATO pumped excessive amount of water. Water level reached the maximum");
        Blynk.email("haidar23@gmail.com", "ATO float switch is broken", "ATO pumped excessive amount of water and it was switched off for safety, check lower and upper ATO float switches");
        Blynk.run(); // run Blynk process
        break;
      }

    }
    digitalWrite(ATO, HIGH);//reversed
    Blynk.virtualWrite(99, secondsSinceATOPumpOn); //send ATO run time to graph
    atopumpled.off();
  }
  else if (wcinp == 0 && feshWaterFloatSwitchStatus == LOW)
  {
    tone(tonePin, 1000, 300);
    terminal.println("Fresh water not sufficient for ATO, please consider adding fresh water as soon as possible");
    terminal.flush();
    Blynk.notify("Fresh water not sufficient for ATO, please consider adding fresh water as soon as possible");
    Blynk.email("haidar23@gmail.com", "Fresh water not sufficient", "Fresh water not sufficient for ATO, please consider adding fresh water as soon as possible");
  }
  else if (wcinp == 1 || (digitalRead(returnPump) == HIGH))//reversed
  {
    terminal.println("Water change in progress/return pump is off, water topoff skipped.");
    terminal.flush();
  }
}
//------END ATO---------------------



    }
  }

}

I see you have a couple of calls to Blynk.run() outside the loop. Why is that? I’m pretty sure that is not needed. And the one in ATO function has an if Blynk.connected() statement in it too.

Hi Lichtsignaal,

I had to add Blynk.run() in the while loops to maintain the heartbeat as these functions might run for several minutes especially the water change function.
I know I need to find a way do this differently, but I am interested to know why when the debut is enable not disconnects happen.
I have a feeling that the disconnect notifications I am receiving when debug is disabled are false alarms as the system keeps working fine without any interruptions before and after the notification is received.

@haidar23 just so you and others new to Blynk are aware you will ALWAYS get disconnection notices if you are flashing new sketches to your hardware. If you flash a new sketch and then “hours / days later” look at the app for the first time you will see the disconnection notice.

It could be a notice that is days old and is just telling you that you flashed a new sketch or the hardware disconnected since you last used the app.

There are various “timeouts” in server.properties and I’m not sure if any of them relate to the “hours / days later” aspect. Might not be as long as hours or days as I am using my app 24/7 so it never gets to hours let alone days before informing me of the “disconnect”.

Thanks Costas. You are right, I noticed that notifications are not always real time.
However in the case I am describing, I get these disconnects while testing/running these function (with debug disabled), so I am sure these are real time notifications.
Can this be because of the fact that enabling debug slows down processing about 10 times, which reduces the server requests frequency?

I guess it’s possible and something that did cross my mind but to be honest I think this is unlikely.
I don’t use DEBUG very often but I think the factor of 10 is the maximum and normally it is much lower than this. It perhaps depends exactly what your sketch is doing.

You need to build up your sketch from the basics and keep adding to it in stages until your bug appears.