New Blynk. Soil Moisture

I did something similar to this, but i am not sure why my LED is not turning on/off when its within the range

1 Like
int slider;

BLYNK_WRITE(V1) //slider widget assigned to virtual pin V1
{

slider = param.asInt();

}

Now you can use slider variable in the if statement, for example if ( value <= slider ) turn on the valve.

@fehrrera posting screenshots of your code makes it very difficult for us to comment on it.
You should copy/paste your code and surround it with triple backticks. Triple backticks look like this:
```

You’re using a variable called limiarin this function. Where is this coming from, and what is its purpose?

Also, it would be helpful for you and others if you gave your variables more meaningful names.

Pete.

Ok. I’m sending the code with comments and variable names that can be understood better.

My question would be: how can I make the setpoint value (slider) be in an if variable as @john93 had said.

 indent preformatted text by 4 spaces
 #define BLYNK_TEMPLATE_ID "TMPLpyZEN5La"
 #define BLYNK_DEVICE_NAME "Teste"

 #define BLYNK_FIRMWARE_VERSION        "0.1.0"

 #define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
//#define USE_WEMOS_D1_MINI

#include "BlynkEdgent.h"

#define sensor A0
#define relay D2

int setpoint = 0; //setpoint value configured in the app (slider)
int h; //humidity variable



BlynkTimer timer;

BLYNK_WRITE(V0)//Button that activates the relay
{
  int pinValue = param.asInt();
  digitalWrite(D2,pinValue);
}

BLYNK_WRITE(V2)//Slider
{
  int setpoint = param.asInt();
  }


void sendData()//Function that sends data from the moisture soil sensor to the app
{
  int value = analogRead(A0);//sensor reading
  value = map(value, 0, 1023, 100, 0); //remap to values ​​from 0 to 100
  Blynk.virtualWrite(V1, value); 
}

void setup()
{
  pinMode(sensor, INPUT);//set sensor as input
  pinMode(relay, OUTPUT);//set relay as input
  Serial.begin(115200);
  delay(100);

  BlynkEdgent.begin();
  timer.setInterval(100L, sendData);
}

void loop() {
    
  BlynkEdgent.run();
  timer.run();
}

By pitting int in front of setpoint you are declaring setpoint to be a local variable. That means that the value you assign to it is not visible outside of the BLYNK_WRITE(V2) function.

If you look at the code snippet that @John93 provided, you’ll see that he declared the variable outside of the function, making it global, and didn’t re-declare it inside the function.

Pete.

Ok, making this variable global is it possible to use the slider value in another function like in sendData, for example?

BLYNK_WRITE(V2)//Slider
{
   setpoint = param.asInt();
    relaystatus = true;
  }


void sendData()//Function that sends data from the moisture soil sensor to the app
{
  value = analogRead(sensor);//sensor reading
  value = map(value, 0, 1023, 100, 0); //remap to values ​​from 0 to 100
  if((setpoint < value) && (relaystatus == true))
  { 
    digitalWrite(relay, LOW); // assuming relay is active HIGH
   relaystatus = false;
  }  
  if((setpoint > value) && (relaystatus == true))
  { 
    digitalWrite(relay, HIGH); // assuming relay is active HIGH
    relaystatus = false;
  } 
  Blynk.virtualWrite(V1, value); 
}

I put the setpoint viariavel as global. And I added an if structure in the sendData function to trigger the relay.

@fehrrera

Global Variable

A Global Variable in the program is a variable defined outside the subroutine or function. It has a global scope means it holds its value throughout the lifetime of the program. Hence, it can be accessed throughout the program by any function defined within the program, unless it is shadowed.

Advantages of using Global variables :

  1. You can access the global variable from all the functions or modules in a program.

  2. You only require to declare global variable single time outside the modules.

  3. It is ideally used for storing “constants” as it helps you keep the consistency.

  4. a global variable is useful when multiple functions are accessing the same data.

Global vs local variable :

Yes of course.

I’m unsure about what you are using relaystatus for.

Also, the code tends to be more readable and logical if you do the comparison the other way around…

if((value < setpoint)`

or better still, use sensible variable names:

if((soil_humidity < target_humidity)`

because you’re actually wanting to say “if the soil humidity is less than the target humidity then water the plants”.

Pete.

Humidity setpoint slider worked!
I would like to know if it is possible to create a delay that the relay will be activated for a certain time (configured with a slider in the app) and after that it will be turned off.

#include "BlynkEdgent.h"

#define sensor A0
#define relay D2

int target_humidity = 0; //setpoint value configured in the app (slider)
int soil_humidity; //humidity variable
bool relaystatus = false;
int interval = 0; //Time that the relay will be on before it is turned off
int pinValue = 0; //Variable that will save the button's value



BlynkTimer timer;

BLYNK_WRITE(V0)//Button that activates the relay
{
   pinValue = param.asInt();
}

BLYNK_WRITE(V2)//Slider
{
   target_humidity = param.asInt();
  }

BLYNK_WRITE(V3)//Time that the relay will be on before it is turned off
{
   interval = param.asInt();
}


void sendData()//Function that sends data from the moisture soil sensor to the app
{
  soil_humidity = analogRead(sensor);//sensor reading
  soil_humidity = map(soil_humidity, 0, 1023, 100, 0); //remap to values ​​from 0 to 100
  if(pinValue == 1){ //If the relay is activated by the button
    digitalWrite(relay, HIGH);
  }
  else if(pinValue == 0){ //If the relay is not activated by the button
  if(soil_humidity > target_humidity)
  { 
    digitalWrite(relay, LOW); // assuming relay is active HIGH
  }  
  if(soil_humidity < target_humidity)
  { 
    digitalWrite(relay, HIGH); // assuming relay is active HIGH
    delay(interval * 1000);
    digitalWrite(relay, LOW);
  } }
  Blynk.virtualWrite(V1, soil_humidity); 
}

For example, the BLYNK.WRITE(V3) function is the slider for setting this delay in seconds. But when I go to test the relay is turning on and off and this delay time does not happen.

While it’s sometimes useful to start small then gradually add to the functionality, it’s usually best to have some idea about the overall functionality that you’re trying to achieve at the beginning, as this can have an impact on some of your design decisions as you proceed.
Otherwise, it’s a bit like starting to build a house without any idea what the finished product will look like.

The simple answer is that you probably ought to use a timeout timer, which is initiated when the watering system is turned on, and when the timer expires it turns off the watering system.
However, if you then want a display of the remaining time then a different approach is probably better.

Having clients drip-feeding functional requirements is the worst nightmare of a software developer, which is why it’s best to gather and document your functional requirements at the beginning and design your software solution with these in mind.

Pete.

@PeteKnight What I need is for the relay to shut down after the timeout is reached. There is no need for a display of the remaining time, just that this timeout is set in the app.

Timeout timer then…

Pete.

I managed to make that, when the button was pressed, the timeout command worked, as in the example below:

if(value == 1){ //If the button that triggers the relay is pressed
    digitalWrite(rele, HIGH);
    timer.setTimeout(5000L, []() //After 5 seconds the relay is turned off
  {  
    digitalWrite(rele, LOW);
  }); 
  }

But when I use the same command with a slider it doesn’t work. The low example is the part of the code where, if the moisture target is greater than the moisture in the ground, the relay will be turned on and after 5 seconds it is turned off, but the interval part with the timeout command is not executed. Would there be a way to make the timeout work with the slider?

else if(value == 0){ //If the button that triggers the relay is not pressed
  if(humidity > target)//If the soil moisture is greater than the configured minimum value
  { 
    digitalWrite(relay, LOW);
  }  
  if(humidity < target)//If the soil moisture is less than the configured minimum value
  { 
    digitalWrite(relay, HIGH);
    timer.setTimeout(5000L, []() //After 5 seconds the relay is turned off
  {  
    digitalWrite(relay, LOW);
  }); 
  }

You can use variable in the timeout timer, for example

timer.setTimeout(slider_value , []()
digitalWrite(relay, HIGH);
    timer.setTimeout(interval, []() //interval fixed by slider in seconds / the relay is turned off
  {

Actually, my difficulty is that when I put an interval variable to control the relay it doesn’t work. The code below is an if structure for the soil moisture, when the humidity is below the desired value the relay should turn on, stay on for 5 seconds and turn off, but it doesn’t. What can I do to force relay shutdown after 5 seconds?

else if(value == 0){ //If the button that triggers the relay is not pressed
  if(humidity < target)//If the soil moisture is less than the configured minimum value
  { 
    digitalWrite(relay, HIGH);
    timer.setTimeout(5000L, []() //After 5 seconds the relay is turned off
  {  
    digitalWrite(relay, LOW);
  });

Do you have timer.run(); in your void loop?

If yes, then please post your complete sketch.

Pete.

Below is the full code:

#include "BlynkEdgent.h"

#define sensor A0
#define relay D2

int target = 0; //Minimum humidity limit (configured in the app)
int humidity; //Variable that will store moisture
int value = 0; //Variable that will store the value of the button that will trigger the relay




BlynkTimer timer;

BLYNK_WRITE(V0)//Button that activates the relay
{
   value = param.asInt();
}

BLYNK_WRITE(V2)//Slider for setting the target of humidity
{
   target = param.asInt();
  }

void sendData()// Function that sends circuit data to the application
{
  humidity = analogRead(sensor);// Sensor reading

  humidity = map(humidity, 0, 1023, 100, 0); //Remaps the sensor value from 0 - 1023 to 0 - 100
  if(value == 1){ //If the button that triggers the relay is pressed
    digitalWrite(rele, HIGH);
    timer.setTimeout(5000L, []() //After 5 seconds the relay is turned off
  {  
    digitalWrite(rele, LOW);
  }); 
  }
  else if(value == 0){ //If the button that triggers the relay is not pressed
  if(humidity < target)//If the soil moisture is less than the configured minimum value
  { 
    digitalWrite(relay, HIGH);
    timer.setTimeout(5000L, []() //After 5 seconds the relay is turned off
  {  
    digitalWrite(relay, LOW);
  }); 
  } 
  Blynk.virtualWrite(V1, humidity); //"Tells" the app that the value of the variable "moisture" is to be shown in a graph in the app
}}

void setup()
{
  pinMode(sensor, INPUT);//Set the variable "sensor" as input
  pinMode(relay, OUTPUT);//Set "relay" variable as output
  Serial.begin(115200);
  delay(100);

  BlynkEdgent.begin();
  timer.setInterval(100L, sendData);
}

void loop() {
    
  BlynkEdgent.run();
  timer.run();
}

rele should be relay

The map command that you are using Les the do what your description says. It inverts the result, so a reading of 0 would be mapped to 100 and a reading of 1023 would be mapped to 0.
I’m not sure if this is what you are expecting, or if it affects your results.

This timer is calling your sendData function ten times per second.
What you probably don’t realise is that the timeout timer is not a blocking function (that’s why we use it) so the sendData fu citing doesn’t simply wait until the timeout timer has completed before returning to the void loop and allowing the function tobe triggered again.
Instead, the state of your widget button is evaluated the first time that sendData is executed, starting one of your timeout timers, then 100ms later the state of the widget button is evaluated again, most likely reversing the state of the relay before the timeout timer is even a fraction of the way through its timeout countdown.

Pete.

1 Like