Blynk App Keeps Disconnecting and Reconnecting From Hardware

Hi,

I believe this title is somewhat overused in the community, but I have read the topics and none of them seems to solve the problem with my project.

—Project Details (I guess)—

I am working on a water monitoring device connected to the Blynk server so that I can view the water quality values on my phone anywhere. My hardware setup is an Arduino Uno wired to an ESP-01, like a WiFi shield (I used external 3.3V regulator AMS1117 connected to Vin of Arduino Uno to power it). I am viewing the data on my Android phone with version 5.1. My Blynk Library version is 0.6.1.

The sensor I am using are DS18B20 Temperature Sensor, pH sensor, TDS sensor, Turbidity sensor and a Dissolved Oxygen Sensor (haven’t bought the sensor yet thanks to its high cost but the code is in the sketch)

I also wired a speaker so that it can produce a siren or something when some sensor values exceed their thresholds.

—The problem—

The app works until I uncomment the line where it will send the dissolved oxygen values to the server. The Blynk App on my phone says that the device disconnected. Shortly, the app says the device is connected and the process repeats.

This is the code I am using:


#define BLYNK_MAX_SENDBYTES 256 // increase number of bytes that can be sent for email and notifications
#define BLYNK_PRINT Serial // uncomment it to view connection logs, comment it to disable print and save space

//Importing necessary libraries
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>


//defining IO pins and other stuff
#define ESP8266_BAUD 9600       // Baud rate to communicate with ESP-01
#define tempSen 4               // DS18B20 Temperature Sensor
#define spkPin 6                // Speaker
#define relayPin 7              // Relay that controls an oxygen air pump
#define loudAlarm 8             // ne555 beeping circuit
#define pHSen A0                // pH Sensor
#define tdsEcSen A1             // TDS EC sensor
#define turbiSen A2             // Turbidity sensor
#define doSen A3                // Dissolved oxygen sensor
#define vRef 5000               //VREF (mv)
#define adcRes 1024            //ADC Resolution
#define twoPointCalib 0 //Single-point calibration Mode=0 OR Two-point calibration Mode=1
//Single point calibration needs to be filled CAL1_V and CAL1_T
#define cal1V (131)            //mv
#define cal1T (25)             //Celsius
//Two-point calibration needs to be filled CAL2_V and CAL2_T
//CAL1 High temperature point, CAL2 Low temperature point
#define cal2V (1300)           //mv
#define cal2T (15)             //Celsius


//variables
char auth[] = "insertauth"; // auth token
char ssid[] = "insertssid";                  // WiFi SSID.
char pass[] = "insertpass";                       // WiFi password. Set password to "" for open networks.
const unsigned long period = 60000;
unsigned long int avgValue;                       // Store the average value of the sensor feedback
unsigned long tempStartTime;
unsigned long pHStartTime;
unsigned int tds = 0;                             // total dissolved solids value
int tempTrig = 0;
int pHTrig = 0;
int senValue = 0;   // variable to store the value coming from the sensor
float ad7 = 366.0;     // change this value to the one on serial monitor when in pH7 buffer
float ad4 = 144.0;     // change this value to the one on serial monitor when in pH4 buffer
float temp = 0;
float volt = 0;
float ntu;
float ec = 0;
float pH;
float ecCalibration = 1;
uint16_t adcVoltage;
float dO = 0;
const uint16_t doTable[41] = {
  14460, 14220, 13820, 13440, 13090, 12740, 12420, 12110, 11810, 11530,
  11260, 11010, 10770, 10530, 10300, 10080, 9860, 9660, 9460, 9270,
  9080, 8900, 8730, 8570, 8410, 8250, 8110, 7960, 7820, 7690,
  7560, 7430, 7300, 7180, 7070, 6950, 6840, 6730, 6630, 6530, 6410
};

int16_t readDO(uint32_t voltageMv, uint8_t temperatureC) {
#if twoPointCalib == 00
  uint16_t vSaturation = (uint32_t)cal1V + (uint32_t)35 * temperatureC - (uint32_t)cal1T * 35;
  return (voltageMv * doTable[temperatureC] / vSaturation);
#else
  uint16_t vSaturation = (int16_t)((int8_t)temperatureC - cal2T) * ((uint16_t)cal1V - cal2V) / ((uint8_t)cal1T - cal2T) + cal2V;
  return (voltageMv * doTable[temperatureC] / vSaturation);
#endif
}

float roundToDp( float inValue, int decimalPlace ) {
  float multiplier = powf( 10.0f, decimalPlace );
  inValue = roundf( inValue * multiplier ) / multiplier;
  return inValue;
}


//objects
SoftwareSerial EspSerial(2, 3); // RX, TX
ESP8266 wifi(&EspSerial);
BlynkTimer timer;
OneWire oneWire(tempSen);
DallasTemperature tempObj(&oneWire);

//obtain temperature
void getTemp() {
  tempObj.requestTemperatures();
  temp = tempObj.getTempCByIndex(0);
  Blynk.virtualWrite(V0, temp);
}


//functions
//obtain total dissolved solids and electrical conductivity
void getTdsEc() {
  float rawEc = analogRead(tdsEcSen) * (vRef / 1000) / 1024.0;                 // read the analog value more stable by the median filtering algorithm, and convert to voltage value
  float tempCoefficient = 1.0 + 0.02 * (temp - 25.0);                 // temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
  ec = (rawEc / tempCoefficient) * ecCalibration;                     // temperature and calibration compensation
  tds = (133.42 * pow(ec, 3) - 255.86 * ec * ec + 857.39 * ec) * 0.5; //convert voltage value to tds value (not needed for now)
  Blynk.virtualWrite(V1, ec);
}

//obtain water turbidity
void getTurbidity() {
  for (int i = 0; i < 800; i++) {
    volt += ((float)analogRead(turbiSen) / 1023) * 5;
  }
  volt /= 800;
  volt = roundToDp(volt, 2);
  if (volt < 2.5) {
    ntu = 3000;
  } else {
    ntu = -1120.4 * sq(volt) + 5742.3 * volt - 4353.8;
  }
  Blynk.virtualWrite(V2, ntu);
}


//obtain water pH
void getpH() {
  int currValue = 0;

  for (int i = 0; i < 10; i++)
  {
    currValue += analogRead(pHSen);
    delay(100);
  }
  senValue = (currValue / 10);
  //Serial.println(senValue); //uncomment this to do calibration
  float m = (-3.0 / (ad4 - ad7));
  //Serial.println(m);
  float c = 7 - (m * ad7);
  //Serial.println(c);
  float a = ((m * senValue) + c);
  //Serial.print("PH = ");    //uncomment this to do calibration
  //Serial.println(a);        //uncomment this to do calibration
  pH = a;
  delay(500);

  Blynk.virtualWrite(V3, pH);
}


//obtain dissolved oxygen in water
void getDO() {
  adcVoltage = uint32_t(vRef) * analogRead(doSen) / adcRes;
  dO = readDO(adcVoltage, uint8_t(temp));
  Blynk.virtualWrite(V4, dO);         // <-------- the connection to Blynk app keeps restarting when I uncomment this line
}

//alert if temperature exceeds a certain limit
void tempAlarm() {
  unsigned long tempTime = millis();
  if (temp > 30) {
    if (tempTime - tempStartTime >= 60000 && tempTrig == 1) {
      Blynk.notify(String("TempNow: ") + String(temp) + String(" C"));
      tempStartTime = tempTime;
    }
    else if (tempTrig == 0) {
      Blynk.email("email@example.com", "Temp Alert", String("TempRec: ") + temp + String("°C"));
      //PORTD &= ~(1 << PORTD7);
      tempTrig = 1;
    }
  }
  else {
    if (tempTrig == 1) {
      //PORTD |= (1 << PORTD7);
      tempTrig = 0;
    }
  }
}

//alert if pH exceeds a certain limit
void pHAlarm() {
  unsigned long pHTime = millis();
  if (pH > 7 || pH < 6) {
    if (pHTime - pHStartTime >= 30000 && pHTrig == 1) {
      Blynk.notify(String("pHNow: ") + String(pH));
      pHStartTime = pHTime;
    }
    else if (pHTrig == 0) {
      Blynk.email("email@example.com", "pH Alert", String("pHRec: ") + pH);
      pHTrig = 1;
    }
  }
  else {
    if (pHTrig == 1) {
      pHTrig = 0;
    }
  }
}

void doAlarm() {
//will implement later
}

//produce siren
void alarmSound() {
  unsigned long alarmTime = millis();
  if (tempTrig == 1 || pHTrig == 1) {
    tone(spkPin, 880);
  }
  else {
    noTone(spkPin);
  }
}


void setup() {
  //obtaining reference time to replace delay() function
  tempStartTime = millis();
  pHStartTime = millis();

  Serial.begin(9600);                   // begin serial monitor, 9600 is recommended for ESP8266 shield setup
  delay(10);
  EspSerial.begin(ESP8266_BAUD);        // Set ESP8266 baud rate
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);  // start Blynk

  tempObj.begin();                      // start DS18B20
  DDRD |= (1 << DDD7);                  // set digital pin 7 as OUTPUT (relayPin)
  PORTD |= (1 << PORTD7);               // set digital pin 7 OUTPUT as HIGH (this will turn off relay)

  //BlynkTimer part to send data to Blynk app within fixed periods (if the app disconnects frequently, try tuning the timeout or interval)
  timer.setTimeout(100, []() {
    timer.setInterval(5000L, getTemp);
  });
  timer.setTimeout(200, []() {
    timer.setInterval(5000L, getTdsEc);
  });
  timer.setTimeout(300, []() {
    timer.setInterval(5000L, getTurbidity);
  });
  timer.setTimeout(400, []() {
    timer.setInterval(5000L, getpH);
  });
  timer.setTimeout(500, []() {
    timer.setInterval(10000L, getDO);
  });
  timer.setTimeout(600, []() {
    timer.setInterval(6000L, tempAlarm);
  });
  timer.setTimeout(700, []() {
    timer.setInterval(6000L, pHAlarm);
  });
  timer.setTimeout(800, []() {
    timer.setInterval(10000L, alarmSound);
  });

  //intro (tells user that the device is up and running)
  for (int i = 0; i < 3; i++) {
    tone(spkPin, 1046.50, 10);
    delay(100);
  }
}

void loop() {
  // ONLY THESE 2 LINES OF CODE CAN BE HERE, REFRAIN FROM ADDING MORE CODE IN LOOP TO PREVENT DISCONNECTION ISSUES

  Blynk.run();
  timer.run();

}

This is the Serial output (that is all it shows, no more prints even after an hour):

I am not sure if this has something to do with the dissolved oxygen code (because I tried replacing the value of dO variable in Blynk.virtualWrite(V4, dO); with a fixed value and the Blynk app can respond correctly.)

I also stumbled across the pinout diagram of ESP32 and realized that it has a lot of analog pins, unlike standalone ESP8266 (because I may add more analog Sensors in the future). I may have to switch to ESP32 but I have already wasted 2 weeks soldering the circuit on a prototype board (thanks to breadboard’s loose connections that messed up my ESP-01) and finding the perfect wire management (which is still not pretty but not too bad).

Is this how far I can go with Arduino with ESP8266 shield setup or I just don’t know how to code IoT projects properly?

Many thanks.

How much memory does this sketch use?

What happens if you add a line which serial prints the d0 value instead of sending it to Blynk?

Pete.

Also, your timers aren’t structured very well. You have many timers that all fire every 5 seconds. Your single threaded processor can’t process these functions simultaneously, so you should stagger your timers.

Pete.

Sorry for the late reply, I was having online classes.

Here is the original code’s memory usage screenshot:

I have tried printing the dO value on Serial instead of sending it to Blynk, but the app still disconnects and reconnects and no serial output of the dO value (only the Blynk print). Adding a millis() delay of 5 seconds does not help.

Regarding the timers, I actually got it from Jamin in this topic:

Not sure if I have misunderstood something in the discussion…

I tried staggering my timers like this:


  timer.setTimeout(100, []() {
    timer.setInterval(5010L, getTemp);
  });
  timer.setTimeout(200, []() {
    timer.setInterval(5020L, getTdsEc);
  });
  timer.setTimeout(300, []() {
    timer.setInterval(5030L, getTurbidity);
  });
  timer.setTimeout(400, []() {
    timer.setInterval(5040L, getpH);
  });
  timer.setTimeout(500, []() {
    timer.setInterval(5050L, getDO);
  });
  timer.setTimeout(600, []() {
    timer.setInterval(6000L, tempAlarm);
  });
  timer.setTimeout(700, []() {
    timer.setInterval(6010L, pHAlarm);
  });
  timer.setTimeout(800, []() {
    timer.setInterval(10000L, alarmSound);
  });

and this:


  timer.setTimeout(100, []() {
    timer.setInterval(5000L, getTemp);
  });
  timer.setTimeout(200, []() {
    timer.setInterval(10000L, getTdsEc);
  });
  timer.setTimeout(300, []() {
    timer.setInterval(15000L, getTurbidity);
  });
  timer.setTimeout(400, []() {
    timer.setInterval(20000L, getpH);
  });
  timer.setTimeout(500, []() {
    timer.setInterval(25000L, getDO);
  });
  timer.setTimeout(600, []() {
    timer.setInterval(6000L, tempAlarm);
  });
  timer.setTimeout(700, []() {
    timer.setInterval(12000L, pHAlarm);
  });
  timer.setTimeout(800, []() {
    timer.setInterval(30000L, alarmSound);
  });

as well as this:


  timer.setTimeout(250, []() {
    timer.setInterval(5000L, getTemp);
  });
  timer.setTimeout(500, []() {
    timer.setInterval(10000L, getTdsEc);
  });
  timer.setTimeout(750, []() {
    timer.setInterval(15000L, getTurbidity);
  });
  timer.setTimeout(1000, []() {
    timer.setInterval(20000L, getpH);
  });
  timer.setTimeout(1250, []() {
    timer.setInterval(25000L, getDO);
  });
  timer.setTimeout(1500, []() {
    timer.setInterval(6000L, tempAlarm);
  });
  timer.setTimeout(1750, []() {
    timer.setInterval(12000L, pHAlarm);
  });
  timer.setTimeout(2000, []() {
    timer.setInterval(30000L, alarmSound);
  });

but they all do not work. Am I doing it right? From what I understand, using the setTimeout method should call the functions sequentially even though the setInterval duration are the same.

also forgot to note that when the app disconnects and reconnects, this code in the setup seems to not run:


  for (int i = 0; i < 3; i++) {
    tone(spkPin, 1046.50, 10);
    delay(100);
  }

so no beeping at all…

Apologies, I hadn’t looked at the delays between the timers, but the delays assume that each function that is called every 5000ms takes 100ms to execute - therefore meaning that the processor is available to do the next timed task.
What evidence do you have to support this?

Try changing the variable name from d0 to something else (dissolved_oxygen maybe?). D0 is used to reference digital pin zero with some boards and may be a reserved word, or at least one that causes issues.

Also, if that doesn’t help try breaking down the elements that make-up the calculation of dissolved oxygen and serial printing this at various points to ensure that there isn’t something odd happening.

Pete.

Thanks for the quick reply

I experimented the setTimeout() with this code:


#define BLYNK_PRINT Serial // uncomment it to view connection logs, comment it to disable print and save space

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SoftwareSerial.h>
#define ESP8266_BAUD 9600       // Baud rate to communicate with ESP-01

char auth[] = "insertauth"; // auth token
char ssid[] = "insertssid";                  // WiFi SSID.
char pass[] = "insertpass";                       // WiFi password. Set password to "" for open networks.

SoftwareSerial EspSerial(2, 3); // RX, TX
ESP8266 wifi(&EspSerial);
BlynkTimer timer;

void first(){
  Serial.println("this is first");
}

void seco(){
  Serial.println("this is seco");
}

void third(){
  Serial.println("this is third");
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);                   // begin serial monitor, 9600 is recommended for ESP8266 shield setup
  delay(10);
  EspSerial.begin(ESP8266_BAUD);        // Set ESP8266 baud rate
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);  // start Blynk

  timer.setTimeout(1000, []() {
    timer.setInterval(5000L, first);
  });
  timer.setTimeout(2000, []() {
    timer.setInterval(10000L, seco);
  });
  timer.setTimeout(3000, []() {
    timer.setInterval(15000L, third);
  });
}

void loop() {
  // put your main code here, to run repeatedly:
  Blynk.run();
  timer.run();
}

and the serial output does not seem to have any overlapped prints. Do you mean that in the original code, the processor is actually taking some time to execute the things in the functions and 100ms is negligible to make any difference, so saying that the processor is available to do other things is invalid? I am kinda lost now…

The O in dO is actually an O, not zero, but I changed it to doOutput to make it easier to read.

The code works until I uncomment the line Blynk.virtualWrite(V4, doOutput); or Serial print it. But I will try to modify the calculation part and see if there is any luck.

Few years ago, I actually made something a little similar but the hardware setup is a standalone LoLin NodeMCU ESP8266 V3. The code is terrible (because I broke the rule of keeping your void loop() clean) but I don’t remember having any runtime errors

Yes, of course.

Pete.

The original code was a mess (tons of unused variables and other unorganized stuff). So I decided to move some code that is known to work. I started with sending only dissolved oxygen sensor values to Blynk and it worked. Later I send more sensor values and also adding the alarm functions (basically just sending notifications and emails) and the entire thing is working normally now.

Not exactly sure about the root cause of the problem, but I think it is a combination of badly staggered timers, inefficient code (although the latest code is probably still inefficient) and too many symbols to send in notification and email part…

Here is the latest code:


#define BLYNK_PRINT Serial // uncomment it to view connection logs, comment it to disable print and save space

#include <Arduino.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// For Ver. 2
//#include <ThingerESP8266AT.h>


#define doSen A3
#define tempSen 4               // DS18B20 Temperature Sensor
#define pHSen A0                // pH Sensor
#define tdsEcSen A1             // TDS EC sensor
#define turbiSen A2             // Turbidity sensor
#define vRef 5000    //VREF (mv)
#define adcRes 1024 //ADC Resolution

// For Ver. 2
/*#define USERNAME "username"
#define DEVICE_ID "id"
#define DEVICE_CREDENTIAL "credential"*/

//Single point calibration needs to be filled CAL1_V and CAL1_T
#define twoPointCalib 0 //Single-point calibration Mode=0 OR Two-point calibration Mode=1
//Single point calibration needs to be filled CAL1_V and CAL1_T
#define cal1V (131)            //mv
#define cal1T (25)             //Celsius
//Two-point calibration needs to be filled CAL2_V and CAL2_T
//CAL1 High temperature point, CAL2 Low temperature point
#define cal2V (1300)           //mv
#define cal2T (15)             //Celsius
#define ESP8266_BAUD 9600
#define spkPin 6

SoftwareSerial EspSerial(2, 3); // RX, TX
ESP8266 wifi(&EspSerial);
BlynkTimer timer;
OneWire oneWire(tempSen);
DallasTemperature tempObj(&oneWire);

// For Ver. 2
//ThingerESP8266AT thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, EspSerial);


char auth[] = "token"; // auth token
char ssid[] = "ssid";                  // WiFi SSID.
char pass[] = "pass";                       // WiFi password. Set password to "" for open networks.
unsigned long tempStartTime = 0;
unsigned long pHStartTime = 0;
unsigned long doStartTime = 0;
int ecCalibration = 1;
unsigned long int doOutput = 0;
String emailContent;
char notiContent;
float temp = 0;
float pH = 0;
float ntu = 0;
float ec = 0;
int tempTrig = 0;
int pHTrig = 0;
int doTrig = 0;
int sendOnce = 0;
uint16_t adcVoltage;
const uint16_t doTable[41] = {
  14460, 14220, 13820, 13440, 13090, 12740, 12420, 12110, 11810, 11530,
  11260, 11010, 10770, 10530, 10300, 10080, 9860, 9660, 9460, 9270,
  9080, 8900, 8730, 8570, 8410, 8250, 8110, 7960, 7820, 7690,
  7560, 7430, 7300, 7180, 7070, 6950, 6840, 6730, 6630, 6530, 6410
};
uint16_t readDO(uint32_t voltageMv, uint8_t temperatureC) {
#if twoPointCalib == 00
  uint16_t vSaturation = (uint32_t)cal1V + (uint32_t)35 * temperatureC - (uint32_t)cal1T * 35;
  return (voltageMv * doTable[temperatureC] / vSaturation);
#else
  uint16_t vSaturation = (int16_t)((int8_t)temperatureC - cal2T) * ((uint16_t)cal1V - cal2V) / ((uint8_t)cal1T - cal2T) + cal2V;
  return (voltageMv * doTable[temperatureC] / vSaturation);
#endif
}

float roundToDp( float inValue, int decimalPlace ) {
  float multiplier = powf( 10.0f, decimalPlace );
  inValue = roundf( inValue * multiplier ) / multiplier;
  return inValue;
}

void getTemp() {
  tempObj.requestTemperatures();
  temp = tempObj.getTempCByIndex(0);
  Blynk.virtualWrite(V0, temp);
}

void getTdsEc() {
  float rawEc = analogRead(tdsEcSen) * (vRef / 1000) / 1024.0;                 // read the analog value more stable by the median filtering algorithm, and convert to voltage value
  float tempCoefficient = 1.0 + 0.02 * (temp - 25.0);                 // temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
  ec = (rawEc / tempCoefficient) * ecCalibration;                     // temperature and calibration compensation
  //float tds = (133.42 * pow(ec, 3) - 255.86 * ec * ec + 857.39 * ec) * 0.5; //convert voltage value to tds value (not needed for now)
  Blynk.virtualWrite(V1, ec);
}

void getTurbidity() {
  float volt = 0;
  for (int i = 0; i < 800; i++) {
    volt += ((float)analogRead(turbiSen) / 1023) * 5;
  }
  //Serial.println(volt);
  volt /= 800;
  volt = roundToDp(volt, 2);

  if (volt < 2.5) {
    ntu = 3000;
  } else {
    ntu = -1120.4 * sq(volt) + 5742.3 * volt - 4353.8;
  }
  Blynk.virtualWrite(V2, ntu);

}

void getpH() {
  int currValue = 0;
  float ad7 = 366.0;     // change this value to the one on serial monitor when in pH7 buffer
  float ad4 = 144.0;     // change this value to the one on serial monitor when in pH4 buffer
  for (int i = 0; i < 10; i++)
  {
    currValue += analogRead(pHSen);
    //delay(100);
  }
  int senValue = (currValue / 10);
  //Serial.println(senValue); //uncomment this to do calibration
  float m = (-3.0 / (ad4 - ad7));
  //Serial.println(m);
  float c = 7 - (m * ad7);
  //Serial.println(c);
  float a = ((m * senValue) + c);
  //Serial.print("PH = ");    //uncomment this to do calibration
  //Serial.println(a);        //uncomment this to do calibration
  pH = a;
  //delay(500);

  Blynk.virtualWrite(V3, pH);
}

void getDO() {
  adcVoltage = uint32_t(vRef) * analogRead(doSen) / adcRes;
  doOutput = readDO(adcVoltage, uint8_t(temp)) / 1000;
  Blynk.virtualWrite(V4, String(doOutput));         // <-------- the connection to Blynk app keeps restarting when I uncomment this line
}

// For Ver. 2
/*void thingerSend() {
  thing["senVal"] >> [] (pson & out) {
    out["Celsius"] = temp;
  };
  thing.write_bucket("sensorValues", "senVal");
}*/

void tempAlarm() {
  unsigned long tempTime = millis();
  if (temp > 30) {
    if (tempTrig == 0) {
      Blynk.notify("TempNow: " + String(temp) + " C");
      Blynk.email("Alert", String("Temp"));
      tempTrig = 1;
    }
    else {
      if (tempTime - tempStartTime >= 300000) { //Wait for 5 minutes to alert the user again
        tempTrig = 0;
        tempStartTime = tempTime;
      }
    }
  }
  else {
    tempTrig = 0;
  }
}

void pHAlarm() {
  unsigned long pHTime = millis();
  if (pH > 7 || pH < 6) {
    if (pHTrig == 0) {
      Blynk.notify("pHNow: " + String(pH));
      Blynk.email("Alert", String("pH"));
      pHTrig = 1;
    }
    else {
      if (pHTime - pHStartTime >= 300000) { //Wait for 5 minutes to alert the user again
        pHTrig = 0;
        pHStartTime = pHTime;
      }
    }
  }
  else {
    pHTrig = 0;
  }
}

void doAlarm() {
  unsigned long doTime = millis();
  if (doOutput < 5000) {
    if (doTrig == 0) {
      Blynk.notify("DoNow: " + String(doOutput) + " mg/L");
      Blynk.email("Alert", String("DO"));
      doTrig = 1;
      PORTD &= ~(1 << PORTD7);
    }
    else {
      if (doTime - doStartTime >= 300000) { //Wait for 5 minutes to alert the user again
        doTrig = 0;
        doStartTime = doTime;
      }
    }
  }
  else {
    PORTD |= (1 << PORTD7);
    doTrig = 0;
  }
}


void alarmSound() {
  if (tempTrig == 1 || pHTrig == 1 || doTrig == 1) {
    tone(spkPin, 400);
  }
  else {
    noTone(spkPin);
    
  }
}



void setup()
{
  Serial.begin(9600);                   // begin serial monitor, 9600 is recommended for ESP8266 shield setup
  delay(10);
  EspSerial.begin(ESP8266_BAUD);        // Set ESP8266 baud rate
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);  // start Blynk
  
  // For Ver. 2
  //thing.add_wifi(ssid, pass);
  tempObj.begin();                      // start DS18B20
  DDRD |= (1 << DDD7);                  // set digital pin 7 as OUTPUT (relayPin)
  PORTD |= (1 << PORTD7);               // set digital pin 7 OUTPUT as HIGH (this will turn off relay)


  timer.setInterval(2000L, alarmSound);
  timer.setInterval(5000L, getTemp);
  timer.setInterval(5010L, getDO);
  timer.setInterval(5020L, getTdsEc);
  timer.setInterval(5030L, getTurbidity);
  timer.setInterval(5040L, getpH);
  timer.setInterval(6100L, tempAlarm);
  timer.setInterval(6200L, pHAlarm);
  timer.setInterval(6300L, doAlarm);
  
  // For Ver. 2
  //timer.setInterval(60000L, thingerSend);
  
  for (int i = 0; i < 3; i++) {
    tone(spkPin, 1046.50, 10);
    delay(100);
  }
}

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

  // For Ver. 2
  //thing.handle();
}

DId I stagger my timers properly this time? I have to shorten my messages for the app to work and I cannot add #define BLYNK_MAX_SENDBYTES as that will cause disconnection problems.

Now my project requirements have been raised and sticking with esp8266 as wifi shield is probably not a viable option anymore, so I have to upgrade it to ESP32 welp.

Maybe I will share my final results in this community when I am done with everything.

It’s impossible to say, without your hardware and preforming tests that print the current millis() value when the various functions begin and end and comparing the results to calculate the average duration of each function.
Personally, I’d be surprised if some of the functions that take sensor readings then perform some calculations can consistently execute in 10ms.

Pete.

Im having the same issue. Im using Arduino uno and ESP01 module but it keeps disconnecting and reconnecting can anybody help

Hey um sorry that I kept this thread inactive for a long time. Can you share your code and schematic diagram? Not sure if I still remember how to do it but I will try to help.

A post was merged into an existing topic: Ping Multi without any connection