BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Slider - Unable to work with value or trigger!

Hi All

I have been reading some posts and documentation, and haven’t figured out how to interact with the Slider values, I can only print them in Serial monitor, but when I try to interact or trigger something else If I uncomment the below code I get connection crash.

I have declares it as global variable int slider as follow:

  int humedad1 = A0;
  int slider;

  BLYNK_WRITE(V8){
  int pinValue = param.asInt();
  slider = pinValue;
  Serial.println(slider);

//  if(slider <= analogRead(humedad1))
//    {
//    Serial.print("Dentro de Funcion");
//    }
//  else {
//  Serial.print("Saliendo");
//    }
    }

Try doing the if/else outside of the BLYNK_WRITE(V8) function

billd

Hi @Bill_Donnelly, first of all thanks for taking the time to reply…

I have managed to make it work for a short period of time (5 minutes, then the connection fails… some times the Arduino continues working other it doesn’t…

I managed to get the system to read it without crashing connection, for that I had to invert the statement, first the slider then the comparison

And when it crashes or disconnects, I have to reopen serial port, it doesn’t re-connect on its own

BLYNK_WRITE(V8){
  int pinValue = param.asInt();
  slider = pinValue;
  Serial.println(slider);
  Serial.println(analogRead(humedad1));
  }

I made this VOID to insert the logic in
(I’m sure there is a much simpler way to do this… like call a function and then kill it for a certain period of time???) but I have 3 different time periods to manage…

void riegoBlk(){
  unsigned long currentTime = millis(); 
  int hum1 = analogRead(humedad1);
    
    if(slider < hum1 && lightMeter.readLightLevel() <= Luzriego)    //Variante para riego solo de Noche)
        {       
        if( currentTime - previousTime2 >= TpropRiego && digitalRead(bomba1) == HIGH)
            {
            digitalWrite(bomba1, LOW);
            previousTime2 = currentTime;        
             }           
        if( currentTime - previousTime2 >= Triego && digitalRead(bomba1)==LOW)
            {
            digitalWrite(bomba1, HIGH);
            previousTime2 = currentTime;        
             }       

The function is being called in SETUP

timer.setInterval(1000L, lecturaBlynk);
 timer.setInterval(2000L, riegoBlk);

@David_Hernandez you have two very similar topics running at the same time, which isn’t a good way to get a useable answer to your issues.

My advice for both topics would be…

  1. Set-up timers to take your readings (humidity, light intensity etc) on a regular basis. If you’re using separate timers for this then try to set them up so that they don’t coincide with each other (One called once per second and once called every two seconds will coincide every 2 seconds). Most importantly, save the results to Global variables, so that they are available within other functions when you need them. Taking this approach will make all of your milis() capture and comparison redundant, so strip it out.

  2. Work-out how long it takes for each function to execute on your board. if you’re still using slow Arduinos, along with slow sensors, then this may be part of your problem. You can either print the current millis() value at the start and end of your function, or print a simple “Started” and “Finished” message and use the timestamp feature in the IDE’s serial monitor.

  3. If your functions are taking too long to execute then add one or more Blynk.run() commands at strategic points within the functions to ensure that the Blynk libraries are serviced correctly.

When you are looking for assistance with code it helps if you provide an overview of what it is your code is trying to achieve, and if you post just small snippets of code then explain where these fit in to the bigger picture. Stating your hardware type (board, sensors etc) is also very useful.

Pete.

Hi Guys

Good Day!! and thanks for the time @PeteKnight @Bill_Donnelly

thanks for the heads up, I ended up deciding to recode everything in Blynk standard, instead of trying to merge both codes.
It seems to be running stable now, the main problem I could figure out was that when coding in Arduino Standard, you put fix variables instead of dynamic like when working with Blynk and its inputs like sliders or others.

it’s a much cleaner and leaner code, in my perspective, still running with some issues in regards to updating the slider value by comparison from the app and server information before running. But for that’s something for another subject or issue or should I keep it on this same on? any advice on best practices regarding this matter?

this is how the code is looking so far, just for reference:
(Left out the connection part)

#include <BH1750.h>       //Modulo Luz
#include <Wire.h>
BH1750 lightMeter;
float lux = lightMeter.readLightLevel();

#include <DHT.h>          //Modulo Ambiente
#define DHTPIN 8
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

float hum;
float temp;

int Flora;
int Vegetacion;// Riego y Humedad
int Germina;
int Cactus = 700;
int Luzriego = 10;

int humedad1 = A0;
int humedad2 = A1;
int bomba2 = 11;
int bomba1 = 12;

unsigned long currentTime = millis();
                          
const unsigned long Tmuestra = 1000; // Propagacion
const unsigned long Triego = 2000; // Bomba Activa
const unsigned long TpropRiego = 3000; // Intervalo Bomba
unsigned long prevT_Tmuestra = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;

//-------BLYNK Interaction---------------------

BlynkTimer timer; //Blynk Timer

BLYNK_WRITE(V8){
  int pinValue = param.asInt();
  Germina = pinValue; 
  Serial.println(Germina);
  Serial.println(analogRead(humedad1));          
  }

  BLYNK_CONNECTED() {
    Blynk.syncAll();
}
  
void lecturaBlynk()
{
  int lecpor1 = map(analogRead(humedad1), 0, 1021, 100, 0);
  int lecpor2 = map(analogRead(humedad2), 0, 1021, 100, 0);
  float lux = lightMeter.readLightLevel();
  Blynk.virtualWrite(V1, dht.readHumidity());
  Blynk.virtualWrite(V2, dht.readTemperature());
  Blynk.virtualWrite(V3, lecpor1);
  Blynk.virtualWrite(V4, lecpor2);
  Blynk.virtualWrite(V5, (analogRead(humedad1)));
  Blynk.virtualWrite(V6, (analogRead(humedad2)));
  Blynk.virtualWrite(V7, lux); 
}

void setup() 
{
  Serial.begin(9600);
  
  EspSerial.begin(ESP8266_BAUD); // Blynk Remoto **COMENTADO PRUEBA
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);  
  
  Wire.begin();   // Luz
  lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE); 
  
  dht.begin();   //Ambiente

  pinMode(humedad1, INPUT);  //Humedad Suelo
  pinMode(humedad2, INPUT); 
  pinMode(bomba1, OUTPUT);
  pinMode(bomba2, OUTPUT);
  digitalWrite(bomba1, HIGH);  //Inicia rele apagado
  digitalWrite(bomba2, HIGH);  //Inicia rele apagado

  
  timer.setInterval(1000L, lecturaBlynk);
  timer.setInterval(1000L, RiegoON);
//  timer.setInterval(3000L, RiegoOFF);

}

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

//==================================
//Riego Inicio y Termino

void RiegoON(){
    unsigned long currentTime = millis();

    if(Germina <= analogRead(humedad1)  && lightMeter.readLightLevel() <= Luzriego)    //Variante para riego solo de Noche)
        {       
        if( currentTime - previousTime2 >= TpropRiego && digitalRead(bomba1) == HIGH)
            {
            digitalWrite(bomba1, LOW); 
            previousTime2 = currentTime;        
             }           
        if( currentTime - previousTime2 >= Triego && digitalRead(bomba1) == LOW)
            {
            digitalWrite(bomba1, HIGH);
            previousTime2 = currentTime;        
             }                  
        }
  }


//------------------------------
//Sensor de Ambiente Hum/Temp
void sensorAmbiente(){    
    float converted = 0.00;
    hum = dht.readHumidity();
    temp =dht.readTemperature();
}

//------------------------------
 //Sensor Luz
void sensorLuz(){    
    float lux = lightMeter.readLightLevel();
    if (lux < 0) {
      Serial.println(F("**Sensor Luz Desconectado**"));
    }
}

There is no “Arduino Standard” and “Blynk Standard” when it comes to Local versus Global variables (I assume that’s what you mean when you refer to “fix variables instead of dynamic”).

Many people who write “Arduino code” choose to put everything in the void loop, and if they don’t want it to execute hundreds of times per second they throw a delay in at the end to make the processor wait before it executes the void loop again.
This isn’t exactly what you’d call structured programming, but with simple pieces of code you can get away with it, and many people don’t know any better.
A much nicer approach is to write blocks of code that perform a certain task - such as taking a temperature reading, calculating a complex formula, outputting a set of results to the serial monitor etc. These blocks of code are known as functions, and your void lecturaBlynk() function is an example.

Any variables declared within a function is local to that function - it’s not visible outside of the function o in any other function.
There are two ways around this, passing parameters into a function and back out again, or using global variables.Passing parameters is a neater way to do do things, but in most situations people (myself included) don’t bother. Instead we use global variables that are accessible from anywhere.

A few comments on your code…

This function isn’t very efficient in my opinion…

void lecturaBlynk()
{
  int lecpor1 = map(analogRead(humedad1), 0, 1021, 100, 0);
  int lecpor2 = map(analogRead(humedad2), 0, 1021, 100, 0);
  float lux = lightMeter.readLightLevel();
  Blynk.virtualWrite(V1, dht.readHumidity());
  Blynk.virtualWrite(V2, dht.readTemperature());
  Blynk.virtualWrite(V3, lecpor1);
  Blynk.virtualWrite(V4, lecpor2);
  Blynk.virtualWrite(V5, (analogRead(humedad1)));
  Blynk.virtualWrite(V6, (analogRead(humedad2)));
  Blynk.virtualWrite(V7, lux); 
}

The slowest part of this process, and therefore the thing you want to do the least, is taking a reading from your analog sensors. You do two analogReads in each sensor within this function, so one option would be to simply take those analog sensor readings once, at the beginning of the function and store them in variables that are then used later…

void lecturaBlynk()
{
  float humidity1 = analogRead(humedad1; //Take your reading once and store it
  float humidity2 = analogRead(humedad2; 

  int lecpor1 = map(humidity1), 0, 1021, 100, 0); // Use your stored reading here
  int lecpor2 = map(humidity2), 0, 1021, 100, 0);

  float lux = lightMeter.readLightLevel();

  Blynk.virtualWrite(V1, dht.readHumidity());
  Blynk.virtualWrite(V2, dht.readTemperature());
  Blynk.virtualWrite(V3, lecpor1);
  Blynk.virtualWrite(V4, lecpor2);
  Blynk.virtualWrite(V5, humidity1); // and use your stored reading here again
  Blynk.virtualWrite(V6, humidity2);
  Blynk.virtualWrite(V7, lux); 
}

However, you also take readings from these sensors in other places within your code…

BLYNK_WRITE(V8)
{
  int pinValue = param.asInt();
  Germina = pinValue; 
  Serial.println(Germina);
  Serial.println(analogRead(humedad1));  // you're reading that sensor again here        
}
void RiegoON()
{
 unsigned long currentTime = millis();
 if(Germina <= analogRead(humedad1)  && lightMeter.readLightLevel() <= Luzriego)    //Variante para riego solo de Noche) // and reading the sensor again here
 {       
   if( currentTime - previousTime2 >= TpropRiego && digitalRead(bomba1) == HIGH)
   {
     digitalWrite(bomba1, LOW); 
     previousTime2 = currentTime;        
   }
              
   if( currentTime - previousTime2 >= Triego && digitalRead(bomba1) == LOW)
   {
    digitalWrite(bomba1, HIGH);
    previousTime2 = currentTime;        
   }                  
  }
}

So maybe a better solution would be to have a timed function which reads your sensors (including your DHT and Lux sensor) and stores those readings as global variables that you can use anywhere within your code. You already seem to have done some of that with your void sensorAmbiente() and void sensorLuz() functions, except they use local variables, and those functions are never called from within your code.

Pete.

Thanks a lot, @PeteKnight,

I´ll consider cleaning up my code as suggested, to save some millis;…

Specs:
Arduino UNO
ESP01
08 Relay board

Objective:
Set 1 variable (Germina which is a slider) to control the desired moisture and have every independent unit (sensor and pump) to work accordingly to that setting.

I have managed to get my connection stable, and I’m not having connection problems for the moment

I’m calling the function to execute with TIMER

timer.setInterval(1000L, lecturaBlynk);
timer.setInterval(1000L, RiegoON2);

the VOID to call the function is:
(I have set up serial printing to time the execution it’s around 300ms)
both serial printings get executed and showed on the screen, but only one function executes, the weird part is that it only executed the one that is fist (in this case "humedad2), if I switch the order the other one starts to execute and skips the second one. this in regards to activating the proper relay associated with it.

I have tried to set the Timer up to 5sec but the same thing happens only one of them (first in order) is executed but every 5sec (but both printed on serial monitor)
Also I’ve tried separating the macet calling in 2 independent voids in the timer calling, still, only one gets executed.(the one thats first in order)

void RiegoON2(){
 
      Serial.println("1"); 
      macet(humedad2, bomba2, Germina);    
      macet(humedad1, bomba1, Germina);
      Serial.println("2");
}

Because I will have more than 1 independent subsystem I have arranged this structure to make it easier to add new units.

int macet(int S, int B, int tipo) 
    {
     unsigned long currentTime = millis();
     float lux = lightMeter.readLightLevel(); 
     int SensorValue = analogRead(S);
     int estBom = digitalRead(B);  

    if(tipo <= SensorValue  && lux <= Luzriego) 
        {      
        if( currentTime - previousTime3 >= TpropRiego && estBom == HIGH)
            {
            digitalWrite(B, LOW); 
            previousTime3 = currentTime;        
             }           
        if( currentTime - previousTime3 >= Triego && estBom == LOW)
            {
            digitalWrite(B, HIGH);
            previousTime3 = currentTime;      
             }                  
        }
     if(tipo >= SensorValue && digitalRead(B) == LOW) {
         digitalWrite(B, HIGH);
      }    
    }

Presumably because of the stuff your doing with previous time and current time. The function executes first time around, but then the if function that compares the time evaluates as false the next time around.

Personally, I’d try to avoid mixing Blynk timers and millis functions - use one or the other where possible.

If you do need to do the millis comparison then you’ll need a current/previous time variable for each relay, which hers complex when you’re passing parameters into your function.

I still think you’re approaching this from the wrong angle, which is one of the reasons you’re having these issues.

Pete.

Hi @PeteKnight

How do would you recomend I should approach it?

I’ve looked at the BlynkTimer and haven’t been able to get my head around, how to do a simple blink with time definitions. Because according to what you say, that should get rid of the millis and solve the problem? right?

Cheers,

So, as I said before, take the readings in a function that’s called by a BlynkTimer.
I’d then have a separate function, probably one for each relay, that evaluates the readings and triggers the relay if appropriate. It should then begin a Blynk timeout timer that, when it ends calls a function to deactivate the relay.

Pete.

1 Like

Hi @PeteKnight

thanks for the tips… I used your idea of a different prevTime for each module, but I included it on the macet function as definition, works fine and stable for now.

void RiegoON(){
 
      Serial.println("1");   
      macet(humedad1, bomba1, Germina, 0);
      macet(humedad2, bomba2, Germina, 0);  
      Serial.println("2");
}
    
int macet(int S, int B, int tipo, int orden) 
    {
     unsigned long currentTime = millis();
     float lux = lightMeter.readLightLevel(); 
     int SensorValue = analogRead(S);
     int estBom = digitalRead(B);

    if(tipo <= SensorValue  && lux <= Luzriego) 
        {      
        if( currentTime - orden >= TpropRiego && estBom == HIGH)
            {
            digitalWrite(B, LOW); 
            orden = currentTime;        
             }           
        if( currentTime - orden >= Triego && estBom == LOW)
            {
            digitalWrite(B, HIGH);
            orden = currentTime;      
             }                  
        }
     if(tipo >= SensorValue && digitalRead(B) == LOW) {
         digitalWrite(B, HIGH);
      }    
    }

Hi @PeteKnight

I would like to change this issue as SOLVED
How do I do that?

Cheers,

1 Like

Done!

Pete.

1 Like