Blynk app working, lcd connected to esp32 working strange

The Blynk App works as designed, but the first two lines on the LCD that is directly connected to the esp32 works funny.
At first it will read correctly than after 1-2 seconds the letter “T” in the word Temperature will start to blink and the readout goes to the default error of -192.60 degrees, while in the app it maintains reading the correct temperature. The flow rate and gallons will also give the proper readout in both displays, the LCD and the App.
Also the Blue Wifi Status led works as it should when starting and making connection than, no longer gives it connected slow flash.

The Super Chart says no Data in Live mode, but in 1 hour mode or any other it shows the requested data.

If all goes well, I’m going to add a total of 8 temperature sensors, with two flow sensors and three voltage dividers to give me the status of three batteries.

I’m using
Esp32 is a Wroom32
DS18B20 sensor
A flow Meter
The LCD is 4x20
The Blynk Region I’m connected to is Region NY3

    LCD at first reads correct, than letter "T" in Temperture flashes and  Sensor Locks up in LCD at "-196.60 degree's, but in the App it still reads correctly.
    setting are in Settings.h tab
    displays Temperature on Lcd and app
    displays Flow on LCD and app
ds18b20 on pin 5   sendimg to V1 pin in app
Blynk reset 1 esp
Flow Sensor PIN 27

V1 = Temperture
V21 = Flow Rate
V22 = Total Gallons
V23 = 


#define BLYNK_DEVICE_NAME           "Deluxe 11"
#define BLYNK_TEMPLATE_NAME "Delux001"
#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define FlowSensor 27
#define BLYNK_PRINT Serial
 //#define BLYNK_DEBUG

#define APP_DEBUG
#define BLYNK_PRINT Serial
#define ONE_WIRE_BUS 5
#define I2C_SDA 21
#define I2C_SCL 22

#define USE_WROVER_BOARD                                                                                        //configured a custom board in Settings.h

#include "BlynkEdgent.h"
#include <SimpleTimer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);                                                                              // set the LCD address to 0x27 for a 16 chars and 4 line display
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Probe01 = { 0x28, 0x3C, 0x13, 0x3B, 0x40, 0x21, 0x8, 0x96};

const byte FLOWSENSOR = 27;                                                                                   // sensor on digital pin sd3 (INT0)
const byte BUTTON = 1;                                                                                        // button on digital pin 3 (int1)
const byte ADDRESS = 0x27;                                                                                    // i2c address for the LCD (0x3F & 0x27 are common)

unsigned long count = 0;                                                                                      // number of pulses from flow sensor (one pulse is 1/450th of a litre)
unsigned long last_count = 0;                                                                                 // timer to track last pulse from sensor
unsigned long last_time = 0;                                                                                  // timer to track last LCD update
const int INTERVAL = 200;                                                                                     // refresh rate for screen readout
//const float COST_PER_LITRE = 0.2523;                                                                        // cost per litre, in cents, not used
//const float COST_PER_Gallon = 0.2523;                                                                       // cost per litre, in cents, not used
unsigned long debounce = 0;                                                                                   // timer for button debounce

bool mode_changed = true;                                                                                     // a flag to update the text label "Rate:" or "Cost:"
bool watering = false;                                                                                        // a flag to indicate if the shower is running
bool mode = true;                                                                                             // show flow rate if true, or cost if false

   The cent sign (¢) is not included in the default character set.
 Therefore, we must create a custom character.
 This was done with the help of this online tool:
byte cent_sign[] = {                                                                                          // this function not used

SimpleTimer timer;

                                                                                                             // temp sensor 
void getTempData()
 Blynk.virtualWrite(V1, sensors.getTempFByIndex(0));
  lcd.print ((char)223);                                                                                      //displays degree Charactor  

void setup()

 // Initialize interrupts
  attachInterrupt(digitalPinToInterrupt(FLOWSENSOR), sensor_pulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(BUTTON), button_press, FALLING);

 timer.setInterval (1000L, flow);
 timer.setInterval(1500L, getTempData);

  lcd.init();                                                                                               // initialize the lcd 
  lcd.createChar(0, cent_sign);

void flow() {

                                                                                                            // if the mode has changed, print the updated text label
  if (mode_changed) {
    lcd.setCursor(0, 3);                                                                                    // move to second line
    if (mode)
      lcd.print("Flow:           ");                                                                        // white space is to clear any extraneous characters
    //lcd.print("Cost:           ");                                                                        // white space is to clear any extraneous characters
      lcd.print("Cost:           ");                                                                        // white space is to clear any extraneous characters
    // lcd.print("Rate:           ");                                                                       // white space is to clear any extraneous characters
    mode_changed = false; // clear flag

                                                                                                            // more than INTERVAL-time has passed, so update the screen
  if (abs(millis() - last_time) > INTERVAL) {
    last_time = millis();                                                                                   // set last update time to present time
    lcd. setCursor (0, 2);
    lcd.print("Total:            ");
    lcd.setCursor(7, 2);
    lcd.print(String(count / 1803.0) + " Gals  ");                                                         // calcluate and print total gallons  ***** 1/2" meter change number to adjust readout flow
    // lcd.print(String(count / 120.5) + " Gals  ");                                                       // calcluate and print total gallons  ***** 1.5" meter   change number to adjust readout flow
    lcd.setCursor(7, 3);
    if (mode) { // flow-rate mode, display current flow rate
      lcd.print(String(1000 * (count - last_count) / 120.5 / INTERVAL) + (" Gals/s   "));

    else { // cost mode, display total cost
     // lcd.print(String(COST_PER_Gallon * count / 1803.0) + " ");                                         // ********************************  1/2'meter             change number to adjust readout flow    *****************
      lcd.print(String(COST_PER_Gallon * count / 1803.0) + " ");                                           // ********************************    1.5 " meter           change number to adjust readout flow    *****************lcd.write(byte(0)); // print cents sign (¢)
      lcd.print("   ");                                                                                    // print trailing spaces to clear extraneous chars

                                                                                                          // this is how we determine if the water is running
    if (last_count == count)
      watering = false;                                                                                   // flow is off
      watering = true;                                                                                    // flow is on

       Blynk.virtualWrite(V21, (1000 * (count - last_count) / 1803.0 / INTERVAL)  );
       Blynk.virtualWrite(V22, count / 1803.0);                                                           //1803.0 for 1\2" pipe    120.5 for 1-1\2" pipe
       Blynk.virtualWrite(V23, count);
    last_count = count;


void sensor_pulse() {
  count++;                                                                                              // increase count by one

void button_press() {
  if (abs(millis() - debounce) > 250) {                                                                 // debounce delay to prevent unwanted button presses
    debounce = millis();                                                                                // reset debounce timer
    if (watering) {                                                                                     // if water is running, the button toggles the mode
      mode = !mode;
      mode_changed = true;                                                                             // raise flag
    else {                                                                                             // if the water is off, the button clears the total
      count = 0;
      last_count = 0;

void loop() {;;


The way that you’re doing your temperature readings is badly thought-out.

This line…

and this line…

are both instructing the code to get a temperature reading from the sensor, and are most likely executed within 1ms (probably far less with an ESP32) of each other.
Sensors don’t like to be interrogated this often, so my guess is that the sensor is giving you the first reading (which goes to Blynk) and returning a NAN result for the second reading that goes to the LCD.

The approach you should adopt is to take one reading and store it in a local variable. Then, send this to Blynk then send it to the LCD display.

You do the same clunky re-calculation of your flow rate numbers too, which isnt the best approach, but something you get away with because of the ESP’s processing power.

There are lots of other messy stuff in your code - duplicated commands, unused variables, inaccurate comments, use of SimpleTimer instead of BlynkTimer, strange debounce routines etc.


Thanks for the direction to head down.