[SOLVED] Blynk Write and Delay to show in App

Hi everyone,

I’m new here and I’m trying to use my project with Blynk app. Until now, I was able to view my variables on the app with no problems, but now I want to write in a variable, so I can control it. That’s my code:

#include <PID_v1.h>
#include <Ultrasonic.h>
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>

#define BLYNK_PRINT Serial                              //Disabilita prints e salva espaço

#define PIN_OUTPUT 3                                    //Define os pinos para Input e Output do PID
//#define PIN_INPUT A0                                  //Esse pino foi retirado pois não utilizei-o, o input está sendo obtido por uma conversão

#define pino_trigger 5                                  //Define os pinos para o trigger e echo do ultrasom
#define pino_echo 6

#define PIN_V0 V0
#define PIN_V1 V1
#define PIN_V2 V2
#define PIN_V3 V3
#define PIN_V4 V4

char auth[] = "auth token";       //

int IN1 = 4;                                            //Define os pinos como saídas digitais ligadas à entrada da Ponte H
//int IN2 = 7;                                          //Esse pino só é utilizado quando há a necessidade de controlar o sentido de rotação do eixo do motor ou bomba

float cmMsec;                                           //Variáveis para conversão do sensor ultrassônico e visualização no monitor serial

float vazao;                                            //Variável para armazenar o valor em L/min
float media = 0;                                        //Variável para tirar a média a cada 1 minuto
int contaPulso;                                         //Variável para a quantidade de pulsos
int i = 0;                                              //Variável para contagem
int flow = 2;                                           //Define o pino como entrada do valor de vazão

double SetpointPorc;                                       //Variáveis para Visualização no monitor serial (% e cm)
double SetpointCM;

double Setpoint, Input, Output;                         //Define as variáveis que conectaremos ao PID

double Kp = 2, Ki = 5, Kd = 1;                          //Especifica as variáveis linkadas e os parametros iniciais do PID

//Testes
float Output2;
float Setpoint2;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

Ultrasonic ultrasonic(pino_trigger, pino_echo);         //Inicializa o sensor nos pinos definidos

void incpulso ()
{
  contaPulso++;                                         //Incrementa a variável de contagem dos pulsos
}

BLYNK_READ(PIN_V0)
{
  // Virtual Pin (0)
  Blynk.virtualWrite(PIN_V0, cmMsec);
}

BLYNK_READ(PIN_V1)
{
  //Virtual Pin (1)
  Blynk.virtualWrite(PIN_V1, vazao);
}

BLYNK_READ(PIN_V2)
{
  //Virtual Pin (2)
  Blynk.virtualWrite(PIN_V2, Output);
}

BLYNK_WRITE(PIN_V3)
{
  //Virtual Pin (3)
  Setpoint = param.asDouble();
}

BLYNK_READ(PIN_V4)
{
  //Virtual Pin (4)
  Blynk.virtualWrite(PIN_V4, SetpointCM);
}

void setup()
{
//Controle PID
  //Define os valores iniciais das variáveis PID
  Input = 0;                                        
  Setpoint = 0;

  //Liga a funçõo PID
  myPID.SetMode(AUTOMATIC);
  
//Driver L298N
  //Inicializa os pinos da Ponte H para acionamento do motor/bomba
  pinMode(IN1, OUTPUT);
  //pinMode(IN2, OUTPUT);

//Inicia a serial
  Serial.begin(9600);
  
//Sensor de Vazão YF-S201
  //Inicializa o pino e informações do sensor de vazão
  pinMode(flow, INPUT);
  attachInterrupt(0, incpulso, RISING);                  //Configurado (Interrupção 0) para trabalhar como interrupção
//  Serial.println("\n\nInicio\n\n");                      //Imprime Inicio na serial
//  Serial.println("Lendo dados do sensor...");

//Blynk
  Blynk.begin(auth);
}

void loop()
{
//Teste
  Output2 = Output;
  Setpoint2 = Setpoint;
  
//Sensor Ultrassonico HC-SR04
  //Le as informações do sensor, em centímetros
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  
//Sensor de Vazão YF-S201
  contaPulso = 0;                                        //Zera a variável para contar os giros por segundos
  sei();                                                 //Habilita interrupção
  delay (500);                                           //Aguarda 0,5 segundo
  cli();                                                 //Desabilita interrupção
  vazao = contaPulso / 7.5;                              //Converte para L/min

//Controle PID
  Input = map(cmMsec, 2, 25, 0, 1023);
//  Setpoint = analogRead(A1);
  myPID.Compute();

  //Define o range de saída para a tensão de operação do motor/bomba
  if (Output >= 95) {
    analogWrite(PIN_OUTPUT, Output);
  }
  else {
    analogWrite(PIN_OUTPUT, 0);
  }

  //Motor
  //Define o sentido de rotação no caso de um motor ou habilita a Ponte H para acionamento da bomba:
  digitalWrite(IN1, HIGH);
  //digitalWrite(IN2, LOW);

  SetpointPorc = map(Setpoint, 0, 1023, 0, 100);
  SetpointCM = map(Setpoint, 0, 1023, 2, 25);

//Blynk
  Blynk.run();
  
/*
  //Imprimi os valores no monitor serial:
  Serial.print("Distancia cm: ");
  Serial.print(cmMsec);
  Serial.print(" Input: ");
  Serial.print(Input);
  Serial.print(" Output: ");
  Serial.print(Output);
  Serial.print(" Vazão: ");
  Serial.print(vazao);
  Serial.print(" L/min  ");
  Serial.print(" Setpoint: ");
  Serial.print(SetpointPorc);
  Serial.print("% - ");
  Serial.print(SetpointCM);
  Serial.print(" cm - ");
  Serial.print(Setpoint2);
  Serial.print(" ");
  Serial.println(Output2);
  delay(1000);
*/
}

My project is to control my pump through my ultrasonic sensor. The variable to control is the Setpoint, which is the exact level that my pump should act to maintain the level set in Setpoint. There are 4 variables to see in Blynk app, the ultrasonic sensor, the flow sensor, the output for my pump and the Setpoint for my PID control. I putted a Gauge in the app as a feedback to see when I change the Setpoint. My problem here is that the Setpoint takes tooooooo long to update in my Arduino, and the other variables are taking more than 1 sec to update too. They are all set to 1 sec. I believe that is something in my code that is messing with all of it. If anyone can help me with that please. Thanks in advance.

loop() normally has just 2 lines when using Blynk.

So when I’m creating my algorithm in void loop( ) I can’t write too much? My void loop( ) has tooo many lines hahaha, that’s it? :confused:

If so, I can’t create a algorithm with more variables that maybe it will have those problems right?

You can create very large algorithms, outside of loop(), as far as lines of code goes but it must be fast acting without delays() etc.

Normally done with BlynkTimer, more commonly known as the SimpleTimer library.

Ok, I will try to make new functions outside of loop() and call them, so there’s no large commands in it. I will study more about BlynkTimer, but I can just exchange Delay() for BlynkTimer()?

Thanks a lot for the help, I will try those modifications and post here.

Sorry it does not work that way

Study this old simpletimer, read the descriptions
https://playground.arduino.cc/Code/SimpleTimer

In short, delay halts entire device from doing anything and simpletimer does not hold the device, it simply waits for a pre defined number of milliseconds until it is time to do work.

just to clarify, it waits before each call to the specified algorithm but continues with all your other algorithms like Blynk.run().

1 Like

Can I use this BlynkTimer() with the interrupt()?! I made the test, moving every commands in loop() to a new void function and then call it back in the loop() and nothing changed. I red about the SimpleTimer and I think I understood how to use it, however not in this specific case, with interrupt. Now my code is like this:

//Bibliotecas
#include <PID_v1.h>
#include <Ultrasonic.h>
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>

#define BLYNK_PRINT Serial                              //Desabilita prints e salva espaço

#define PIN_OUTPUT 3                                    //Define os pinos para Input e Output do PID
//#define PIN_INPUT A0                                  //Esse pino foi retirado pois não utilizamos para esse projeto, o input está sendo obtido por uma conversão

#define pino_trig 5                                     //Define os pinos para o trigger e echo do ultrasom
#define pino_echo 6

#define PIN_V0 V0
#define PIN_V1 V1
#define PIN_V2 V2
#define PIN_V3 V3
#define PIN_V4 V4

char auth[] = "auth token";       //Código do meu projeto no app para controlá-lo

int IN1 = 4;                                            //Pinos digitais ligadas à entrada da Ponte H
//int IN2 = 7;                                          //Esse pino só é utilizado quando há a necessidade de controlar o sentido de rotação do eixo do motor

float cmPsec;                                           //Variáveis para conversão do sensor ultrassônico e visualização no monitor serial

float vazao;                                            //Variável para armazenar o valor em L/min
int contaPulso;                                         //Variável para a quantidade de pulsos
int pulso = 2;                                          //Pino de entrada dos pulsos do sensor de vazão

double SetpointPorc;                                    //Variáveis para Visualização no monitor serial (% e cm)
double SetpointCM;

double Setpoint, Input, Output;                         //Define as variáveis que conectaremos ao PID

double Kp = 2, Ki = 5, Kd = 1;                          //Especifica as variáveis linkadas e os parametros iniciais do PID

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

Ultrasonic ultrasonic(pino_trig, pino_echo);         //Inicializa o sensor nos pinos definidos

void incpulso ()
{
  contaPulso++;                                         //Incrementa a variável de contagem dos pulsos
}

BLYNK_READ(PIN_V0)
{
  // Virtual Pin (0)
  Blynk.virtualWrite(PIN_V0, cmPsec);
}

BLYNK_READ(PIN_V1)
{
  //Virtual Pin (1)
  Blynk.virtualWrite(PIN_V1, vazao);
}

BLYNK_READ(PIN_V2)
{
  //Virtual Pin (2)
  Blynk.virtualWrite(PIN_V2, Output);
}

BLYNK_WRITE(PIN_V3)
{
  //Virtual Pin (3)
  Setpoint = param.asDouble();
}

BLYNK_READ(PIN_V4)
{
  //Virtual Pin (4)
  Blynk.virtualWrite(PIN_V4, SetpointCM);
}

void setup()
{
//Controle PID
  //Define os valores iniciais das variáveis PID
  Input = 0;                                        
//  Setpoint = analogRead(PIN_V3);

  //Liga a funçõo PID
  myPID.SetMode(AUTOMATIC);
  
//Driver L298N
  //Inicializa os pinos da Ponte H para acionamento do motor/bomba
  pinMode(IN1, OUTPUT);
  //pinMode(IN2, OUTPUT);

//Inicia a serial
  Serial.begin(9600);
  
//Sensor de Vazão YF-S201
  //Inicializa o pino e informações do sensor de vazão
  pinMode(pulso, INPUT);
  attachInterrupt(0, incpulso, RISING);                  //Configurado (Interrupção 0) para trabalhar como interrupção
//  Serial.println("\n\nInicio\n\n");                      //Imprime Inicio na serial
//  Serial.println("Lendo dados do sensor...");

//Blynk
  Blynk.begin(auth);
}

void loop()
{  
  callback ();

//Blynk
  Blynk.run();
  
}
void callback ()
{
//Sensor Ultrassonico HC-SR04
  //Le as informações do sensor, em centímetros
  long microsec = ultrasonic.timing();
  cmPsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  delay(1000);  

//Sensor de Vazão YF-S201
  contaPulso = 0;                                        //Zera a variável para contar os giros por segundos
  sei();                                                 //Habilita interrupção
  delay (500);                                           //Aguarda 0,5 segundo
  cli();                                                 //Desabilita interrupção
  vazao = contaPulso / 7.5;                              //Converte para L/min

//Controle PID
  Input = map(cmPsec, 2, 25, 0, 1023);
//  Setpoint = analogRead(PIN_V3);
  myPID.Compute();

  //Define o range de saída para a tensão de operação do motor/bomba
  if (Output >= 95) {
    analogWrite(PIN_OUTPUT, Output);
  }
  else {
    analogWrite(PIN_OUTPUT, 0);
  }

//Driver L298N
  //Define o sentido de rotação no caso de um motor ou habilita a Ponte H para acionamento da bomba:
  digitalWrite(IN1, HIGH);
  //digitalWrite(IN2, LOW);

  SetpointPorc = map(Setpoint, 0, 1023, 0, 100);
  SetpointCM = map(Setpoint, 0, 1023, 2, 25);
}

The variable that is taking tooooooo long to change is the only one that I’m trying to control, the Setpoint, it’s taking between 30s and 2 min. I will keep trying to change the delay() but if anyone could help me, I would be very glad :grin:. Thanks in advance!

@Edespro I know what you’re going through, but these are the growing pains of learning to write real-time systems. Here are a couple of tips that helped me write code that works with Blynk (and most real-time embedded system):

  1. Avoid delay() function calls at all cost.
  2. Avoid delay() function calls at all cost.
  3. Avoid delay() function calls at all cost.
  4. Use timers to distribute the processing time according to priorities.
  5. Use state variables as a way to avoid code blocking.
  6. Never sit in a loop waiting for something to happen.
  7. For 8266 wifi MCU’s don’t use interrupts. ESP32 might be OK, but the verdict is still out.

Don’t take these as gospel. It’s just some rules that have helped me.

1 Like