Advice for my project

My program has a weird behavior when I start my pump. The ultrasonic sensor that is used to read my water level is showing 100% everytime I enable the pump , and then goes back to normal .
Showing 100% level either means:

  • the sensor reads a distance of 2cm or less all of the sudden
  • the sensor gets disconnected
void get_water_level()

{

    duration = sonar.ping_median(10);

    distance = (duration / 2) * 0.0343;

    if (distance >= 400 || distance <= 2)

    {

      //Serial.println("Out of range");

    }

    percent = constrain((map(distance, 12, 2, 0, 100)), 0, 100);

    Blynk.virtualWrite(V0, percent);

  

}

Is it something you heard of it before ?

give us your timer.setInterval for get_water_level

mytimer.setInterval(3000L, get_water_level);

Full code:

BLYNK_WRITE(V4) // Button Widget writes to Virtual Pin V5 

{

  int val= param.asInt();

  digitalWrite(32, !val );

}

BLYNK_WRITE(V5)

{

  int led = param.asInt();

  ledcWrite(0, led);

  Blynk.virtualWrite(V5,led);

}

void get_temperature()

{

    t = dht.readTemperature();

    if (isnan(t)) // look into this

    {

      //Serial.println(F("Failed to read from DHT sensor!"));

    }

    Blynk.virtualWrite(V1,t);

  

}

void get_soil_humidity()

{

    soilMoistureValue = analogRead(SoilPin);

    soilmoisturepercent = constrain((map(soilMoistureValue, AirValue, WaterValue, 0, 100)), 0, 100);

    Blynk.virtualWrite(V3,soilmoisturepercent );

}

void get_water_level()

{

    duration = sonar.ping_median(10);

    distance = (duration / 2) * 0.0343;

    if (distance >= 400 || distance <= 2)

    {

      //Serial.println("Out of range");

    }

    percent = constrain((map(distance, 12, 2, 0, 100)), 0, 100);

    Blynk.virtualWrite(V0, percent);

  

}

void get_humidity()

{

    h = dht.readHumidity();

    if (isnan(h)) // look into this

    {

      //Serial.println(F("Failed to read from DHT sensor!"));

    }

     Blynk.virtualWrite(V2,h);

  

}

void setup()

{

  BlynkEdgent.begin();

  pinMode(DHTPin, INPUT);

  pinMode(SoilPin, OUTPUT);

  dht.begin();

  pinMode(32, OUTPUT);

  digitalWrite( 32, HIGH ) ;

  ledcAttachPin(33, 0);

  ledcSetup(0, 4000, 8);

  mytimer.setInterval(3000L, get_temperature);

  mytimer.setInterval(3000L, get_water_level);

  mytimer.setInterval(2000L, get_soil_humidity);

  mytimer.setInterval(3000L, get_humidity);

  

}

void loop()

{

  BlynkEdgent.run();

  mytimer.run();

}

First of all, you have to stage timers
You have 3 timers at same time
then, you should insert Serial.println(distance) before if condition , to see the results in your serial monitor.

What do you mean by I have 3 timers at the same time? And how can I stage them

mytimer.setInterval(3000L, get_temperature);
mytimer.setInterval(3000L, get_water_level);
mytimer.setInterval(3000L, get_humidity);

Read the “Staggering Timers” section of this…

Take care not to fall asleep before you get to the right bit! :laughing:

Pete.

3 Likes

Very nice post!
So let me know I understood it corectly. I should use different periods of time, but also be careful for them to not be combinations like 1 sec / 2 sec or 2 secs / 4 secs etc .
Of course, I dont plan to call my temperature/humidity sensor once every 3 seconds. I was doing this now just so I can test things out. I will definitely make those numbers higher , 30 secs ++++ .

I will ran some tests to check how long each function takes to also have an idea on the delay .

Thank you very much for the information ! I will come back here if I have further problems with this project, to not spam the forum with new posts

1 Like

Question about Blynk.syncVirtual().
So, if I turn my switch on , then disconnect to board, and connect it back again , the component connected to that switched will not work, even tho my switch is on . Because of that, I need to use this sync function . Did I get it right ?

Yes, it synchronises the board with the app.

Pete.

1 Like

Hi again!
Coming back to ask some advices on adding the automatic mode on my water pump, that takes care of watering the plant.
My idea is to have 2 switches , one that I use to manually to start the pump at any moment I want , and another one that, if activated, will take care of this task for me, if some conditions are met. ( see pictures below )

I’m using 2 threshold values:

  • low_threshold = if soil_hum_percent is under this then START watering
  • high_threshold = use to stop the pump when soil_hum_percent has passed this value

My implementation so far is shown below. I’m open to advices on how to do it better. Or, if its actually any good what I did so far.
PS : I’m making use of the function that reads my soil moisture to check if I need to water the plant or not. I dont know how correct this is.


bool auto_mode = 0;
byte low_threshold = 20;
byte high_threshold = 85;

BlynkTimer mytimer;

BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V4); // will cause BLYNK_WRITE(V4) to be executed
  Blynk.syncVirtual(V6);
  Blynk.syncVirtual(V8);
  Blynk.syncVirtual(V7);

  // CAN I USE BLYNK.syncAll() here?
}

BLYNK_WRITE(V4) // Manual Mode button
{
  bool value = param.asInt();
  if (auto_mode == 1 && value == 1) // if auto_mode is enable when I want to manually turn on the PUMP, then disable it.
  {
    auto_mode = 0;
    Blynk.virtualWrite(V6, auto_mode);
  }
  digitalWrite(relayPin, !value);
}

BLYNK_WRITE(V6) // Automatic mode button
{
  auto_mode = param.asInt();
}

BLYNK_WRITE(V7) 
{
  low_threshold = param.asInt();
}

BLYNK_WRITE(V8) 
{
  high_threshold = param.asInt();
}

void get_soil_humidity()
{
  soilMoistureValue = analogRead(SoilPin);
  soilmoisturepercent = constrain((map(soilMoistureValue, DryValue, WetValue, 0, 100)), 0, 100);

  if (auto_mode == 1 && (soilmoisturepercent < low_threshold || soilmoisturepercent < high_threshold)) // if auto_mode is ON .. AND soil_hum_percent is in between my threshold values then
  {
    digitalWrite(relayPin, 0); // turn ON
  }
  else
  {
    digitalWrite(relayPin, 1); // turn OFF
  }
  Blynk.virtualWrite(V3, soilmoisturepercent);
}

Also this is how often I check the soil humidity:

mytimer.setInterval(3112L, get_soil_humidity);

This are my datastreams:

And the app itself ( web part ):
image

Still waiting for some advice in here :slight_smile:

Hey @PeteKnight , can you take a peak at the code above and give me your thoughts ? Please and thank you.

Particularly the get_soil_humidity() function.

void get_soil_humidity()
{
  soilMoistureValue = analogRead(SoilPin);
  soilmoisturepercent = constrain((map(soilMoistureValue, DryValue, WetValue, 0, 100)), 0, 100);

  if (auto_mode == 1 && (soilmoisturepercent < low_threshold || soilmoisturepercent < high_threshold)) // if auto_mode is ON .. AND soil_hum_percent is in between my threshold values then
  {
    digitalWrite(relayPin, 0); // turn ON
  }
  else
  {
    digitalWrite(relayPin, 1); // turn OFF
  }
  Blynk.virtualWrite(V3, soilmoisturepercent);
}

Is it a good idea to use the timer that reads my soil humidity to start/stop the pump?
In this case, the pump would be on for at least 3 seconds if the condition is met , because the timer I use for this function is 3112 ms .

Maybe is it a better idea to control the time of the on/off pump separately… Using a slider in the app to set the time would be nice I guess. Like a slider.

I don’t know what your setup looks like, and what sort of soil volume and water flow rate you have, and how far your moisture sensor is from your water outlet.

In most situations, you’d expect a workflow that does something like this…

  • Check soil moisture
  • If soil moisture is < threshold then start watering. The watering duration is likely to be a function of how much the soul moisture is below the threshold, and how much spoil volume you have and what water flow rate is.
  • Take soul moisture readings throughout the watering process, and when either the moisture level is above the threshold, or the maximum watering time is reached, turn off the water.
  • Wait a pre-determined time before thinking about watering again, to allow the moisture to spread throughout the soil and give sensible readings.

So, there are too many unknowns in your setup to be able to provide any realistic guidance I’m afraid.

Pete.

How could I implement a pre-determined time for the automatic watering? Like, only water the plant if moisture < threshold but also if a certain amount of time has passed ?

Maybe using a widget so that the user can change that time whenever he wants.

I’d use a timeout timer, or change the frequency of your interval timer within your sketch.

Pete.

3 Likes

It came across my mind that I can use Automations to water the plant at a certain point in the week, but the problem is I can only do it for 1 minute minimum, which is too much in my case.

Like every Monday at 10:00 AM start the pump , and at 10:01 AM stop it.
I hope in the future we will able to also choose the seconds, for the automations that require small intervals of time

I guess you could use the automation to start it, then a timeout timer to stop it after x seconds.

Have you considered reducing the water pressure so that your watering periods can be longer?

Pete.

1 Like

How exactly can I use a timeout timer? I can’t really find a tutorial on it.

Have you considered reducing the water pressure so that your watering periods can be longer?

I will take this in consideration also, thank you !

Edit : Ah, you have a section about timeout timers on the post about timers. Reading it right now and I will come back if I have further questions. Thank you, Pete

Try not to fall asleep before you get to the relevant part :zzz:

Pete.