Blynk notification issue

@PeteKnight @Blynk_Coeur
I want to receive a notification when my LED is on, which FLOATSENSOR2 triggered. I code Blynk.notify(“First water level detected”); after the digitalWrite(LED, HIGH); then when I upload the code and run then the blynk will disconnect and connect itself in a short time and no output result for my DHT11. Below is my coding that looks fine when there without Blynk.notify(“First water level detected”);

#define BLYNK_PRINT Serial

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>

char auth[] = "xxx";

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

// or Software Serial on Uno, Nano...
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(10, 11); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

int statusLed    = 13; // byte stores an 8-bit unsigned number, from 0 to 255.
int sensorInterrupt = 0;  // 0 = digital pin 2
int sensorPin       = 2;
const int sensorMin = 0;     // sensor minimum
const int sensorMax = 1024;  // sensor maximum

#define FLOAT_SENSOR   12     // the number of the pushbutton pin
#define FLOAT_SENSOR2  13 
#define LED            5      // the number of the LED pin
#define BUZZER         6
#define DHTPIN         4         // What digital pin we're connected to
#define DHTTYPE DHT11     // DHT 11

float calibrationFactor = 4.5;

volatile byte pulseCount;  

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

unsigned long oldTime;

DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
}

//Insterrupt Service Routine
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  // Set ESP8266 baud rate
  EspSerial.begin(ESP8266_BAUD);
  
  delay(10);
  
  Blynk.begin(auth, wifi, ssid, pass);
  //Blynk.begin(auth, wifi, ssid, pass, IPAddress(192,168,1,100), 8080);
  Serial.print("\n");
  // You can also specify server:
  //Blynk.begin(auth, wifi, ssid, pass, "blynk.cloud", 80);

  {
    // initialize the WFS pin as an input:
    pinMode(sensorPin, INPUT);
     // initialize the LED pin as an output:
    pinMode(LED, OUTPUT);
    // initialize the BUZZER pin as an output:
    pinMode(BUZZER, OUTPUT);
    // initialize the pushbutton pin as an input:
    pinMode(FLOAT_SENSOR, INPUT_PULLUP);
    // initialize the pushbutton pin as an input:
    pinMode(FLOAT_SENSOR2, INPUT_PULLUP);

    digitalWrite(sensorPin, HIGH);
   
    pulseCount        = 0;
    flowRate          = 0.0;
    flowMilliLitres   = 0;
    totalMilliLitres  = 0;
    oldTime           = 0;
  
    // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
    // Configured to trigger on a FALLING state change (transition from HIGH
    // state to LOW state)
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    
    dht.begin();
  
    // Setup a function to be called every second
    timer.setInterval(1000L, sendSensor);
  }
}

void loop()
{
  if(digitalRead(FLOAT_SENSOR2) == HIGH) 
  {
     // turn LED on:
     digitalWrite(LED, HIGH);
   } 
   else 
   {
      // turn LED off:
      digitalWrite(LED, LOW);
   }
   if(digitalRead(FLOAT_SENSOR) == HIGH) 
   {
      // turn BUZZER on:
      digitalWrite(BUZZER, HIGH);
   } 
   else 
   {
      // turn BUZZER off:
      digitalWrite(BUZZER, LOW);
   }
  if((millis() - oldTime) > 1000)    // Only process counters once per second
  { 
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
    detachInterrupt(sensorInterrupt);
        
    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    
    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    oldTime = millis();
    
    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres = (flowRate / 60) * 1000;
    
    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;
      
    unsigned int frac;
    
    // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");        
    Serial.print(totalMilliLitres);
    Serial.println("mL"); 
    Serial.print("\t");       // Print tab space
  
    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;
    
    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
  
  // read the sensor on analog A0:
  int sensorReading = analogRead(A0);
  // map the sensor range (four options):
  // ex: 'long int map(long int, long int, long int, long int, long int)'
  int range = map(sensorReading, sensorMin, sensorMax, 0, 3);
  
  // range value:
  switch (range) {
  case 0:    // Sensor getting more wet
    Serial.println("Flood");
    break;
  case 1:    // Sensor getting wet
    Serial.println("Rain Warning");
    break;
  case 2:    // Sensor dry - To shut this up delete the " Serial.println("Not Raining"); " below.
    Serial.println("Not Raining");
    break;
  }
  delay(1000);  // delay between reads
  Blynk.run();
  timer.run();
}

Keep your void loop clean. You cannot have functions inside loop. Call the same via timers.

Ok, so what I should do now ?

Listen to the advice that people give you.

I’ve already told you that you are sampling your DHT11 sensor too often, and that your void loop is cluttered.

Pete.

Ok. I’ll try to change my code. I’m new to Blynk and Arduino, and I’m trying to learn new things; I hope you understand.

You can call timers and do a blynk.run in the main loop. DHT sensors need about 2 seconds between reads. Put all that in a SensorTimer function with a 2 second timeout.

@ScottB Hi, thanks for suggestion. I have written another function to be called every second timer.setInterval(1000L, ledstatus);. It works also.

void ledStatus()
{
  if(digitalRead(FLOAT_SENSOR2) == HIGH) 
  {
     // turn LED on:
     digitalWrite(LED, HIGH);
     Blynk.notify("First water level detected");
   } 
   else 
   {
      // turn LED off:
      digitalWrite(LED, LOW);
   }
   if(digitalRead(FLOAT_SENSOR) == HIGH) 
   {
      // turn BUZZER on:
      digitalWrite(BUZZER, HIGH);
   } 
   else 
   {
      // turn BUZZER off:
      digitalWrite(BUZZER, LOW);
   }
}

//Insterrupt Service Routine
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  // Set ESP8266 baud rate
  EspSerial.begin(ESP8266_BAUD);
  
  delay(10);
  
  Blynk.begin(auth, wifi, ssid, pass);
  //Blynk.begin(auth, wifi, ssid, pass, IPAddress(192,168,1,100), 8080);
  Serial.print("\n");
  // You can also specify server:
  //Blynk.begin(auth, wifi, ssid, pass, "blynk.cloud", 80);

  {
    // initialize the WFS pin as an input:
    pinMode(sensorPin, INPUT);
     // initialize the LED pin as an output:
    pinMode(LED, OUTPUT);
    // initialize the BUZZER pin as an output:
    pinMode(BUZZER, OUTPUT);
    // initialize the pushbutton pin as an input:
    pinMode(FLOAT_SENSOR, INPUT_PULLUP);
    // initialize the pushbutton pin as an input:
    pinMode(FLOAT_SENSOR2, INPUT_PULLUP);

    digitalWrite(sensorPin, HIGH);
   
    pulseCount        = 0;
    flowRate          = 0.0;
    flowMilliLitres   = 0;
    totalMilliLitres  = 0;
    oldTime           = 0;
  
    // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
    // Configured to trigger on a FALLING state change (transition from HIGH
    // state to LOW state)
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    
    dht.begin();
  
    // Setup a function to be called every second
    timer.setInterval(1000L, sendSensor);

    // Setup a function to be called every second
    timer.setInterval(1000L, ledStatus);
  }

You have 2 calls at same time , not possible.

If only someone would tell him that he shouldn’t be reading the DHT11 once every second - oh wait, maybe they did :crazy_face:

Next thing you know someone will be telling him that you can only send one notification every 5 seconds and that he should use a ‘notification sent’ flag, but that would probably fall on deaf ears too!

Pete.

According to the DHT11 datasheet you can take measure every one second but in my opinion 5 to 10 seconds is better. I don’t know why he’s reading every 1 second, the temperature won’t change in 1 second.

The problem is that if you try to read the DHT11 once every second it starts to heat up. This skews the temperature and humidity readings, which are really inaccurate anyway.
You are also more likely to get NAN results, so its just a waste of time.

TBH, the DHT range of sensors are so poor that they belong in the bin. I quite like the SHT30 sensors, which are much more accurate in terms of temperature and are I2C which allows you to make the most of limited pins on an ESP8266.

I still don’t think there’s any point in taking readings more often than every 5-10 seconds.

Pete.

1 Like

this is another great temp sensor, and they even have waterproof versions !
[

DS18B20 Digital temperature sensor

@Blynk_Coeur Can I know whether there are any ways to solve that? @PeteKnight So I need to change it to timer.setInterval(5000L, sendSensor) right? @John93 timer.setInterval(5000L, sendSensor) isit the one you mention? @ScottB can you show me the code as reference?

I am new and i hope to gain knowledge here, thanks

Read this…

Pete.

Generally the main loop() has nothing in it but the Blynk.run() and a call to your shortest timer, let’s say “HeartBeat”. In most of my routines this call is something between 500 ms and 1 second. In that service routine you do whatever and call your other longer timers. I have a reporting timer at 60 seconds and a DHT timer at 5 seconds. Once the DHT gives me a successful read I don’t call it again until I report the results. DHTs pretty much suck and are not that reliable. Most fail within a year. DHT11s are better than DHT22s, which need to be powered down and repowered if they get in a persistent not a number state. Most of my temperature work is done with DS18B20s, which use one wire regardless of how many sensors there are and are addressable.

So essentially when you call heartbeat, it checks all the other timers in sequence. None of them appear in the loop() section.

Well, that statement confused me I’m afraid!

Pete.

Pete, don’t bitch at me about the tick marks…never posted code before.

[Unformatted code removed by moderator]

Actually the Blynk.run() is in the HeartBeatTimer.run() as well.

Well, that doesn’t help anybody now does it…feel better?

Take my advice. move to blynk iot and use automation.

If you don’t want to, or can’t be bothered to, follow the forum rules then your code or your post will be deleted.

Beside that, the code you posted simply had a ‘timer-object-name.run()` command in the void loop. That timer object will support 16 timer instances (or 12 if you use SimpleTimer instead of BlynkTimer).
It’s the timer object that you’re calling in the void loop, not an instance, so you assertion that your void loop should contain…

makes no sense.

The implication of this…

is that you are creating additional timer objects within the function called by a single timer instance which belongs to your initial timer object.
This would lead to a situation where say 5 timers had 5 timer objects with one timer each. This would use 4 times more memory and processor resources than doing it the correct way, which is to have one timer object and 5 timer instances.

Either way, your code didn’t demonstrate the child timer object scenario that you described, so didn’t help to verify that this is what you are actually doing.

Pete.

1 Like