BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Flow Meters sporadically log flow when there is none - Otherwise works perfectly

Greetings, I’ve been using Blynk for years, soon after the Kickstarter, quietly lurking, making dozens of projects without much problem even though I still consider myself quite a noob.

But this one has me stumped and I don’t even know where to look to find the problem. This project is trying to log water consumption from 2 separate water systems in our Overland Truck. Our water tanks are pressurized stainless steel kegs and thus we can’t easily see our remaining water supply. One system is for our purified drinking water, it has 2 stainless float switches that trip at 10L and 20L of water remaining and now also a flow meter. And the second set of tanks is for wash water that we get from random taps along the way, this also has a separate flow meter.

I have the flow meters calibrated perfectly - They measure to the mL as close as I can verify with a measuring cup or filling several 1l bottles etc - it’s spot on and works perfectly… Until it glitches.

The problem I’m having is that once or twice a day it will just drop 2 or 3 liters from the count, and oddly it’s usually in the middle of the night, and it’s usually on both water systems. In the screenshot below you can see this at 1:30am and again at 3:30am.

In an attempt to track it down, I disconnected one of the flow meters and tied the signal pin to ground and it still glitches in the same way in time with the other. For this reason, I don’t think it’s hardware.

Because it often happens when we’re sleeping I started logging the serail data showing the flow rate and consumption, but as shown below there is no flow being detected between 17:23 and 08:41, but yet the consumption jumped by ~2 liters in the middle of the night. (the event isn’t logged because it only writes debugs when there is flow)

[17:23:06:405] Flowing: 2.6L/min␍␊
[17:23:06:405] Flowing: 43mL/Sec␍␊
[17:23:06:438] Drinking Water Remaining: 15.59L␍␊
[17:23:07:406] Flowing: 1.0L/min␍␊
[17:23:07:406] Flowing: 18mL/Sec␍␊
[17:23:07:439] Drinking Water Remaining: 15.57L␍␊
[08:41:19:931] Flowing: 0.1L/min␍␊
[08:41:19:931] Flowing: 1mL/Sec␍␊
[08:41:19:965] Drinking Water Remaining: 13.71L␍␊ <—{ Here the water remaining jumps by ~2 liters}

The code below is taken from Pkarun’s GitHub and was nearly perfect for my needs, I only duplicated everything to track two separate flow meters and added my float switches.

• Hardware Details: Wemos D1 mini, 2 Flow Meters, 2 Float Switches
• Smartphone OS is Android 10
• Currently using the Blynk server


/*
 Using Code modified from: 
 Blynk Flow Sensor Water Meter- Calculates Total Water Consumption.
  Source: https://github.com/pkarun/Blynk-Flow-Sensor-Water-Meter
*/

//#define BLYNK_PRINT Serial           // Uncomment for debugging

#include "settings.h"
#include "secret.h"   // <<--- UNCOMMENT this before you use and change values on config.h tab

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//#include <ESP8266mDNS.h>  // For OTA with ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

BlynkTimer timer;

int BLYNKneedsZero = 0;
int BLYNKneedsUpdate = 0;
int topFloatTripped = 0;
int bottomFloatTripped = 0;
volatile long DRINKpulseCount = 0;
volatile long WASHpulseCount = 0;
float DRINKflowRate;
float WASHflowRate;
unsigned int DRINKflowMilliLitres;
unsigned int WASHflowMilliLitres;
unsigned long DRINKtotalMilliLitres;
unsigned long WASHtotalMilliLitres;
float DRINKtotalLitres;
float WASHtotalLitres;
float DRINKtotalLitresold;
float WASHtotalLitresold;
unsigned long DRINKoldTime;
unsigned long WASHoldTime;


BLYNK_CONNECTED() { // runs once at device startup, once connected to server.

  Blynk.syncVirtual(VPIN_TOTAL_LITERS_DRINK); //gets last know value of virtual pin
  Blynk.syncVirtual(VPIN_TOTAL_LITERS_WASH); //gets last know value of virtual pin
}

// Restores last known liter count values from the virtual pin on the Blynk server
BLYNK_WRITE(VPIN_TOTAL_LITERS_DRINK)
{
  DRINKtotalLitresold = param.asFloat();
}

BLYNK_WRITE(VPIN_TOTAL_LITERS_WASH)
{
  WASHtotalLitresold = param.asFloat();
}

BLYNK_WRITE(VPIN_SET_DRINK) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersDrink = param.asInt();
  Serial.println("Setting Drinking Water Level");
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, setLitersDrink);
  Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, 0);
  DRINKflowRate = 0;
  DRINKflowMilliLitres = 0;
  DRINKtotalMilliLitres = 0;
  DRINKtotalLitres = setLitersDrink;
  DRINKtotalLitresold = setLitersDrink;
  Blynk.virtualWrite(VPIN_SET_DRINK, " ");
  topFloatTripped = 0;
  bottomFloatTripped = 0;
  Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
  Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_BLUE);
}

BLYNK_WRITE(VPIN_SET_WASH) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersWASH = param.asInt();
  Serial.println("Setting WASHing Water Level");
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, setLitersWASH);
  Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, 0);
  WASHflowRate = 0;
  WASHflowMilliLitres = 0;
  WASHtotalMilliLitres = 0;
  WASHtotalLitres = setLitersWASH;
  WASHtotalLitresold = setLitersWASH;
  Blynk.virtualWrite(VPIN_SET_WASH, " ");
  //Blynk.setProperty(VPIN_TOTAL_LITERS_WASH, "color", BLYNK_YELLOW);
}

void DRINKpulseCounter()
{
  DRINKpulseCount++;
}
void WASHpulseCounter()
{
  WASHpulseCount++;
}

void flow()
{

  if ((millis() - DRINKoldTime) > 1000)   // Only process counters once per second
  {
    detachInterrupt(PULSE_PIN_DRINK);
    DRINKflowRate = ((1000.0 / (millis() - DRINKoldTime)) * DRINKpulseCount) / FLOW_CALIBRATION;
    DRINKoldTime = millis();
    DRINKflowMilliLitres = (DRINKflowRate / 60) * 1000;
    DRINKtotalMilliLitres += DRINKflowMilliLitres;
    DRINKtotalLitres = DRINKtotalLitresold - DRINKtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN
    unsigned int frac;

    if (DRINKflowRate > 0) {
      // Print the flow rate for this second in liters / minute
      Serial.print("Flowing: ");
      Serial.print(int(DRINKflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (DRINKflowRate - int(DRINKflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(DRINKflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Drinking Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(DRINKtotalLitres);
      Serial.println("L");
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 1;
    }
    if (DRINKflowRate == 0 & BLYNKneedsZero == 1) {
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 0;
    }

    DRINKpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

    attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output

    detachInterrupt(PULSE_PIN_WASH);
    WASHflowRate = ((1000.0 / (millis() - WASHoldTime)) * WASHpulseCount) / FLOW_CALIBRATION;
    WASHoldTime = millis();
    WASHflowMilliLitres = (WASHflowRate / 60) * 1000;
    WASHtotalMilliLitres += WASHflowMilliLitres;
    WASHtotalLitres = WASHtotalLitresold - WASHtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN
    //unsigned int frac; //Don't need this twice

    if (WASHflowRate > 0) {

      // Print the flow rate for this second in liters/minute
      Serial.print("Flowing: ");
      Serial.print(int(WASHflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (WASHflowRate - int(WASHflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(WASHflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Washing Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(WASHtotalLitres);
      Serial.println("L");
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 1;
    }

    if (WASHflowRate == 0 & BLYNKneedsZero == 1) {
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 0;
    }

    WASHpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

    attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output
  }

}


void sendtoBlynk()  // In this function we are sending values to blynk server
{
  if (digitalRead(PIN_TOP_FLOAT) == 0 && (topFloatTripped) == 0) //When the Top float trips for the first time.
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_YELLOW);
    //    DRINKtotalLitres = 30;
    //    DRINKtotalMilliLitres = 30000;
    topFloatTripped = 1;
    Blynk.notify("30% Water Level Float Tripped");
    Serial.print("30% Water Level Float Tripped at ");  // Print the cumulative total of liters flowed since starting
    Serial.print(DRINKtotalLitres);

  }
  else if (digitalRead(PIN_TOP_FLOAT) == 1 && (topFloatTripped) == 1) // When it Un-Trips, ie; goes back up or sloshes
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 0 && (topFloatTripped) == 1) // Then It goes down again...
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
  }


  if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && (bottomFloatTripped) == 0)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_RED);
    //    DRINKtotalLitres = 15;
    //    DRINKtotalMilliLitres = 15000;
    bottomFloatTripped = 1;
    Blynk.notify("15% Water Level Float Tripped");
    Serial.print("15% Water Level Float Tripped at ");  // Print the cumulative total of liters flowed since starting
    Serial.print(DRINKtotalLitres);
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 1 && (bottomFloatTripped) == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
    digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && (bottomFloatTripped) == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
  }

  if (BLYNKneedsUpdate = 1) {
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);          // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);            // Displays the flow rate for this second in liters / minute (L/min)
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres);          // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);            // Displays the flow rate for this second in liters / minute (L/min)
    BLYNKneedsUpdate = 0;
  }
}

void batteryBlynk()
{
  float BatteryVoltage = (analogRead(PIN_CHASSIS_VOLTAGE)) * 0.01554955;
  Blynk.virtualWrite(V10, BatteryVoltage);
  //  if (BatteryVoltage < 12); {
  //    //Blynk.notify("Chassis Battery Below 12 Volts");
  //    Blynk.notify(BatteryVoltage);
  //  }

}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
  ArduinoOTA.setHostname(OTA_HOSTNAME);  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA

  DRINKpulseCount        = 0;
  WASHpulseCount        = 0;
  DRINKflowRate          = 0.0;
  WASHflowRate          = 0.0;
  DRINKflowMilliLitres   = 0;
  WASHflowMilliLitres   = 0;
  DRINKtotalMilliLitres  = 0;
  WASHtotalMilliLitres  = 0;
  DRINKoldTime           = 0;
  WASHoldTime           = 0;
  DRINKtotalLitresold = 0;
  WASHtotalLitresold = 0;
  BLYNKneedsUpdate = 0;

  pinMode(BLUE_LED, OUTPUT);
  digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  pinMode(PULSE_PIN_DRINK, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT
  pinMode(PULSE_PIN_WASH, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT

  pinMode(PIN_TOP_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_TOP_FLOAT" as INPUT
  pinMode(PIN_BOTTOM_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_BOTTOM_FLOAT" as INPUT

  attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);
  attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);

  timer.setInterval(1000L, sendtoBlynk); // send values blynk server every sec (if it needs updating)
  timer.setInterval(60000L, batteryBlynk); // send values blynk server every 60 sec

}


void loop()
{

  Blynk.run();
  ArduinoOTA.handle();  // For OTA
  timer.run();
  flow();

}

I would be very grateful for any advice and would be more than willing to commission some assistance to get this going, I also have several other projects on the go that have stalled out because I’m running into problems, and would be happy to have someone on retainer to help squash bugs…

Thanks in advance,

Jason

Do the shorter time periods in Superchart show anything different?
If you’re using low resolution for your Superchart views then does switching to high resolution show anything different?

I’d enable this line:

as it will show you in your serial monitor when any Blynk disconnections/reconnections occur.

Pete.

Higher-resolution super charts show 3 sequential readings that get progressively lower over 3 minutes… I don’t have an example handy.

This just happened however, these two values just dropped and then went back up on their own, and nowhere in the code should it go back up…

I have re-enabled BLYNK_PRINT Serial and we are seeing lots of disconnects at times, this is to be expected as we are currently connected through an LTE Router due to the mobile nature of Overlanding. No correlation with liters dropping yet.

I have also commented out Blynk.syncVirtual(VPIN_TOTAL_LITERS_WASH) to see what happens.

This has me wondering if ambient temperature or climate conditions during the night can affect the tanks internal pressure… no idea if/how that would affect a flow sensor.

Another software/hardware confirmation would be to ground out both sensors, or even do so right at the GPIO connection (AKA bypass the sensors altogether)… if the issue happens regularly, then you might be able to test this in a single day.

Or, and without literally going through code line by line this is just a guess… Perhaps there is a syntax issue wherein a variable linked to one sensor is also mistakenly used in the 2nd sensor code… I personally have never made that mistake before :innocent: :rofl:

Putting some form of temporary logging right after the count increment may also help tracking, albeit in minute detail… best done when NOT expecting any action.

EG. BLYNK_LOG(WASHpulseCount); or Serial.println(WASHpulseCount); With or without some timestamps if possible… the Blynk log option should supply that.

PS, I have seen a few of your channel episodes… am admittedly mostly drawn to the “RV” :slight_smile: My motorhome only wishes it could look like that… not that it ever moves far, or at all…

I agree with @GTT that you need some temporary logging of the values that are sent to Blynk, along with a time stamp.

Your code also sends battery voltage to Blynk every 60 seconds. Is there any correlation between battery voltage readings and these blips in the water level readings?

Superchart can often produce unexpected results because of the way that it buffers readings over a 1 minute period before averaging these readings and writing the averaged value to the database.
However, I can’t see how that could be producing these results, but it is something to bear in mind when trying to make sense of the logged values compared to what is being shown in Superchart.

A couple of comments about your code…

You’re calling the flow function from your void loop, and then using a millis() calculation to see is one second has passed and the flow rate needs to be calculated.
As you’re already using a Blynk timer, it would make more sense to let the timer call this function once every second and remove calculation - or if the exact number of millis since the last reading is needed for your flow accuracy then keep this in but remove the 1 second elapsed time check.

Also, I assume that you’re using a fairly old version of the ESP core - otherwise you’d be getting ISR not in IRAM error messages and constant reboots with your existing interrupt code.
Modern versions of the ESP core require the syntax of the interrupt function name to be changed slightly and you also either need to pre-declare the ISR functions or ensure that they appear in your code before the interrupts are initialised in void setup.

If your ESP core is out of date then I wonder if your Blynk library is also out of date (the latest is 0.6.1) and whether that could be causing any issues (although that seems like a bit of a long shot).

Pete.

1 Like

I considered this, but they didn’t register any flow for dozens of hours, and then all of the sudden the water is lost at a rate 10 times that the maximum flow of the system… This is what led me to disconnect the flow meter and ground the input. I did this right at the GPIO, and I can try again with both flow meters, but because the problem is so sporadic, it takes time to recreate/document it.

Thanks, I’m filming this project for a YouTube video, but I’ve been fighting for days with this and my hair is getting longer in each clip…

Not that I can tell, I can comment that out for now to confirm that.

Understood, I was just using gauge widgets at first, but I added the superchart as an initial debug step to see when and why we’d loose half our water.

Yes, I downgraded to 2.4.2 at some point as other people cited the newer versions as having some bugs… But I have just upgraded back to 2.7.4 and can confirm I have Blynk v0.6.1

I think I have the ICACHE_RAM_ATTR in all the right places, cuz it’s working…

It seems I can’t edit my first post with the new updated code, shall I just repost it again?

I wouldn’t comment it out, I’d add it as an additional data stream in the SuperChart and see if there is a correlation.

Yes, no problem.

Pete.

Here’s what I’m running and logging now…̶I̶ ̶r̶e̶m̶e̶m̶b̶e̶r̶ ̶o̶n̶e̶ ̶o̶f̶ ̶t̶h̶e̶ ̶r̶e̶a̶s̶o̶n̶s̶ ̶I̶ ̶d̶o̶w̶n̶g̶r̶a̶d̶e̶d̶ ̶t̶o̶ ̶2̶.̶4̶.̶2̶ ̶w̶a̶s̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶I̶ ̶w̶a̶s̶ ̶s̶e̶e̶i̶n̶g̶ ̶i̶n̶p̶u̶t̶ ̶p̶i̶n̶s̶ ̶t̶r̶i̶g̶g̶e̶r̶i̶n̶g̶ ̶w̶h̶e̶n̶ ̶t̶h̶e̶y̶ ̶s̶h̶o̶u̶l̶d̶ ̶n̶o̶t̶ ̶b̶e̶, Now it’s happening with 2.4.2 too… No Idea Why, PIN_TOP_FLOAT is currently showing as LOW, tripping that code at line 192, yet the pin is very much HIGH and should not be triggering that code. If I pull the pin high or low, it registers, but then it goes back to the wrong value. I don’t know how to describe that better…

/*
  Using Code modified from:
  Blynk Flow Sensor Water Meter- Calculates Total Water Consumption.
  Source: https://github.com/pkarun/Blynk-Flow-Sensor-Water-Meter
*/

#define BLYNK_PRINT Serial           // Uncomment for debugging

#include "settings.h"
#include "secret.h"   // <<--- UNCOMMENT this before you use and change values on config.h tab

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA with ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

BlynkTimer timer;

int BLYNKneedsZero = 0;
int BLYNKneedsUpdate = 0;
int topFloatTripped = 0;
int bottomFloatTripped = 0;
volatile long DRINKpulseCount = 0;
volatile long WASHpulseCount = 0;
float DRINKflowRate;
float WASHflowRate;
unsigned int DRINKflowMilliLitres;
unsigned int WASHflowMilliLitres;
unsigned long DRINKtotalMilliLitres;
unsigned long WASHtotalMilliLitres;
float DRINKtotalLitres;
float WASHtotalLitres;
float DRINKtotalLitresold;
float WASHtotalLitresold;
unsigned long DRINKoldTime;
unsigned long WASHoldTime;


BLYNK_CONNECTED() { // runs once at device startup, once connected to server.

  Blynk.syncVirtual(VPIN_TOTAL_LITERS_DRINK); //gets last know value of virtual pin
  Blynk.syncVirtual(VPIN_TOTAL_LITERS_WASH); //gets last know value of virtual pin
}

// Restores last known liter count values from the virtual pin on the Blynk server
BLYNK_WRITE(VPIN_TOTAL_LITERS_DRINK)
{
  DRINKtotalLitresold = param.asFloat();
}

BLYNK_WRITE(VPIN_TOTAL_LITERS_WASH)
{
  WASHtotalLitresold = param.asFloat();
}

BLYNK_WRITE(VPIN_SET_DRINK) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersDrink = param.asInt();
  Serial.print("Setting Drinking Water Level to ");
  Serial.println(setLitersDrink);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, setLitersDrink);
  Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, 0);
  DRINKflowRate = 0;
  DRINKflowMilliLitres = 0;
  DRINKtotalMilliLitres = 0;
  DRINKtotalLitres = setLitersDrink;
  DRINKtotalLitresold = setLitersDrink;
  Blynk.virtualWrite(VPIN_SET_DRINK, " ");
  topFloatTripped = 0;
  bottomFloatTripped = 0;
  Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
  Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_BLUE);
}

BLYNK_WRITE(VPIN_SET_WASH) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersWASH = param.asInt();
  Serial.print("Setting Washing Water Level to ");
  Serial.println(setLitersWASH);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, setLitersWASH);
  Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, 0);
  WASHflowRate = 0;
  WASHflowMilliLitres = 0;
  WASHtotalMilliLitres = 0;
  WASHtotalLitres = setLitersWASH;
  WASHtotalLitresold = setLitersWASH;
  Blynk.virtualWrite(VPIN_SET_WASH, " ");
  //Blynk.setProperty(VPIN_TOTAL_LITERS_WASH, "color", BLYNK_YELLOW);
}

void ICACHE_RAM_ATTR DRINKpulseCounter()
{
  DRINKpulseCount++;
  Serial.print("DRINKpulseCount = ");
  Serial.println(DRINKpulseCount);
}
void ICACHE_RAM_ATTR WASHpulseCounter()
{
  WASHpulseCount++;
  Serial.print("WASHpulseCount = ");
  Serial.println(WASHpulseCount);

}

void flow()
{
  if ((millis() - DRINKoldTime) > 1000)   // Only process counters once per second
  {
    detachInterrupt(PULSE_PIN_DRINK);
    DRINKflowRate = ((1000.0 / (millis() - DRINKoldTime)) * DRINKpulseCount) / FLOW_CALIBRATION;
    DRINKoldTime = millis();
    DRINKflowMilliLitres = (DRINKflowRate / 60) * 1000;
    DRINKtotalMilliLitres += DRINKflowMilliLitres;
    DRINKtotalLitres = DRINKtotalLitresold - DRINKtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN
    unsigned int frac;

    if (DRINKflowRate > 0) {
      // Print the flow rate for this second in liters / minute
      Serial.print("Flowing: ");
      Serial.print(int(DRINKflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (DRINKflowRate - int(DRINKflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(DRINKflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Drinking Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(DRINKtotalLitres);
      Serial.println("L");
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 1;
    }
    if (DRINKflowRate == 0 & BLYNKneedsZero == 1) {
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 0;
    }

    DRINKpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

    attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output

    detachInterrupt(PULSE_PIN_WASH);
    WASHflowRate = ((1000.0 / (millis() - WASHoldTime)) * WASHpulseCount) / FLOW_CALIBRATION;
    WASHoldTime = millis();
    WASHflowMilliLitres = (WASHflowRate / 60) * 1000;
    WASHtotalMilliLitres += WASHflowMilliLitres;
    WASHtotalLitres = WASHtotalLitresold - WASHtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN

    if (WASHflowRate > 0) {

      // Print the flow rate for this second in liters/minute
      Serial.print("Flowing: ");
      Serial.print(int(WASHflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (WASHflowRate - int(WASHflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(WASHflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Washing Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(WASHtotalLitres);
      Serial.println("L");
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 1;
    }

    if (WASHflowRate == 0 & BLYNKneedsZero == 1) {
      BLYNKneedsUpdate = 1;
      BLYNKneedsZero = 0;
    }

    WASHpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

    attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output

  }

}


void sendtoBlynk()  // In this function we are sending values to blynk server
{
  if (digitalRead(PIN_TOP_FLOAT) == 0 && (topFloatTripped) == 0) //When the Top float trips for the first time.
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_YELLOW);
    //    DRINKtotalLitres = 30;
    //    DRINKtotalMilliLitres = 30000;
    topFloatTripped = 1;
    Blynk.notify("30% Water Level Float Tripped");
    Serial.print("30% Water Level Float Tripped at ");  // Print the cumulative total of liters flowed since starting
    Serial.print("Debug Point 1");

  }
  else if (digitalRead(PIN_TOP_FLOAT) == 1 && (topFloatTripped) == 1) // When it Un-Trips, ie; goes back up or sloshes
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
    Serial.print("Debug Point 2");
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 0 && (topFloatTripped) == 1) // Then It goes down again...
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
  }


  if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && (bottomFloatTripped) == 0)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_RED);
    //    DRINKtotalLitres = 15;
    //    DRINKtotalMilliLitres = 15000;
    bottomFloatTripped = 1;
    Blynk.notify("15% Water Level Float Tripped");
    Serial.print("15% Water Level Float Tripped at ");  // Print the cumulative total of liters flowed since starting
    Serial.println(DRINKtotalLitres);
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 1 && (bottomFloatTripped) == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
    digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && (bottomFloatTripped) == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
  }

  if (BLYNKneedsUpdate == 1) {
    Serial.println("Sending Values to Server");
    Serial.print("Drinking Water = ");
    Serial.println(DRINKtotalLitres);
    Serial.print("Wash Water = ");
    Serial.println(WASHtotalLitres);
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);          // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);            // Displays the flow rate for this second in liters / minute (L/min)
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres);          // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);            // Displays the flow rate for this second in liters / minute (L/min)
    BLYNKneedsUpdate = 0;
  }
}

void batteryBlynk()
{
  float BatteryVoltage = (analogRead(PIN_CHASSIS_VOLTAGE)) * 0.01554955;
  Blynk.virtualWrite(V10, BatteryVoltage);
  //  if (BatteryVoltage < 12); {
  //    //Blynk.notify("Chassis Battery Below 12 Volts");
  //    Blynk.notify(BatteryVoltage);
  //  }

}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);
  ArduinoOTA.setHostname(OTA_HOSTNAME);  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA

  DRINKpulseCount        = 0;
  WASHpulseCount        = 0;
  DRINKflowRate          = 0.0;
  WASHflowRate          = 0.0;
  DRINKflowMilliLitres   = 0;
  WASHflowMilliLitres   = 0;
  DRINKtotalMilliLitres  = 0;
  WASHtotalMilliLitres  = 0;
  DRINKoldTime           = 0;
  WASHoldTime           = 0;
  DRINKtotalLitresold = 0;
  WASHtotalLitresold = 0;
  BLYNKneedsUpdate = 0;

  pinMode(BLUE_LED, OUTPUT);
  digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  pinMode(PULSE_PIN_DRINK, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT
  pinMode(PULSE_PIN_WASH, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT

  pinMode(PIN_TOP_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_TOP_FLOAT" as INPUT
  pinMode(PIN_BOTTOM_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_BOTTOM_FLOAT" as INPUT

  attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);
  attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);

  timer.setInterval(1000L, sendtoBlynk); // send values blynk server every sec (if it needs updating)
  timer.setInterval(60000L, batteryBlynk); // send values blynk server every 60 sec

}


void loop()
{

  Blynk.run();
  ArduinoOTA.handle();  // For OTA
  timer.run();
  flow();

}

it might be useful if you shared the contents of your settings.h file, as its currently impossible to work-oit which GPIOs you’re using.

Pete.

Of course! Sorry!

                           
                           
                           /////////////////////////////////////////////////////////////////
                          //                           Settings                          //
                         /////////////////////////////////////////////////////////////////

                    
/***************************************************
 *      Hardware Settings
 **************************************************/

#define PIN_CHASSIS_VOLTAGE      A0
#define PULSE_PIN_DRINK      D7
#define PULSE_PIN_WASH       D6
#define PIN_TOP_FLOAT        D2   //Also tried just  "0" and "4" with the same results.
#define PIN_BOTTOM_FLOAT     D3
#define BLUE_LED             D4

#define BLYNK_GREEN     "#23C48E"
#define BLYNK_BLUE      "#04C0F8"
#define BLYNK_YELLOW    "#ED9D00"
#define BLYNK_RED       "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"

/***************************************************
 *        Variable Settings
 **************************************************/

//#define FLOW_CALIBRATION 8.2 
#define FLOW_CALIBRATION 18.226

 
/***************************************************
 *        Blynk Virtual Pin Assignment
 **************************************************/

#define VPIN_TOTAL_LITERS_DRINK       V21
#define VPIN_FLOW_RATE_DRINK          V22
#define VPIN_FLOW_MILLI_LITERS_DRINK  V23 /**DONT THINK THIS IS USED**/
#define VPIN_SET_DRINK                V24


#define VPIN_TOTAL_LITERS_WASH        V25
#define VPIN_FLOW_RATE_WASH           V26
#define VPIN_FLOW_MILLI_LITERS_WASH   V27 /**DONT THINK THIS IS USED**/
#define VPIN_SET_WASH                 V28

#define VPIN_TOP_FLOAT                V30
#define VPIN_BOTTOM_FLOAT             V31

/***************************************************
 *        Server Settings
 **************************************************/
      
#define OTA_HOSTNAME "Blynk Wemos Water Flow Sensors"```

Why does topFloatTripped have brackets around it?`

I also noticed that in a couple of places you are using one ampersand in an if comparison, causing C++ to do a bitwise comparison…

Is this correct?

Pete.

Hi, I’ll be very interested in the outcome . . . I have a flow rate meter attached to Wemos D1 mini with the same issue of sporadic, random increment of total flow.

I have almost identical issues with rain gauge attached to ESP32, sporadic, random increment of total rainfall.

Both are hall-effect sensors attached to interrupts.

Both worked well and reliably on the test bench, both started playing up when installed. I believe it is related to electrical noise on the interrupt signal pin/cable. When I move, re-route or isolate the cable the amount of false reading varies noticeably.

For the water flow rate the false reading used to be in the order of a few litres/day . . . I recently added some additional equipment near the sensor (powered from a common power board, cables nearby etc) and the false reading have skyrocketed to tens-of-litres/day. . .

The senor pin cables on both sensors are quite long, I believe acting as antenna for electrical noise, therefore triggering the interrupts.

My next steps are to properly shield the cables (I may use Cat6A ground at both ends) and test from there.

Have you made any physical changes to your setup and/or new/associated devices that may be inducing noise?

Good Luck.

cul
billd

Stupid mistake…

Nope, Corrected.

I’ve spent a few hours cleaning up the code, removing useless redundant lines, and adding lots of clear debug prints.

I’ve also moved it to my local Blynk server and so I’ll let it go for a few days and see what happens.

Yes, our lost water was 20 to 30 liters at a time, all in a matter of minutes, faster than the water could possibly spin the flow meter.

Our flowmeters are connected directly to the GPIO, 4" or 10cm wire length, so I doubt that’s our problem.

I still kind of think it was the Blynk Server, and as I understand it they have a few on a CDN - So if the client connects to the wrong one or a different one it could get a crazy wrong / old number…

Like I said above, I made myself a local Blynk server and I’m working on a python script to scrape the values from my server and post it to the Blynk Cloud… I really just needed to get this done and get the YouTube video posted…

That’s not how it works.
There are 3 cloud servers, in New York, Frankfurt and Singapore. Your Blynk project only exists on one of these, and if your DNS server happens to resolve to the wrong on (either because you’ve travelled to a different part of the world, or your ISP is doing weird stuff), Blynk will redirect your connection request to the correct server.

Pete.

Cool, I stand happily corrected.

So I thought I’d licked it by switching to the local Blynk server… it seemed to work fine enough for a couple of days, but then this morning, I got up and turned on the screen, watching the serial debug data, and filled a kettle with water for coffee.

Note that the last water I used was last night at 18:15:18, Then at 03:35:28 it needed to reconnect to the server and it grabbed the last known values which were correct - I was happy with this and went ahead filling the kettle.

[18:15:17:851] Drinking Water Remaining: 35.76L␍␊
[18:15:18:360] Sending Values to Server␍␊
[18:15:18:360] Drinking Water = 35.76␍␊
[18:15:18:394] Wash Water = 23.50␍␊
[03:35:28:124] [60109974] Connecting to 192.168.10.100:8080␍␊
[03:35:28:158] [60109984] Ready (ping: 4ms).␍␊
[03:35:28:272] Retriving levels from server␍␊
[03:35:28:272] 35.76␍␊
[03:35:28:290] 23.50␍␊

Made the coffee and started getting camera gear ready to film this video, sipping on my coffee when out of the corner of my eye I see debug lines being written to the screen…

[07:48:40:590] Sending Values to Server␍␊
[07:48:40:590] Drinking Water = 34.79␍␊
[07:48:40:622] Wash Water = 22.47␍␊
[08:01:19:091] [76060541] Connecting to 192.168.10.100:8080␍␊
[08:01:19:125] [76060550] Ready (ping: 5ms).␍␊
[08:01:19:239] Retriving levels from server␍␊
[08:01:19:239] 34.79␍␊
[08:01:19:255] 22.47␍␊
[08:02:24:823] [76126271] Connecting to 192.168.10.100:8080␍␊
[08:02:24:857] [76126280] Ready (ping: 5ms).␍␊
[08:02:24:971] Retriving levels from server␍␊
[08:02:24:971] 33.82␍␊
[08:02:24:999] 21.43␍␊
[08:26:45:636] [77587045] Connecting to 192.168.10.100:8080␍␊
[08:26:45:663] [77587080] Ready (ping: 21ms).␍␊
[08:26:45:804] Retriving levels from server␍␊
[08:26:45:804] 32.85␍␊
[08:26:45:823] 20.40␍␊
[08:32:21:319] [77922726] Connecting to 192.168.10.100:8080␍␊
[08:32:21:353] [77922738] Ready (ping: 6ms).␍␊
[08:32:21:469] Retriving levels from server␍␊
[08:32:21:469] 31.89␍␊
[08:32:21:487] 19.37␍␊
[08:33:12:072] [77973478] Connecting to 192.168.10.100:8080␍␊
[08:33:12:106] [77973508] Ready (ping: 20ms).␍␊
[08:33:12:242] Retriving levels from server␍␊
[08:33:12:242] 30.92␍␊
[08:33:12:259] 18.34␍␊

I didn’t notice the events at 08:01, but at 08:26-33 I’m standing there watching it reconnecting to the server, and every time it’s lost a ~1ℓ of water from the count.

I’ve included the complete log from last night at 18:15 till now below, You can see I’ve got the DRINKpulseCount logging every pulse to the screen and it wasn’t seeing any flow - it’s only when it reconnects to the server that the level magically decreases. (although I have had it increase too, as I’ve mentioned before.)

18:15:16:921] Drinking Water =DRINKpulseCount = 1␍␊
[18:15:16:954]  35.76␍␊
[18:15:16:987] Wash Water = 23.50␍␊
[18:15:16:987] DRINKpulseCount = 2␍␊
[18:15:17:021] DRINKpulseCount = 3␍␊
[18:15:17:118] DRINKpulseCount = 4␍␊
[18:15:17:297] DRINKpulseCount = 5␍␊
[18:15:17:361] Sending Values to Server␍␊
[18:15:17:361] Drinking Water = 35.76␍␊
[18:15:17:394] Wash Water = 23.50␍␊
[18:15:17:645] DRINKpulseCount = 6␍␊
[18:15:17:817] Flowing: 0.3L/min␍␊
[18:15:17:817] Flowing: 5mL/Sec␍␊
[18:15:17:851] Drinking Water Remaining: 35.76L␍␊
[18:15:18:360] Sending Values to Server␍␊
[18:15:18:360] Drinking Water = 35.76␍␊literish
[18:15:18:394] Wash Water = 23.50␍␊
[03:35:28:124] [60109974] Connecting to 192.168.10.100:8080␍␊
[03:35:28:158] [60109984] Ready (ping: 4ms).␍␊
[03:35:28:272] Retriving levels from server␍␊
[03:35:28:272] 35.76␍␊
[03:35:28:290] 23.50␍␊
[07:48:29:010] DRINKpulseCount = 1␍␊
[07:48:29:043] DRINKpulseCount = 2␍␊
[07:48:29:043] DRINKpulseCount = 3␍␊
[07:48:29:076] DRINKpulseCount = 4␍␊
[07:48:29:076] DRINKpulseCount = 5␍␊
[07:48:29:110] DRINKpulseCount = 6␍␊
[07:48:29:144] DRINKpulseCount = 7␍␊
[07:48:29:144] DRINKpulseCount = 8␍␊
[07:48:29:177] DRINKpulseCount = 9␍␊
[07:48:29:209] DRINKpulseCount = 10␍␊
[07:48:29:209] DRINKpulseCount = 11␍␊
[07:48:29:243] DRINKpulseCount = 12␍␊
[07:48:29:277] DRINKpulseCount = 13␍␊
[07:48:29:310] DRINKpulseCount = 14␍␊
[07:48:29:310] DRINKpulseCount = 15␍␊
[07:48:29:344] DRINKpulseCount = 16␍␊
[07:48:29:376] Flowing: 0.8L/min␍␊
[07:48:29:376] Flowing: 14mL/Sec␍␊
[07:48:29:410] Drinking Water Remaining: 35.02L␍␊
[07:48:29:443] DRINKpulseCount = 1␍␊
[07:48:29:443] DRINKpulseCount = 2␍␊
[07:48:29:477] DRINKpulseCount = 3␍␊
[07:48:29:510] DRINKpulseCount = 4␍␊
[07:48:29:510] DRINKpulseCount = 5␍␊
[07:48:29:544] DRINKpulseCount = 6␍␊
[07:48:29:576] DRINKpulseCount = 7␍␊
[07:48:29:576] DRINKpulseCount = 8␍␊
[07:48:29:610] DRINKpulseCount = 9␍␊
[07:48:29:644] DRINKpulseCount = 10␍␊
[07:48:29:644] DRINKpulseCount = 11␍␊
[07:48:29:676] DRINKpulseCount = 12␍␊
[07:48:29:711] Sending DRINKpulseCount = 13␍␊
[07:48:29:743] DRINKpulseCount = 14␍␊
[07:48:29:743] DRINKpulseCount = 15␍␊
[07:48:29:777] ValuDRINKpulseCount = 16␍␊
[07:48:29:810] DRINKpulseCount = 17␍␊
[07:48:29:844] DRINKpulseCount = 18␍␊
[07:48:29:844] es tDRINKpulseCount = 19␍␊
[07:48:29:876] DRINKpulseCount = 20␍␊
[07:48:29:910] DRINKpulseCount = 21␍␊
[07:48:29:910] o SeDRINKpulseCount = 22␍␊
[07:48:29:943] DRINKpulseCount = 23␍␊
[07:48:29:977] DRINKpulseCount = 24␍␊
[07:48:30:010] rverDRINKpulseCount = 25␍␊
[07:48:30:010] DRINKpulseCount = 26␍␊
[07:48:30:043] DRINKpulseCount = 27␍␊
[07:48:30:077] ␍␊
[07:48:30:077] DrDRINKpulseCount = 28␍␊
[07:48:30:110] DRINKpulseCount = 29␍␊
[07:48:30:110] DRINKpulseCount = 30␍␊
[07:48:30:144] inkinDRINKpulseCount = 31␍␊
[07:48:30:176] DRINKpulseCount = 32␍␊
[07:48:30:210] g Water DRINKpulseCount = 33␍␊
[07:48:30:244] DRINKpulseCount = 34␍␊
[07:48:30:244] DRINKpulseCount = 35␍␊
[07:48:30:277] = 35.DRINKpulseCount = 36␍␊
[07:48:30:311] DRINKpulseCount = 37␍␊
[07:48:30:311] DRINKpulseCount = 38␍␊
[07:48:30:343] 02␍␊
[07:48:30:343] DRINKpulseCount = 39␍␊
[07:48:30:377] DRINKpulseCount = 40␍␊
[07:48:30:410] DRINKpulseCount = 41␍␊
[07:48:30:410] WashDRINKpulseCount = 42␍␊
[07:48:30:443] DRINKpulseCount = 43␍␊
[07:48:30:476] DRINKpulseCount = 44␍␊
[07:48:30:476]  WateDRINKpulseCount = 45␍␊
[07:48:30:510] DRINKpulseCount = 46␍␊
[07:48:30:543] DRINKpulseCount = 47␍␊
[07:48:30:577] r = DRINKpulseCount = 48␍␊
[07:48:30:609] DRINKpulseCount = 49␍␊
[07:48:30:609] DRINKpulseCount = 50␍␊
[07:48:30:643] 22.47DRINKpulseCount = 51␍␊
[07:48:30:676] DRINKpulseCount = 52␍␊
[07:48:30:676] DRINKpulseCount = 53␍␊
[07:48:30:710] ␍␊
[07:48:30:710] DRINKpulseCount = 54␍␊
[07:48:30:744] DRINKpulseCount = 55␍␊
[07:48:30:776] DRINKpulseCount = 56␍␊
[07:48:30:776] DRINKpulseCount = 57␍␊
[07:48:30:810] DRINKpulseCount = 58␍␊
[07:48:30:843] DRINKpulseCount = 59␍␊
[07:48:30:843] DRINKpulseCount = 60␍␊
[07:48:30:877] DRINKpulseCount = 61␍␊
[07:48:30:910] DRINKpulseCount = 62␍␊
[07:48:30:910] DRINKpulseCount = 63␍␊
[07:48:30:944] DRINKpulseCount = 64␍␊
[07:48:30:976] DRINKpulseCount = 65␍␊
[07:48:30:976] DRINKpulseCount = 66␍␊
[07:48:31:010] DRINKpulseCount = 67␍␊
[07:48:31:044] DRINKpulseCount = 68␍␊
[07:48:31:044] Flowing: 2.2L/min␍␊
[07:48:31:077] Flowing: 38mL/Sec␍␊
[07:48:31:110] Drinking Water Remaining: 34.99L␍␊
[07:48:31:143] SendiDRINKpulseCount = 1␍␊
[07:48:31:177] DRINKpulseCount = 2␍␊
[07:48:31:177] DRINKpulseCount = 3␍␊
[07:48:31:210] ng ValuDRINKpulseCount = 4␍␊
[07:48:31:243] DRINKpulseCount = 5␍␊
[07:48:31:243] DRINKpulseCount = 6␍␊
[07:48:31:276] es to SDRINKpulseCount = 7␍␊
[07:48:31:310] DRINKpulseCount = 8␍␊
[07:48:31:344] DRINKpulseCount = 9␍␊
[07:48:31:344] erver␍␊
[07:48:31:344] DDRINKpulseCount = 10␍␊
[07:48:31:376] DRINKpulseCount = 11␍␊
[07:48:31:410] DRINKpulseCount = 12␍␊
[07:48:31:443] rinkDRINKpulseCount = 13␍␊
[07:48:31:443] DRINKpulseCount = 14␍␊
[07:48:31:477] DRINKpulseCount = 15␍␊
[07:48:31:509] ing DRINKpulseCount = 16␍␊
[07:48:31:543] DRINKpulseCount = 17␍␊
[07:48:31:543] DRINKpulseCount = 18␍␊
[07:48:31:577] WaterDRINKpulseCount = 19␍␊
[07:48:31:610] DRINKpulseCount = 20␍␊
[07:48:31:610] DRINKpulseCount = 21␍␊
[07:48:31:644]  = 3DRINKpulseCount = 22␍␊
[07:48:31:676] DRINKpulseCount = 23␍␊
[07:48:31:710] DRINKpulseCount = 24␍␊
[07:48:31:710] 4.99DRINKpulseCount = 25␍␊
[07:48:31:743] DRINKpulseCount = 26␍␊
[07:48:31:777] DRINKpulseCount = 27␍␊
[07:48:31:809] ␍␊
[07:48:31:809] WasDRINKpulseCount = 28␍␊
[07:48:31:809] DRINKpulseCount = 29␍␊
[07:48:31:843] DRINKpulseCount = 30␍␊
[07:48:31:877] h WatDRINKpulseCount = 31␍␊
[07:48:31:910] DRINKpulseCount = 32␍␊
[07:48:31:910] DRINKpulseCount = 33␍␊
[07:48:31:944] er =DRINKpulseCount = 34␍␊
[07:48:31:976] DRINKpulseCount = 35␍␊
[07:48:31:976] DRINKpulseCount = 36␍␊
[07:48:32:010]  22.4DRINKpulseCount = 37␍␊
[07:48:32:043] DRINKpulseCount = 38␍␊
[07:48:32:077] DRINKpulseCount = 39␍␊
[07:48:32:077] 7␍␊
[07:48:32:077] DRINKpulseCount = 40␍␊
[07:48:32:109] DRINKpulseCount = 41␍␊
[07:48:32:143] DRINKpulseCount = 42␍␊
[07:48:32:176] DRINKpulseCount = 43␍␊
[07:48:32:176] DRINKpulseCount = 44␍␊
[07:48:32:210] DRINKpulseCount = 45␍␊
[07:48:32:243] DRINKpulseCount = 46␍␊
[07:48:32:243] DRINKpulseCount = 47␍␊
[07:48:32:276] DRINKpulseCount = 48␍␊
[07:48:32:310] DRINKpulseCount = 49␍␊
[07:48:32:310] DRINKpulseCount = 50␍␊
[07:48:32:343] DRINKpulseCount = 51␍␊
[07:48:32:377] DRINKpulseCount = 52␍␊
[07:48:32:377] DRINKpulseCount = 53␍␊
[07:48:32:409] DRINKpulseCount = 54␍␊
[07:48:32:443] Flowing: 2.1L/min␍␊
[07:48:32:443] Flowing: 35mL/Sec␍␊
[07:48:32:476] Drinking Water Remaining: 34.95L␍␊
[07:48:32:510] SendDRINKpulseCount = 1␍␊
[07:48:32:544] DRINKpulseCount = 2␍␊
[07:48:32:544] DRINKpulseCount = 3␍␊
[07:48:32:576] ing ValuDRINKpulseCount = 4␍␊
[07:48:32:610] DRINKpulseCount = 5␍␊
[07:48:32:643] DRINKpulseCount = 6␍␊
[07:48:32:643] es to SDRINKpulseCount = 7␍␊
[07:48:32:677] DRINKpulseCount = 8␍␊
[07:48:32:711] DRINKpulseCount = 9␍␊
[07:48:32:743] erver␍␊
[07:48:32:743] DDRINKpulseCount = 10␍␊
[07:48:32:743] DRINKpulseCount = 11␍␊
[07:48:32:789] DRINKpulseCount = 12␍␊
[07:48:32:832] rinkDRINKpulseCount = 13␍␊
[07:48:32:868] DRINKpulseCount = 14␍␊
[07:48:32:868] DRINKpulseCount = 15␍␊
[07:48:32:921] ing DRINKpulseCount = 16␍␊
[07:48:32:921] DRINKpulseCount = 17␍␊
[07:48:32:970] DRINKpulseCount = 18␍␊
[07:48:32:970] WateDRINKpulseCount = 19␍␊
[07:48:33:012] DRINKpulseCount = 20␍␊
[07:48:33:012] DRINKpulseCount = 21␍␊
[07:48:33:012] r = DRINKpulseCount = 22␍␊
[07:48:33:047] DRINKpulseCount = 23␍␊
[07:48:33:076] DRINKpulseCount = 24␍␊
[07:48:33:110] 34.9DRINKpulseCount = 25␍␊
[07:48:33:110] DRINKpulseCount = 26␍␊
[07:48:33:143] DRINKpulseCount = 27␍␊
[07:48:33:177] 5␍␊
[07:48:33:177] WaDRINKpulseCount = 28␍␊
[07:48:33:211] DRINKpulseCount = 29␍␊
[07:48:33:211] DRINKpulseCount = 30␍␊
[07:48:33:243] sh WaDRINKpulseCount = 31␍␊
[07:48:33:277] DRINKpulseCount = 32␍␊
[07:48:33:310] DRINKpulseCount = 33␍␊
[07:48:33:310] ter =DRINKpulseCount = 34␍␊
[07:48:33:344] DRINKpulseCount = 35␍␊
[07:48:33:376] DRINKpulseCount = 36␍␊
[07:48:33:376]  22.DRINKpulseCount = 37␍␊
[07:48:33:410] DRINKpulseCount = 38␍␊
[07:48:33:443] DRINKpulseCount = 39␍␊
[07:48:33:477] 47␍␊
[07:48:33:477] DRINKpulseCount = 40␍␊
[07:48:33:477] DRINKpulseCount = 41␍␊
[07:48:33:511] DRINKpulseCount = 42␍␊
[07:48:33:543] DRINKpulseCount = 43␍␊
[07:48:33:543] DRINKpulseCount = 44␍␊
[07:48:33:577] DRINKpulseCount = 45␍␊
[07:48:33:610] DRINKpulseCount = 46␍␊
[07:48:33:644] DRINKpulseCount = 47␍␊
[07:48:33:644] DRINKpulseCount = 48␍␊
[07:48:33:676] DRINKpulseCount = 49␍␊
[07:48:33:710] DRINKpulseCount = 50␍␊
[07:48:33:710] DRINKpulseCount = 51␍␊
[07:48:33:743] DRINKpulseCount = 52␍␊
[07:48:33:776] DRINKpulseCount = 53␍␊
[07:48:33:776] DRINKpulseCount = 54␍␊
[07:48:33:810] Flowing: 2.1L/min␍␊
[07:48:33:843] Flowing: 35mL/Sec␍␊
[07:48:33:843] Drinking Water Remaining: 34.92L␍␊
[07:48:33:877] SendiDRINKpulseCount = 1␍␊
[07:48:33:910] DRINKpulseCount = 2␍␊
[07:48:33:944] DRINKpulseCount = 3␍␊
[07:48:33:944] ng ValuDRINKpulseCount = 4␍␊
[07:48:33:978] DRINKpulseCount = 5␍␊
[07:48:34:010] DRINKpulseCount = 6␍␊
[07:48:34:043] es to SeDRINKpulseCount = 7␍␊
[07:48:34:076] DRINKpulseCount = 8␍␊
[07:48:34:076] DRINKpulseCount = 9␍␊
[07:48:34:110] rver␍␊
[07:48:34:110] DrDRINKpulseCount = 10␍␊
[07:48:34:143] DRINKpulseCount = 11␍␊
[07:48:34:143] DRINKpulseCount = 12␍␊
[07:48:34:177] inkiDRINKpulseCount = 13␍␊
[07:48:34:209] DRINKpulseCount = 14␍␊
[07:48:34:243] DRINKpulseCount = 15␍␊
[07:48:34:243] ng WaDRINKpulseCount = 16␍␊
[07:48:34:276] DRINKpulseCount = 17␍␊
[07:48:34:310] DRINKpulseCount = 18␍␊
[07:48:34:344] ter =DRINKpulseCount = 19␍␊
[07:48:34:344] DRINKpulseCount = 20␍␊
[07:48:34:377] DRINKpulseCount = 21␍␊
[07:48:34:411]  34.DRINKpulseCount = 22␍␊
[07:48:34:443] DRINKpulseCount = 23␍␊
[07:48:34:443] DRINKpulseCount = 24␍␊
[07:48:34:477] 92␍␊
[07:48:34:477] WDRINKpulseCount = 25␍␊
[07:48:34:510] DRINKpulseCount = 26␍␊
[07:48:34:510] DRINKpulseCount = 27␍␊
[07:48:34:544] ash WaDRINKpulseCount = 28␍␊
[07:48:34:576] DRINKpulseCount = 29␍␊
[07:48:34:610] DRINKpulseCount = 30␍␊
[07:48:34:610] ter DRINKpulseCount = 31␍␊
[07:48:34:643] DRINKpulseCount = 32␍␊
[07:48:34:677] DRINKpulseCount = 33␍␊
[07:48:34:711] = 22.DRINKpulseCount = 34␍␊
[07:48:34:711] DRINKpulseCount = 35␍␊
[07:48:34:743] DRINKpulseCount = 36␍␊
[07:48:34:777] 47␍␊
[07:48:34:777] DRINKpulseCount = 37␍␊
[07:48:34:810] DRINKpulseCount = 38␍␊
[07:48:34:810] DRINKpulseCount = 39␍␊
[07:48:34:844] DRINKpulseCount = 40␍␊
[07:48:34:876] DRINKpulseCount = 41␍␊
[07:48:34:876] DRINKpulseCount = 42␍␊
[07:48:34:910] DRINKpulseCount = 43␍␊
[07:48:34:943] DRINKpulseCount = 44␍␊
[07:48:34:943] DRINKpulseCount = 45␍␊
[07:48:34:977] DRINKpulseCount = 46␍␊
[07:48:35:010] DRINKpulseCount = 47␍␊
[07:48:35:043] DRINKpulseCount = 48␍␊
[07:48:35:043] DRINKpulseCount = 49␍␊
[07:48:35:077] DRINKpulseCount = 50␍␊
[07:48:35:110] DRINKpulseCount = 51␍␊
[07:48:35:110] Flowing: 2.1L/min␍␊
[07:48:35:144] Flowing: 35mL/Sec␍␊
[07:48:35:144] Drinking Water Remaining: 34.88L␍␊
[07:48:35:210] SendinDRINKpulseCount = 1␍␊
[07:48:35:210] DRINKpulseCount = 2␍␊
[07:48:35:243] DRINKpulseCount = 3␍␊
[07:48:35:277] DRINKpulseCount = 4␍␊
[07:48:35:277] g ValDRINKpulseCount = 5␍␊
[07:48:35:309] DRINKpulseCount = 6␍␊
[07:48:35:343] DRINKpulseCount = 7␍␊
[07:48:35:343] ues to SDRINKpulseCount = 8␍␊
[07:48:35:377] DRINKpulseCount = 9␍␊
[07:48:35:410] DRINKpulseCount = 10␍␊
[07:48:35:444] erver␍␊
[07:48:35:444] DRINKpulseCount = 11␍␊
[07:48:35:476] DRINKpulseCount = 12␍␊
[07:48:35:476] DRINKpulseCount = 13␍␊
[07:48:35:510] DrinkDRINKpulseCount = 14␍␊
[07:48:35:543] DRINKpulseCount = 15␍␊
[07:48:35:577] DRINKpulseCount = 16␍␊
[07:48:35:577] ing WDRINKpulseCount = 17␍␊
[07:48:35:609] DRINKpulseCount = 18␍␊
[07:48:35:643] DRINKpulseCount = 19␍␊
[07:48:35:643] ater DRINKpulseCount = 20␍␊
[07:48:35:677] DRINKpulseCount = 21␍␊
[07:48:35:710] DRINKpulseCount = 22␍␊
[07:48:35:744] = 34.DRINKpulseCount = 23␍␊
[07:48:35:744] DRINKpulseCount = 24␍␊
[07:48:35:776] DRINKpulseCount = 25␍␊
[07:48:35:810] 88␍␊
[07:48:35:810] WDRINKpulseCount = 26␍␊
[07:48:35:843] DRINKpulseCount = 27␍␊
[07:48:35:843] DRINKpulseCount = 28␍␊
[07:48:35:876] ash WDRINKpulseCount = 29␍␊
[07:48:35:909] DRINKpulseCount = 30␍␊
[07:48:35:943] DRINKpulseCount = 31␍␊
[07:48:35:943] aterDRINKpulseCount = 32␍␊
[07:48:35:977] DRINKpulseCount = 33␍␊
[07:48:36:010] DRINKpulseCount = 34␍␊
[07:48:36:010]  = 22DRINKpulseCount = 35␍␊
[07:48:36:043] DRINKpulseCount = 36␍␊
[07:48:36:076] DRINKpulseCount = 37␍␊
[07:48:36:110] .47␍␊
[07:48:36:110] DRINKpulseCount = 38␍␊
[07:48:36:143] DRINKpulseCount = 39␍␊
[07:48:36:143] DRINKpulseCount = 40␍␊
[07:48:36:177] DRINKpulseCount = 41␍␊
[07:48:36:209] DRINKpulseCount = 42␍␊
[07:48:36:209] DRINKpulseCount = 43␍␊
[07:48:36:243] DRINKpulseCount = 44␍␊
[07:48:36:277] DRINKpulseCount = 45␍␊
[07:48:36:277] DRINKpulseCount = 46␍␊
[07:48:36:310] DRINKpulseCount = 47␍␊
[07:48:36:343] DRINKpulseCount = 48␍␊
[07:48:36:343] DRINKpulseCount = 49␍␊
[07:48:36:377] DRINKpulseCount = 50␍␊
[07:48:36:409] DRINKpulseCount = 51␍␊
[07:48:36:409] DRINKpulseCount = 52␍␊
[07:48:36:443] Flowing: 2.1L/min␍␊
[07:48:36:476] Flowing: 35mL/Sec␍␊
[07:48:36:476] Drinking Water Remaining: 34.85L␍␊
[07:48:36:515] SendiDRINKpulseCount = 1␍␊
[07:48:36:543] DRINKpulseCount = 2␍␊
[07:48:36:576] DRINKpulseCount = 3␍␊
[07:48:36:610] ng ValueDRINKpulseCount = 4␍␊
[07:48:36:610] DRINKpulseCount = 5␍␊
[07:48:36:643] DRINKpulseCount = 6␍␊
[07:48:36:677] s to SeDRINKpulseCount = 7␍␊
[07:48:36:715] DRINKpulseCount = 8␍␊
[07:48:36:715] DRINKpulseCount = 9␍␊
[07:48:36:743] rver␍␊
[07:48:36:743] DrDRINKpulseCount = 10␍␊
[07:48:36:776] DRINKpulseCount = 11␍␊
[07:48:36:810] DRINKpulseCount = 12␍␊
[07:48:36:810] inkinDRINKpulseCount = 13␍␊
[07:48:36:844] DRINKpulseCount = 14␍␊
[07:48:36:876] DRINKpulseCount = 15␍␊
[07:48:36:876] g WatDRINKpulseCount = 16␍␊
[07:48:36:911] DRINKpulseCount = 17␍␊
[07:48:36:944] DRINKpulseCount = 18␍␊
[07:48:36:976] er = DRINKpulseCount = 19␍␊
[07:48:37:010] DRINKpulseCount = 20␍␊
[07:48:37:010] DRINKpulseCount = 21␍␊
[07:48:37:043] 34.85␍DRINKpulseCount = 22␍␊
[07:48:37:077] DRINKpulseCount = 23␍␊
[07:48:37:077] DRINKpulseCount = 24␍␊
[07:48:37:109] ␊
[07:48:37:109] WasDRINKpulseCount = 25␍␊
[07:48:37:143] DRINKpulseCount = 26␍␊
[07:48:37:176] DRINKpulseCount = 27␍␊
[07:48:37:176] h WatDRINKpulseCount = 28␍␊
[07:48:37:210] DRINKpulseCount = 29␍␊
[07:48:37:244] DRINKpulseCount = 30␍␊
[07:48:37:276] er = DRINKpulseCount = 31␍␊
[07:48:37:276] DRINKpulseCount = 32␍␊
[07:48:37:310] DRINKpulseCount = 33␍␊
[07:48:37:343] 22.47DRINKpulseCount = 34␍␊
[07:48:37:377] DRINKpulseCount = 35␍␊
[07:48:37:377] DRINKpulseCount = 36␍␊
[07:48:37:409] ␍␊
[07:48:37:409] DRINKpulseCount = 37␍␊
[07:48:37:443] DRINKpulseCount = 38␍␊
[07:48:37:443] DRINKpulseCount = 39␍␊
[07:48:37:477] DRINKpulseCount = 40␍␊
[07:48:37:510] DRINKpulseCount = 41␍␊
[07:48:37:544] DRINKpulseCount = 42␍␊
[07:48:37:544] DRINKpulseCount = 43␍␊
[07:48:37:576] DRINKpulseCount = 44␍␊
[07:48:37:610] DRINKpulseCount = 45␍␊
[07:48:37:610] DRINKpulseCount = 46␍␊
[07:48:37:643] DRINKpulseCount = 47␍␊
[07:48:37:677] DRINKpulseCount = 48␍␊
[07:48:37:677] DRINKpulseCount = 49␍␊
[07:48:37:710] DRINKpulseCount = 50␍␊
[07:48:37:743] DRINKpulseCount = 51␍␊
[07:48:37:743] DRINKpulseCount = 52␍␊
[07:48:37:776] Flowing: 2.1L/min␍␊
[07:48:37:810] Flowing: 35mL/Sec␍␊
[07:48:37:810] Drinking Water Remaining: 34.81L␍␊
[07:48:37:844] SendDRINKpulseCount = 1␍␊
[07:48:37:876] DRINKpulseCount = 2␍␊
[07:48:37:910] DRINKpulseCount = 3␍␊
[07:48:37:910] ing ValuDRINKpulseCount = 4␍␊
[07:48:37:943] DRINKpulseCount = 5␍␊
[07:48:37:977] DRINKpulseCount = 6␍␊
[07:48:38:009] es to SeDRINKpulseCount = 7␍␊
[07:48:38:043] DRINKpulseCount = 8␍␊
[07:48:38:043] DRINKpulseCount = 9␍␊
[07:48:38:077] rver␍␊
[07:48:38:077] DrDRINKpulseCount = 10␍␊
[07:48:38:110] DRINKpulseCount = 11␍␊
[07:48:38:110] DRINKpulseCount = 12␍␊
[07:48:38:144] inking WDRINKpulseCount = 13␍␊
[07:48:38:176] DRINKpulseCount = 14␍␊
[07:48:38:210] DRINKpulseCount = 15␍␊
[07:48:38:210] ater DRINKpulseCount = 16␍␊
[07:48:38:243] = 34.8DRINKpulseCount = 17␍␊
[07:48:38:277] 1␍␊
[07:48:38:277] Wash WDRINKpulseCount = 18␍␊
[07:48:38:309] ater = 22.47␍␊
[07:48:38:343] DRINKpulseCount = 19␍␊
[07:48:38:343] DRINKpulseCount = 20␍␊
[07:48:38:377] DRINKpulseCount = 21␍␊
[07:48:38:410] DRINKpulseCount = 22␍␊
[07:48:38:410] DRINKpulseCount = 23␍␊
[07:48:38:502] DRINKpulseCount = 24␍␊
[07:48:38:589] Sending Values to Server␍␊
[07:48:38:589] Drinking Water = 34.81␍␊
[07:48:38:623] Wash Water = 22.47␍␊
[07:48:38:654] DRINKpulseCount = 25␍␊
[07:48:38:736] DRINKpulseCount = 26␍␊
[07:48:38:792] Flowing: 1.2L/min␍␊
[07:48:38:792] Flowing: 21mL/Sec␍␊
[07:48:38:825] Drinking Water Remaining: 34.79L␍␊
[07:48:38:917] DRINKpulseCount = 1␍␊
[07:48:39:589] Sending Values to Server␍␊
[07:48:39:589] Drinking Water = 34.79␍␊
[07:48:39:622] Wash Water = 22.47␍␊
[07:48:39:995] Flowing: 0.0L/min␍␊
[07:48:39:995] Flowing: 0mL/Sec␍␊
[07:48:40:028] Drinking Water Remaining: 34.79L␍␊
[07:48:40:590] Sending Values to Server␍␊
[07:48:40:590] Drinking Water = 34.79␍␊
[07:48:40:622] Wash Water = 22.47␍␊
[08:01:19:091] [76060541] Connecting to 192.168.10.100:8080␍␊
[08:01:19:125] [76060550] Ready (ping: 5ms).␍␊
[08:01:19:239] Retriving levels from server␍␊
[08:01:19:239] 34.79␍␊
[08:01:19:255] 22.47␍␊
[08:02:24:823] [76126271] Connecting to 192.168.10.100:8080␍␊
[08:02:24:857] [76126280] Ready (ping: 5ms).␍␊
[08:02:24:971] Retriving levels from server␍␊
[08:02:24:971] 33.82␍␊
[08:02:24:999] 21.43␍␊
[08:26:45:636] [77587045] Connecting to 192.168.10.100:8080␍␊
[08:26:45:663] [77587080] Ready (ping: 21ms).␍␊
[08:26:45:804] Retriving levels from server␍␊
[08:26:45:804] 32.85␍␊
[08:26:45:823] 20.40␍␊
[08:32:21:319] [77922726] Connecting to 192.168.10.100:8080␍␊
[08:32:21:353] [77922738] Ready (ping: 6ms).␍␊
[08:32:21:469] Retriving levels from server␍␊
[08:32:21:469] 31.89␍␊
[08:32:21:487] 19.37␍␊
[08:33:12:072] [77973478] Connecting to 192.168.10.100:8080␍␊
[08:33:12:106] [77973508] Ready (ping: 20ms).␍␊
[08:33:12:242] Retriving levels from server␍␊
[08:33:12:242] 30.92␍␊
[08:33:12:259] 18.34␍␊

Here is the current code:

/*
  Using Code modified from:
  Blynk Flow Sensor Water Meter- Calculates Total Water Consumption.
  Source: https://github.com/pkarun/Blynk-Flow-Sensor-Water-Meter
*/

#define BLYNK_PRINT Serial           // Uncomment for debugging

#include "settings.h"
#include "secret.h"   // <<--- UNCOMMENT this before you use and change values on config.h tab

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA with ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

BlynkTimer timer;
bool BLYNKneedsZero = 0;
int topFloatTripped = 0;
int bottomFloatTripped = 0;
volatile long DRINKpulseCount = 0;
volatile long WASHpulseCount = 0;
float DRINKflowRate;
float WASHflowRate;
unsigned int DRINKflowMilliLitres;
unsigned int WASHflowMilliLitres;
unsigned long DRINKtotalMilliLitres;
unsigned long WASHtotalMilliLitres;
float DRINKtotalLitres;
float WASHtotalLitres;
float DRINKtotalLitresold;
float WASHtotalLitresold;
unsigned long DRINKoldTime;
unsigned long WASHoldTime;


BLYNK_CONNECTED() { // runs once at device startup, once connected to server.

  Blynk.syncVirtual(VPIN_TOTAL_LITERS_DRINK, VPIN_TOTAL_LITERS_WASH); //gets last know value of virtual pins
}

// Restores last known liter count values from the virtual pin on the Blynk server
BLYNK_WRITE(VPIN_TOTAL_LITERS_DRINK)
{
  DRINKtotalLitresold = param.asFloat();
  Serial.println("Retriving levels from server");
  Serial.println(DRINKtotalLitresold);

}

BLYNK_WRITE(VPIN_TOTAL_LITERS_WASH)
{
  WASHtotalLitresold = param.asFloat();
  Serial.println(WASHtotalLitresold);
}

BLYNK_WRITE(VPIN_SET_DRINK) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersDrink = param.asInt();
  Serial.print("Setting Drinking Water Level to ");
  Serial.println(setLitersDrink);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, setLitersDrink);
  DRINKtotalLitres = setLitersDrink;
  DRINKtotalLitresold = setLitersDrink;
  Blynk.virtualWrite(VPIN_SET_DRINK, " ");
  topFloatTripped = 0;
  bottomFloatTripped = 0;
  Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
  Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_BLUE);
}

BLYNK_WRITE(VPIN_SET_WASH) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersWASH = param.asInt();
  Serial.print("Setting Washing Water Level to ");
  Serial.println(setLitersWASH);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, setLitersWASH);
  WASHtotalLitres = setLitersWASH;
  WASHtotalLitresold = setLitersWASH;
  Blynk.virtualWrite(VPIN_SET_WASH, " ");
}

void ICACHE_RAM_ATTR DRINKpulseCounter()
{
  DRINKpulseCount++;
  Serial.print("DRINKpulseCount = ");
  Serial.println(DRINKpulseCount);
}
void ICACHE_RAM_ATTR WASHpulseCounter()
{
  WASHpulseCount++;
  Serial.print("WASHpulseCount = ");
  Serial.println(WASHpulseCount);
}

void flow()
{
  if ((millis() - DRINKoldTime) > 1000)   // Only process counters once per second
  {
    detachInterrupt(PULSE_PIN_DRINK);
    DRINKflowRate = ((1000.0 / (millis() - DRINKoldTime)) * DRINKpulseCount) / FLOW_CALIBRATION;
    DRINKoldTime = millis();
    DRINKflowMilliLitres = (DRINKflowRate / 60) * 1000;
    DRINKtotalMilliLitres += DRINKflowMilliLitres;
    DRINKtotalLitres = DRINKtotalLitresold - DRINKtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN
    unsigned int frac;

    if (DRINKflowRate > 0) {
      // Print the flow rate for this second in liters / minute
      Serial.print("Flowing: ");
      Serial.print(int(DRINKflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (DRINKflowRate - int(DRINKflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(DRINKflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Drinking Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(DRINKtotalLitres);
      Serial.println("L");
    }

    DRINKpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

    attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output

    detachInterrupt(PULSE_PIN_WASH);
    WASHflowRate = ((1000.0 / (millis() - WASHoldTime)) * WASHpulseCount) / FLOW_CALIBRATION;
    WASHoldTime = millis();
    WASHflowMilliLitres = (WASHflowRate / 60) * 1000;
    WASHtotalMilliLitres += WASHflowMilliLitres;
    WASHtotalLitres = WASHtotalLitresold - WASHtotalMilliLitres * 0.001; // CHANGED THIS TO SUBTRACT AS WE WANT TO COUNT DOWN

    if (WASHflowRate > 0) {

      // Print the flow rate for this second in liters/minute
      Serial.print("Flowing: ");
      Serial.print(int(WASHflowRate));  // Print the integer part of the variable

      Serial.print(".");             // Print the decimal point
      frac = (WASHflowRate - int(WASHflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
      Serial.print(frac, DEC) ;      // Print the fractional part of the variable
      Serial.println("L/min");

      Serial.print("Flowing: ");  // Print the number of liters flowed in this second
      Serial.print(WASHflowMilliLitres);
      Serial.println("mL/Sec");

      Serial.print("Washing Water Remaining: ");  // Print the cumulative total of liters flowed since starting
      Serial.print(WASHtotalLitres);
      Serial.println("L");
    }

    WASHpulseCount = 0;  // Reset the pulse counter so we can start incrementing again
    attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);    // Enable the interrupt again now that we've finished sending output
  }
}

void sendtoBlynk()  // In this function we are sending values to blynk server
{
  if (digitalRead(PIN_TOP_FLOAT) == 0 && topFloatTripped == 0) //When the Top float trips for the first time.
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_YELLOW);
    DRINKtotalLitres = 19;
    DRINKtotalLitresold = 19;
    topFloatTripped = 1;
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);          //update new water level
    Blynk.notify("30% Water Level Float Tripped");
    Serial.print("30% Water Level Float Tripped at ");  // Print the cumulative total of liters flowed since starting
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 1 && topFloatTripped == 1) // When it Un-Trips, ie; goes back up or sloshes
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 0 && topFloatTripped == 1) // Then It goes down again...
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
  }

  if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && bottomFloatTripped == 0)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_RED);
    DRINKtotalLitres = 10;
    DRINKtotalLitresold = 10;
    bottomFloatTripped = 1;
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);   //update new water level
    Blynk.notify("15% Water Level Float Tripped");
    Serial.print("15% Water Level Float Tripped at ");  // Print the liters it thought was remaining when the float tripped.
    Serial.println(DRINKtotalLitres);
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 1 && bottomFloatTripped == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
    digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && bottomFloatTripped == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
  }

  if (WASHflowRate != 0 || DRINKflowRate != 0) {
    Serial.println("Sending Values to Server");
    Serial.print("Drinking Water = ");
    Serial.println(DRINKtotalLitres);
    Serial.print("Wash Water = ");
    Serial.println(WASHtotalLitres);
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);  // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);     // Displays the flow rate for this second in liters / minute (L/min)
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres); // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);  // Displays the flow rate for this second in liters / minute (L/min)
    BLYNKneedsZero = 1;
  }
  if (WASHflowRate == 0 && DRINKflowRate == 0 && BLYNKneedsZero == 1) {
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);   // Sends Zeros for the flow rates to make the interface nice.
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);
    BLYNKneedsZero = 0;
  }
}

void CronJob1Min()
{
  float BatteryVoltage = (analogRead(PIN_CHASSIS_VOLTAGE)) * 0.01554955;
  Blynk.virtualWrite(V10, BatteryVoltage);
//  if (BatteryVoltage < 12); {
//    //Blynk.notify("Chassis Battery Below 12 Volts");
//    //Blynk.notify(BatteryVoltage);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres); //Updating server once a minute to keep the chart nice
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres); //Updating server once a minute to keep the chart nice
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS, SERVER, PORT);
  ArduinoOTA.setHostname(OTA_HOSTNAME);  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA

  pinMode(BLUE_LED, OUTPUT);
  digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  pinMode(PULSE_PIN_DRINK, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT
  pinMode(PULSE_PIN_WASH, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT

  pinMode(PIN_TOP_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_TOP_FLOAT" as INPUT
  pinMode(PIN_BOTTOM_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_BOTTOM_FLOAT" as INPUT

  attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);
  attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);

  timer.setInterval(1000L, sendtoBlynk); // send values blynk server every sec (if it needs updating)
  timer.setInterval(60000L, CronJob1Min); // send values blynk server every 60 sec

}


void loop()
{

  Blynk.run();
  ArduinoOTA.handle();  // For OTA
  timer.run();
  flow();

}

I just tested repeatedly pressing the reset button, watching it boot, connect and get the values from the server correctly 50+ times. It must be whatever is causing it to disconnect in the first place.

I’m not really keen on your flow() function being called from your void loop. As I said before, i think it ought to be called by a timer. I think you could also simplify the logic by always writing the current values to Blynk when flow() executes.

I’m also unhappy about the way that you’re disabling and re-enabling the interrupts in flow().
The idea is that you don’t want the code execution to be diverted away from flow() by having an interrupt firing. So, to do this correctly you should be disabling both interrupts at the beginning, then reinstating them at the end of the function.

You could do this in a simpletway by using noInterrupts(); and Interrupts();

  noInterrupts();
    // your critical, time-sensitive code here
  interrupts();

Have you checked for a correlation between battery voltage and disconnections?

Pete.

I generally learn best by example and thus kept the flow() function as it was in the original code at https://github.com/pkarun/Blynk-Flow-Sensor-Water-Meter

But I think I’ve made all the changes you’ve suggested now in the below code and we’ll see if that has any effect of this issue.

Handy! Implemented!

I had it writing serial debugs for a while but it cluttered it up, so I’ve commented it out for now.

If you’d be so kind as to confirm I’ve made these changes correctly as you suggested and I hope to come back with a good report soon.

/*
  Using Code now heavily modified, but based on:
  Blynk Flow Sensor Water Meter- Calculates Total Water Consumption.
  Source: https://github.com/pkarun/Blynk-Flow-Sensor-Water-Meter
*/

#define BLYNK_PRINT Serial           // Uncomment for debugging

#include "settings.h"
#include "secret.h"   // <<--- This file contains the secret Blynk Auth code and WiFi Credentials

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA with ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

BlynkTimer timer;
bool BLYNKneedsZero = 0;
bool topFloatTripped = 0;
bool bottomFloatTripped = 0;
float DRINKflowRate;
float WASHflowRate;
float DRINKtotalLitres;
float WASHtotalLitres;
float DRINKtotalLitresold;
float WASHtotalLitresold;
unsigned int frac;
unsigned int DRINKflowMilliLitres;
unsigned int WASHflowMilliLitres;
unsigned long DRINKtotalMilliLitres;
unsigned long WASHtotalMilliLitres;
unsigned long DRINKoldTime;
unsigned long WASHoldTime;
volatile long DRINKpulseCount = 0;
volatile long WASHpulseCount = 0;

BLYNK_CONNECTED() { // runs once at device startup, once connected to server.

  Blynk.syncVirtual(VPIN_TOTAL_LITERS_DRINK, VPIN_TOTAL_LITERS_WASH); //gets last known value of virtual pins
}

// Restores last known liter count values from the virtual pin on the Blynk server
BLYNK_WRITE(VPIN_TOTAL_LITERS_DRINK)
{
  DRINKtotalLitresold = param.asFloat();
  Serial.println("Retrieving levels from server");
  Serial.println(DRINKtotalLitresold);

}

BLYNK_WRITE(VPIN_TOTAL_LITERS_WASH)
{
  WASHtotalLitresold = param.asFloat();
  Serial.println(WASHtotalLitresold);
}

BLYNK_WRITE(VPIN_SET_DRINK) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersDrink = param.asInt();
  Serial.print("Setting Drinking Water Level to ");
  Serial.println(setLitersDrink);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, setLitersDrink);
  DRINKtotalLitres = setLitersDrink;
  DRINKtotalLitresold = setLitersDrink;
  Blynk.virtualWrite(VPIN_SET_DRINK, " ");
  topFloatTripped = 0;
  bottomFloatTripped = 0;
  Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
  Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_BLUE);
}

BLYNK_WRITE(VPIN_SET_WASH) {  // Set Water Level in PUSH mode on virtual pin V24
  int setLitersWASH = param.asInt();
  Serial.print("Setting Washing Water Level to ");
  Serial.println(setLitersWASH);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, setLitersWASH);
  WASHtotalLitres = setLitersWASH;
  WASHtotalLitresold = setLitersWASH;
  Blynk.virtualWrite(VPIN_SET_WASH, " ");
}

void ICACHE_RAM_ATTR DRINKpulseCounter()
{
  DRINKpulseCount++;
  Serial.print("DRINKpulseCount = ");
  Serial.println(DRINKpulseCount);
}
void ICACHE_RAM_ATTR WASHpulseCounter()
{
  WASHpulseCount++;
  Serial.print("WASHpulseCount = ");
  Serial.println(WASHpulseCount);
}

void sendtoBlynk()
{
  noInterrupts(); // Disable the interrupts for a scoach....
  DRINKflowRate = ((1000.0 / (millis() - DRINKoldTime)) * DRINKpulseCount) / FLOW_CALIBRATION;
  DRINKoldTime = millis();
  DRINKflowMilliLitres = (DRINKflowRate / 60) * 1000;
  DRINKtotalMilliLitres += DRINKflowMilliLitres;
  DRINKtotalLitres = DRINKtotalLitresold - DRINKtotalMilliLitres * 0.001;

  if (DRINKflowRate > 0) {
    Serial.print("Flowing: ");     // Print the flow rate for this second in liters / minute
    Serial.print(int(DRINKflowRate));  // Print the integer part of the variable
    Serial.print(".");             // Print the decimal point
    frac = (DRINKflowRate - int(DRINKflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    Serial.print(frac, DEC) ;      // Print the fractional part of the variable
    Serial.println("L/min");
    Serial.print("Flowing: ");  // Print the number of mL flowed in this second
    Serial.print(DRINKflowMilliLitres);
    Serial.println("mL/Sec");
    Serial.print("Drinking Water Remaining: ");  // Print the drinking water remaining
    Serial.print(DRINKtotalLitres);
    Serial.println("L");
  }
  DRINKpulseCount = 0;  // Reset the pulse counter so we can start incrementing again


  // Now we check if the wash water is flowing...
  WASHflowRate = ((1000.0 / (millis() - WASHoldTime)) * WASHpulseCount) / FLOW_CALIBRATION;
  WASHoldTime = millis();
  WASHflowMilliLitres = (WASHflowRate / 60) * 1000;
  WASHtotalMilliLitres += WASHflowMilliLitres;
  WASHtotalLitres = WASHtotalLitresold - WASHtotalMilliLitres * 0.001;

  if (WASHflowRate > 0) {
    Serial.print("Flowing: ");     // Print the flow rate for this second in liters/minute
    Serial.print(int(WASHflowRate));  // Print the integer part of the variable
    Serial.print(".");             // Print the decimal point
    frac = (WASHflowRate - int(WASHflowRate)) * 10; // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    Serial.print(frac, DEC) ;      // Print the fractional part of the variable
    Serial.println("L/min");
    Serial.print("Flowing: ");     // Print the number of mL flowed in this second
    Serial.print(WASHflowMilliLitres);
    Serial.println("mL/Sec");
    Serial.print("Washing Water Remaining: ");  // Print the wash water remaining
    Serial.print(WASHtotalLitres);
    Serial.println("L");
  }

  WASHpulseCount = 0;  // Reset the pulse counter so we can start incrementing again

  interrupts();  //Re-enable the interrupts

  // Here we check if either of the level floats have tripped and adjust the measured water levels if true.
  if (digitalRead(PIN_TOP_FLOAT) == 0 && topFloatTripped == 0) //When the Top float trips for the first time.
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_YELLOW);
    Serial.print("30% Water Level Float Tripped at ");  // Print the cumulative total measured liters remaining when the top float tripped.
    Serial.println(DRINKtotalLitres);
    Blynk.notify("30% Water Level Float Tripped");
    DRINKtotalLitres = 19;
    DRINKtotalLitresold = 19;
    topFloatTripped = 1;
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);          //update new water level
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 1 && topFloatTripped == 1) // When it Un-Trips, ie; goes back up or sloshes
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 0);
  }
  else if (digitalRead(PIN_TOP_FLOAT) == 0 && topFloatTripped == 1) // Then It goes down again...
  {
    Blynk.virtualWrite(VPIN_TOP_FLOAT, 255);
  }

  if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && bottomFloatTripped == 0)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
    Blynk.setProperty(VPIN_TOTAL_LITERS_DRINK, "color", BLYNK_RED);
    Blynk.notify("15% Water Level Float Tripped");
    Serial.print("15% Water Level Float Tripped at ");   // Print the cumulative total measured liters remaining when the bottom float tripped.
    Serial.println(DRINKtotalLitres);
    DRINKtotalLitres = 10;
    DRINKtotalLitresold = 10;
    bottomFloatTripped = 1;
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);   //update new water level
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 1 && bottomFloatTripped == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 0);
    digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  }
  else if (digitalRead(PIN_BOTTOM_FLOAT) == 0 && bottomFloatTripped == 1)
  {
    Blynk.virtualWrite(VPIN_BOTTOM_FLOAT, 255);
    digitalWrite(BLUE_LED, LOW); // LED On - Stupid LED is inverted
  }

  if (WASHflowRate != 0 || DRINKflowRate != 0) {
    Serial.println("Sending Values to Server");
    Serial.print("Drinking Water = ");
    Serial.println(DRINKtotalLitres);
    Serial.print("Wash Water = ");
    Serial.println(WASHtotalLitres);
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres);  // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);     // Displays the flow rate for this second in liters / minute (L/min)
    Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres); // Total water consumption in liters (L)
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);  // Displays the flow rate for this second in liters / minute (L/min)
    BLYNKneedsZero = 1;
  }
  if (WASHflowRate == 0 && DRINKflowRate == 0 && BLYNKneedsZero == 1) {
    Blynk.virtualWrite(VPIN_FLOW_RATE_DRINK, DRINKflowRate);   // Sends Zeros for the flow rates to make the interface nice.
    Blynk.virtualWrite(VPIN_FLOW_RATE_WASH, WASHflowRate);
    BLYNKneedsZero = 0;
  }
}

void CronJob1Min()
{
  //float BatteryVoltage = (analogRead(PIN_CHASSIS_VOLTAGE)) * 0.01554955;
  //Blynk.virtualWrite(V10, BatteryVoltage);
  //  if (BatteryVoltage < 12); {
  //    //Blynk.notify("Chassis Battery Below 12 Volts");
  //    //Blynk.notify(BatteryVoltage);
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_DRINK, DRINKtotalLitres); //Updating server once a minute to keep the chart nice
  Blynk.virtualWrite(VPIN_TOTAL_LITERS_WASH, WASHtotalLitres); //Updating server once a minute to keep the chart nice
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS, SERVER, PORT);
  ArduinoOTA.setHostname(OTA_HOSTNAME);  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA

  pinMode(BLUE_LED, OUTPUT);
  digitalWrite(BLUE_LED, HIGH); // LED Off - Stupid LED is inverted
  pinMode(PULSE_PIN_DRINK, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT
  pinMode(PULSE_PIN_WASH, INPUT_PULLUP);  // Initialization of the variable "PULSE_PIN_DRINK" as INPUT

  pinMode(PIN_TOP_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_TOP_FLOAT" as INPUT
  pinMode(PIN_BOTTOM_FLOAT, INPUT_PULLUP);  // Initialization of the variable "PIN_BOTTOM_FLOAT" as INPUT

  attachInterrupt(PULSE_PIN_DRINK, DRINKpulseCounter, FALLING);
  attachInterrupt(PULSE_PIN_WASH, WASHpulseCounter, FALLING);

  timer.setInterval(1000L, sendtoBlynk); // send values blynk server every sec (if it needs updating)
  timer.setInterval(60000L, CronJob1Min); // send values blynk server every 60 sec to keep the charts nice
}

void loop()
{
  Blynk.run();
  ArduinoOTA.handle();  // For OTA Updates
  timer.run();
}

Personally, I’d put the line that re-enables interrupts right at the bottom of the sendtoBlynk function, otherwise an interrupt could err… interrupt the execution of that function and your values might not get written to the server.

Pete.

Done!