Arduino Blynk Multiple DS18B20 With High/Low Alarm

Need help to modify this sketch to implement multiple sensors. The alarm Levels should be Equal for all sensors, both high and low.

Have found the Project at: https://github.com/MLXXXp/Blynk_ESP8266_DS18B20

/*****************************************************************************
  Arduino sketch to report the temperature using an ESP8266 with connected
  Dallas DS18B20 sensor, for the Blynk system.
  http://www.blynk.cc
*****************************************************************************/

/*


#define BLYNK_DEBUG
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space

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

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "myssid";
char pass[] = "mypassword";

// Temperature sensor full ID, including family code and CRC
DeviceAddress tempSensor = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

// Alert messages
char alertMessageLow[] = "House temperature is LOW!";
char alertMessageHigh[] = "House temperature is HIGH!";

// Pin used for the OneWire interface
#define ONEWIRE_PIN 4

OneWire oneWire(ONEWIRE_PIN);
DallasTemperature sensors(&oneWire);
SimpleTimer timer;

// Current temperature is a global so it can used to reset min/max temperatures
float currentTemp = 0;

// Minimum and maximum temperatures are set to out of range values that will be
// overridden the first time the actual temperature is read.
float minTemp = 10000.0;
float maxTemp = -10000.0;

int alertTempLow, alertTempHigh;
boolean lowAlertOn = false;
boolean highAlertOn = false;


// Virtual pins to send temperature reading (from device)
#define V_PIN_TEMP_A V0 // Value - Widget must allow color change
#define V_PIN_TEMP_B V1
// Virtual pins for alert temperature set points (to device)
#define V_PIN_ALERT_LOW V2
#define V_PIN_ALERT_HIGH V3
// Virtual pins for min/max temperatures (from device)
#define V_PIN_TEMP_MIN V4
#define V_PIN_TEMP_MAX V5
// Virtual pin for min/max temperature reset (to device)
#define V_PIN_MIN_MAX_RESET V6

#undef TEMP_IN_FAHRENHEIT
// Uncomment to use Fahrenheit or comment out for Celsius
#define TEMP_IN_FAHRENHEIT

// Hysteresis in degrees for alerts
#define ALERT_HYSTERESIS 1

// Temperature reading interval, in SECONDS
#define READ_INTERVAL 60

// Check interval for network connection, in milliseconds
// This should be a bit shorter than the Blynk reconnect poll time, which
// at the time of writing was 7 seconds
#define CONNECTION_CHECK_TIME 6500

// LED flash time for link down, in milliseconds
#define LED_DISC_FLASH_TIME 2000

// LED blink rate for "sensor not found" indication, in milliseconds
#define NO_SENSOR_BLINK_SPEED 500

// LED blink time for "sensor not found" indication, in milliseconds
#define NO_SENSOR_BLINK_TIME 200

// LED flash time for successful sensor read, in milliseconds
#define LED_READ_OK_FLASH_TIME 30

// LED flash time for sensor read error, in milliseconds
#define LED_READ_ERR_FLASH_TIME 5000

// Pin for LED indicator
#define LED_PIN 2

// The number of bits of temperature resolution
// 9 = 0.5, 10 = 0.25, 11 = 0.125, 12 = 0.0625 degrees Celsius
#define TEMPERATURE_RES_BITS 10

// Temperature conversion wait time, in milliseconds
#define READ_CONV_WAIT 800

// Pin values for indicator LED on and off
#define LED_ON LOW
#define LED_OFF HIGH

// Widget colors for alerts
#define ALERT_COLOR_OK   "#23C48E" // Green
#define ALERT_COLOR_LOW  "#5F7CD8" // Dark Blue
#define ALERT_COLOR_HIGH "#D3435C" // Red

//--------------------- SETUP -------------------
void setup() {
  Serial.begin(9600);

  pinMode(LED_PIN, OUTPUT);
  indLEDoff();

  sensors.begin();
  if (!sensors.isConnected(tempSensor)) {
    while (true) {
      indLEDon();
      delay(NO_SENSOR_BLINK_TIME);
      indLEDoff();
      delay(NO_SENSOR_BLINK_SPEED - NO_SENSOR_BLINK_TIME);
    }
  }

  // Set the resolution of the temperature readings
  sensors.setResolution(tempSensor, TEMPERATURE_RES_BITS);

  // We'll do the "wait for conversion" ourselves using a timer,
  // to avoid the call to delay() that the library would use
  sensors.setWaitForConversion(false);

  // Start up Blynk
  Blynk.begin(auth, ssid, pass);

  // Start the interval timer that checks if the connection is up
  timer.setInterval(CONNECTION_CHECK_TIME, connectionCheck);

  // Start the timer that handles the temperature read interval
  timer.setInterval(READ_INTERVAL * 1000, startSensorRead);
}
//-----------------------------------------------

// Synchronize pins when connection comes up
BLYNK_CONNECTED() {
  Blynk.syncAll();
}

// Set low alert temperature
BLYNK_WRITE(V_PIN_ALERT_LOW) {
  alertTempLow = param.asInt();
}

// Set high alert temperature
BLYNK_WRITE(V_PIN_ALERT_HIGH) {
  alertTempHigh = param.asInt();
}

// Reset minimum and maximum temperatures
BLYNK_WRITE(V_PIN_MIN_MAX_RESET) {
  if (param.asInt()) { // if button pressed
    minTemp = maxTemp = currentTemp;
    Blynk.virtualWrite(V_PIN_TEMP_MIN, currentTemp);
    Blynk.virtualWrite(V_PIN_TEMP_MAX, currentTemp);
  }
}

// Blink the LED if the connection is down
void connectionCheck() {
  if (Blynk.connected()) {
    return;
  }

  indLEDon();
  delay(LED_DISC_FLASH_TIME);
  indLEDoff();
}

// Start a temperature read and the conversion wait timer
void startSensorRead() {
  if (!Blynk.connected()) {
    return;
  }

  sensors.requestTemperatures();
  timer.setTimeout(READ_CONV_WAIT, sensorRead);
}

// Read the temperature from the sensor and perform the appropriate actions
void sensorRead() {
  int16_t tempRaw;

  if (!Blynk.connected()) {
    return;
  }

  tempRaw = sensors.getTemp(tempSensor);
  if (tempRaw != DEVICE_DISCONNECTED_RAW) {
#ifdef TEMP_IN_FAHRENHEIT
    currentTemp = sensors.rawToFahrenheit(tempRaw);
#else
    currentTemp = sensors.rawToCelsius(tempRaw);
#endif

    // Send temperature value
    Blynk.virtualWrite(V_PIN_TEMP_A, currentTemp);
    Blynk.virtualWrite(V_PIN_TEMP_B, currentTemp);

    // Low temperature alerts
    if ((currentTemp <= alertTempLow) && !lowAlertOn) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_LOW);
      Blynk.notify(alertMessageLow);
      lowAlertOn = true;
    }
    else if (lowAlertOn && (currentTemp > alertTempLow + ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_OK);
      lowAlertOn = false;
    }

    // High temperature alerts
    if ((currentTemp >= alertTempHigh) && !highAlertOn) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_HIGH);
      Blynk.notify(alertMessageHigh);
      highAlertOn = true;
    }
    else if (highAlertOn && (currentTemp < alertTempHigh - ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_OK);
      highAlertOn = false;
    }

    // Minimum and maximum temperatures
    if (currentTemp < minTemp) {
      minTemp = currentTemp;
      Blynk.virtualWrite(V_PIN_TEMP_MIN, currentTemp);
    }
    if (currentTemp > maxTemp) {
      maxTemp = currentTemp;
      Blynk.virtualWrite(V_PIN_TEMP_MAX, currentTemp);
    }

    flashLED(LED_READ_OK_FLASH_TIME);
  }
  else {
    flashLED(LED_READ_ERR_FLASH_TIME);
  }
}

//--------------------- LOOP --------------------
void loop() {
  Blynk.run();
  timer.run();
}
//-----------------------------------------------

// Flash the indicator LED for the specified duration
void flashLED(long dur) {
  timer.setTimeout(dur, indLEDoff);
  indLEDon();
}

// Turn on the indicator LED
void indLEDon() {
  digitalWrite(LED_PIN, LED_ON);
}

// Turn off the indicator LED
void indLEDoff() {
  digitalWrite(LED_PIN, LED_OFF);
}

I doubt you will find anyone here to write the code for you.

What you need to do is find the portion of the code that reads the sensor, and modify it so that it reads all of the sensors you are trying to use. You will need to add the address for each sensor.

Then once you have the sensor values, compare them to the High/Low alarm values, and then take the appropriate action.

2 Likes

Thanks for the reply. I have tried many different options, but doesn’t get a proper result.

I wouldnt expect that someone would Write the code for me, but point me in the right direction.

If you, or you know someone who could Write me the code, I would pay them.

HERE is an example for reading multiple ds18b20 sensors (due note there are other ways of reading multiple ds18b20 sensors, e.g. by index).

Once you are reading each sensor, add in the checks for the HIGH/LOW alarm. For example:

void sendSensor2() {
  sensors.requestTemperatures();
  temperature2 = sensors.getTempC(tempSensor2);
  Blynk.virtualWrite(2, temperature2);
 // Low temperature alerts
    if ((temperature2 <= alertTempLow) && !lowAlertOn2) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_LOW);
      Blynk.notify(alertMessageLow);
      lowAlertOn2 = true;
    }
    else if (lowAlertOn2 && (temperature2 > alertTempLow + ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_OK);
      lowAlertOn2 = false;
    }
// High temperature alerts
    if ((temperature2 >= alertTempHigh) && !highAlertOn2) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_HIGH);
      Blynk.notify(alertMessageHigh);
      highAlertOn2 = true;
    }
    else if (highAlertOn2 && (temperature2 < alertTempHigh - ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_A, "color", ALERT_COLOR_OK);
      highAlertOn2 = false;
    }
}

The example you are working from has a lot of features. If you are not familiar with programming, I suggest you start simple and work your way up to the more advanced stuff.

1 Like

You could also try the BLYNK SEARCH

And GOOGLE

and YouTube

Have made it pretty much like that for the second sensors. Get the Reading, but the alarm doesn’t seem to work quite right.

Well show what YOU have done, maybe we can spot your error and give some advise.

2 Likes

Found some errors and did some changes. This is the final code, and it seems to work just fine. Many thanks for the help and pointing me in the right direction :slight_smile:

/*****************************************************************************
  Arduino sketch to report the temperature using an ESP8266 with connected
  Dallas DS18B20 sensor, for the Blynk system.
  http://www.blynk.cc
*****************************************************************************/

/*
Copyright (c) 2017 Scott Allen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#define BLYNK_DEBUG
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space

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

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "9c86a10eb9c94a9e863b8d3174b7daa8";
int LED20 = V20;
int LED21 = V21;
const int Relay01 = D0; //Relay Output 1 - Sirc. Pump
const int Relay02 = D1; //Relay Output 2 - Cooling Unit
const int Relay03 = D2; //Relay Output 3 - Heating Unit
const int Relay04 = D5; //Relay Output 4 - Optional

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Adriano";
char pass[] = "22022017";

// Temperature sensor full ID, including family code and CRC
DeviceAddress tempSensor01 = { 0x28, 0xEC, 0xA4, 0x6E, 0x09, 0x00, 0x00, 0x6D };
DeviceAddress tempSensor02 = { 0x28, 0xFF, 0x9D, 0xC4, 0xC4, 0x16, 0x04, 0xCE };

// Alert messages
char alertMessageLow[] = "Left Battery Bank Temp LOW!";
char alertMessageHigh[] = "Left Battery Bank Temp HIGH!";


// Pin used for the OneWire interface
#define ONEWIRE_PIN D3

OneWire oneWire(ONEWIRE_PIN);
DallasTemperature sensors(&oneWire);
SimpleTimer timer;

// Current temperature is a global so it can used to reset min/max temperatures
float currentTemp = 0;
float currentTemp02 = 0;


// Minimum and maximum temperatures are set to out of range values that will be
// overridden the first time the actual temperature is read.
float minTemp = 10000.0;
float maxTemp = -10000.0;

int alertTempLow, alertTempHigh;
boolean lowAlertOn = false;
boolean highAlertOn = false;

boolean lowAlertOn02 = false;
boolean highAlertOn02 = false;


// Virtual pins to send temperature reading (from device)
#define V_PIN_TEMP_00 V1 // Value - Widget must allow color change
#define V_PIN_TEMP_01 V0
#define V_PIN_TEMP_03 V10

// Virtual pins for alert temperature set points (to device)
#define V_PIN_ALERT_LOW V2
#define V_PIN_ALERT_HIGH V3
// Virtual pins for min/max temperatures (from device)
#define V_PIN_TEMP_MIN V4
#define V_PIN_TEMP_MAX V5
// Virtual pin for min/max temperature reset (to device)
#define V_PIN_MIN_MAX_RESET V6

#undef TEMP_IN_CELSIUS
// Uncomment to use Fahrenheit or comment out for Celsius
#define TEMP_IN_CELSIUS

// Hysteresis in degrees for alerts
#define ALERT_HYSTERESIS 1

// Temperature reading interval, in SECONDS
#define READ_INTERVAL 3

// Check interval for network connection, in milliseconds
// This should be a bit shorter than the Blynk reconnect poll time, which
// at the time of writing was 7 seconds
#define CONNECTION_CHECK_TIME 6500

// LED flash time for link down, in milliseconds
#define LED_DISC_FLASH_TIME 2000

// LED blink rate for "sensor not found" indication, in milliseconds
#define NO_SENSOR_BLINK_SPEED 500

// LED blink time for "sensor not found" indication, in milliseconds
#define NO_SENSOR_BLINK_TIME 200

// LED flash time for successful sensor read, in milliseconds
#define LED_READ_OK_FLASH_TIME 30

// LED flash time for sensor read error, in milliseconds
#define LED_READ_ERR_FLASH_TIME 5000

// Pin for LED indicator
#define LED_PIN 2

// The number of bits of temperature resolution
// 9 = 0.5, 10 = 0.25, 11 = 0.125, 12 = 0.0625 degrees Celsius
#define TEMPERATURE_RES_BITS 10

// Temperature conversion wait time, in milliseconds
#define READ_CONV_WAIT 800

// Pin values for indicator LED on and off
#define LED_ON LOW
#define LED_OFF HIGH

// Widget colors for alerts
#define ALERT_COLOR_OK   "#23C48E" // Green
#define ALERT_COLOR_LOW  "#04C0F8" // Blue
#define ALERT_COLOR_HIGH "#D3435C" // Red

//--------------------- SETUP -------------------
void setup() {
  Serial.begin(9600);

  pinMode(LED_PIN, OUTPUT);
  pinMode(Relay01, OUTPUT);
  pinMode(Relay02, OUTPUT);
  pinMode(Relay03, OUTPUT);
  pinMode(Relay04, OUTPUT);
  indLEDoff();

  sensors.begin();
  if (!sensors.isConnected(tempSensor01))
  if (!sensors.isConnected(tempSensor02))
  {
    while (true) {
      indLEDon();
      delay(NO_SENSOR_BLINK_TIME);
      indLEDoff();
      delay(NO_SENSOR_BLINK_SPEED - NO_SENSOR_BLINK_TIME);
    }
  }

  // Set the resolution of the temperature readings
  sensors.setResolution(tempSensor01, TEMPERATURE_RES_BITS);
  sensors.setResolution(tempSensor02, TEMPERATURE_RES_BITS);

  // We'll do the "wait for conversion" ourselves using a timer,
  // to avoid the call to delay() that the library would use
  sensors.setWaitForConversion(false);

  // Start up Blynk
  Blynk.begin(auth, ssid, pass);

  // Start the interval timer that checks if the connection is up
  timer.setInterval(CONNECTION_CHECK_TIME, connectionCheck);

  // Start the timer that handles the temperature read interval
  timer.setInterval(READ_INTERVAL * 1000, startSensorRead01);
  timer.setInterval(READ_INTERVAL * 1000, startSensorRead02);
}
//-----------------------------------------------

// Synchronize pins when connection comes up
BLYNK_CONNECTED() {
  Blynk.syncAll();
}

// Set low alert temperature
BLYNK_WRITE(V_PIN_ALERT_LOW) {
  alertTempLow = param.asInt();
}

// Set high alert temperature
BLYNK_WRITE(V_PIN_ALERT_HIGH) {
  alertTempHigh = param.asInt();
}

// Reset minimum and maximum temperatures
BLYNK_WRITE(V_PIN_MIN_MAX_RESET) {
  if (param.asInt()) { // if button pressed
    minTemp = maxTemp = currentTemp;
    Blynk.virtualWrite(V_PIN_TEMP_MIN, currentTemp);
    Blynk.virtualWrite(V_PIN_TEMP_MAX, currentTemp);
  }
}

// Blink the LED if the connection is down
void connectionCheck() {
  if (Blynk.connected()) {
    return;
  }

  indLEDon();
  delay(LED_DISC_FLASH_TIME);
  indLEDoff();
}

// Start a temperature read and the conversion wait timer
void startSensorRead01() {
  if (!Blynk.connected()) {
    return;
  }

  sensors.requestTemperatures();
  timer.setTimeout(READ_CONV_WAIT, sensorRead01);
}

void startSensorRead02()
{
  if (!Blynk.connected()) 
  {
    return;
  }

  sensors.requestTemperatures();
  timer.setTimeout(READ_CONV_WAIT, sensorRead02);
}

// Read the temperature from the sensor and perform the appropriate actions
void sensorRead01() {
  int16_t tempRaw;

  if (!Blynk.connected()) {
    return;
  }

  tempRaw = sensors.getTemp(tempSensor01);
  if (tempRaw != DEVICE_DISCONNECTED_RAW) {
#ifdef TEMP_IN_FAHRENHEIT
    currentTemp = sensors.rawToFahrenheit(tempRaw);
#else
    currentTemp = sensors.rawToCelsius(tempRaw);
#endif

    // Send temperature value
    Blynk.virtualWrite(V_PIN_TEMP_01, currentTemp);
    Blynk.virtualWrite(V_PIN_TEMP_00, currentTemp);

    // Low temperature alerts
    if ((currentTemp <= alertTempLow) && !lowAlertOn) {
      Blynk.setProperty(V_PIN_TEMP_01, "color", ALERT_COLOR_LOW);
      Blynk.notify(alertMessageLow);
      lowAlertOn = true;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump ON
      digitalWrite(Relay02, LOW); //Turns Cooling OFF
      digitalWrite(Relay03, HIGH); //Turns Heating ON
      Blynk.virtualWrite(LED20, 1023); // Blue LED turns ON
      Blynk.virtualWrite(LED21, 0); // Red LED turns OFF
    }
    else if (lowAlertOn && (currentTemp > alertTempLow + ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_01, "color", ALERT_COLOR_OK);
      lowAlertOn = false;
      digitalWrite(Relay01, LOW); //Turns Sirculation Pump OFF
      digitalWrite(Relay02, LOW); //Turns Cooling OFF
      digitalWrite(Relay03, LOW); //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 0); // Red LED turns OFF
    }

    // High temperature alerts
    if ((currentTemp >= alertTempHigh) && !highAlertOn) {
      Blynk.setProperty(V_PIN_TEMP_01, "color", ALERT_COLOR_HIGH);
      Blynk.notify(alertMessageHigh);
      highAlertOn = true;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump ON
      digitalWrite(Relay02, HIGH); //Turns Cooling ON
      digitalWrite(Relay03, LOW);  //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 1023); //Red LED turns ON
    }
    else if (highAlertOn && (currentTemp < alertTempHigh - ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_01, "color", ALERT_COLOR_OK);
      highAlertOn = false;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump OFF
      digitalWrite(Relay02, HIGH); //Turns Cooling OFF
      digitalWrite(Relay03, HIGH); //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 0); //Red LED turns OFF
    }

    // Minimum and maximum temperatures
    if (currentTemp < minTemp) {
      minTemp = currentTemp;
      Blynk.virtualWrite(V_PIN_TEMP_MIN, currentTemp);
    }
    if (currentTemp > maxTemp) {
      maxTemp = currentTemp;
      Blynk.virtualWrite(V_PIN_TEMP_MAX, currentTemp);
    }

    flashLED(LED_READ_OK_FLASH_TIME);
  }
  else {
    flashLED(LED_READ_ERR_FLASH_TIME);
  }
}
void sensorRead02() {
  int16_t tempRaw02;

  if (!Blynk.connected()) {
    return;
  }

  tempRaw02 = sensors.getTemp(tempSensor02);
  if (tempRaw02 != DEVICE_DISCONNECTED_RAW) {
#ifdef TEMP_IN_FAHRENHEIT
    currentTemp02 = sensors.rawToFahrenheit(tempRaw02);
#else
    currentTemp02 = sensors.rawToCelsius(tempRaw02);
#endif

    // Send temperature value
    Blynk.virtualWrite(V_PIN_TEMP_03, currentTemp02);
   // Blynk.virtualWrite(V_PIN_TEMP_04, currentTemp);

    // Low temperature alerts
    if ((currentTemp02 <= alertTempLow) && !lowAlertOn02) {
      Blynk.setProperty(V_PIN_TEMP_03, "color", ALERT_COLOR_LOW);
      Blynk.notify(alertMessageLow);
      lowAlertOn02 = true;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump ON
      digitalWrite(Relay02, LOW); //Turns Cooling OFF
      digitalWrite(Relay03, HIGH); //Turns Heating ON
      Blynk.virtualWrite(LED20, 1023); // Blue LED turns ON
      Blynk.virtualWrite(LED21, 0); // Red LED turns OFF
    }
    else if (lowAlertOn02 && (currentTemp02 > alertTempLow + ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_03, "color", ALERT_COLOR_OK);
      lowAlertOn02 = false;
      digitalWrite(Relay01, LOW); //Turns Sirculation Pump OFF
      digitalWrite(Relay02, LOW); //Turns Cooling OFF
      digitalWrite(Relay03, LOW); //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 0); // Red LED turns OFF
    }

    // High temperature alerts
    if ((currentTemp02 >= alertTempHigh) && !highAlertOn02) {
      Blynk.setProperty(V_PIN_TEMP_03, "color", ALERT_COLOR_HIGH);
      Blynk.notify(alertMessageHigh);
      highAlertOn02 = true;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump ON
      digitalWrite(Relay02, HIGH); //Turns Cooling ON
      digitalWrite(Relay03, LOW);  //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 1023); //Red LED turns ON
    }
    else if (highAlertOn02 && (currentTemp02 < alertTempHigh - ALERT_HYSTERESIS)) {
      Blynk.setProperty(V_PIN_TEMP_03, "color", ALERT_COLOR_OK);
      highAlertOn02 = false;
      digitalWrite(Relay01, HIGH); //Turns Sirculation Pump OFF
      digitalWrite(Relay02, HIGH); //Turns Cooling OFF
      digitalWrite(Relay03, HIGH); //Turns Heating OFF
      Blynk.virtualWrite(LED20, 0); // Blue LED turns OFF
      Blynk.virtualWrite(LED21, 0); //Red LED turns OFF
    }

    // Minimum and maximum temperatures
    if (currentTemp02 < minTemp) {
      minTemp = currentTemp02;
      Blynk.virtualWrite(V_PIN_TEMP_MIN, currentTemp02);
    }
    if (currentTemp02 > maxTemp) {
      maxTemp = currentTemp02;
      Blynk.virtualWrite(V_PIN_TEMP_MAX, currentTemp02);
    }

    flashLED(LED_READ_OK_FLASH_TIME);
  }
  else {
    flashLED(LED_READ_ERR_FLASH_TIME);
  }
}


//--------------------- LOOP --------------------
void loop() {
  Blynk.run();
  timer.run();
}
//-----------------------------------------------

// Flash the indicator LED for the specified duration
void flashLED(long dur) {
  timer.setTimeout(dur, indLEDoff);
  indLEDon();
}

// Turn on the indicator LED
void indLEDon() {
  digitalWrite(LED_PIN, LED_ON);
}

// Turn off the indicator LED
void indLEDoff() {
  digitalWrite(LED_PIN, LED_OFF);
}

Hy, this sketch is wery useful, work ok, but have 1 problem for me.
When disconnect ds18b20 probe, value on blynk gauge frozen, and show last temperatue reading, instead -127.
In sketch is alarm for broken sensor, and only led on d1 mini flashes. This is not enough for me, i need report from blynk app when sensor disconnected to show -127 and acivate low alert alarm.
Anyone know or have idea what need to change in sketch to show -127 when sensor is disconnected??