Cannot control a continuous servo motor from both Blynk and from Ardunio event at same time

I am making a automatic pet feeder using Arduino Mega2560 with a S5100 Ethernet Shield and I have created a Blynk app to control it. I have achieved that the Continuous servo motor that dispenses the food to automatically activate for a few seconds once the cat (with a RFID tag in its collar) approaches the reader. I also want the user to be able to activate the servo with the push of a button on Blynk.

However, when adding the code to control de virtual pin (V4) I have created on Blynk, the activation by the RFID does not work. It seems that the OFF state of the Blynk button continuously stops the servo even in the presence of the right RFID. Can anyone help me to identify the problem?

The simplified code is:

void setup() 
{
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Serial.begin(9600);  
  Serial1.begin(9600);   
  servocomida.attach(9);
  SPI.begin(); 
  mfrc522.PCD_Init(); 
  scale.begin(pinData,pinClk);
  scale.set_scale(216000); 
  scale.tare(); 
  lcd.init();  
  lcd.backlight(); 
  Blynk.begin(auth);
}
void loop() 
{
  Blynk.run();
  RFIDRead();
}

void RFIDRead()
{
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  Serial.print("TagID :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  content.toUpperCase();
  if (content.substring(1) == "10 1A 7B A3")
  {
    girarservocomida1();
  }
 else   
  {
    Serial.println("Non_authorized tag:");
  }
} 
void girarservocomida1()
{
   servocomida.write(45); 
   delay(4000); 
   servocomida.write(90); 
}
BLYNK_WRITE(V4)
{
if(param.asInt() == 1)
  {
    servocomida.write(45); 
  }
else
  {
    servocomida.write(90);  
  }
}

I’d suggest that you post your entire sketch, and replace any sensitive data with the word “REDACTED”, otherwise it’s impossible for uis to know if you’ve missed something important out.

Some info on your hardware, how it’s connected and powered etc would also be useful.

Pete.

Sure, the complete code is here:

#define BLYNK_TEMPLATE_ID "REDACTED"
#define BLYNK_DEVICE_NAME "REDACTED"
#define BLYNK_AUTH_TOKEN "REDACTED"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <MFRC522.h>
#include <Servo.h>
#include "HX711.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h> //cargamos la librería DHT
#define W5100_CS  10
#define SDCARD_CS 4
#define SDA_PIN 53 //Entrada SDA de RFID
#define RST_PIN 49  //Entrada RST de RFID
#define sensoragua A0  //Entrada sensoragua
#define echo 8 // Asigno el Echo a pin 8 de Arduino
#define trigger 7 //Asigno el Trigger a pin 7 de Arduino
#define DHTPIN 40 //Seleccionamos el pin 40 en el que se conectará el sensor de temperatura y humedad
#define DHTTYPE DHT11 //Se selecciona el DHT11
#define pinCaudalimetro 22 // Fijo el la entrada del caudalímetro a pin 22
DHT dht (DHTPIN,DHTTYPE); //Se inicia una variable usada por Arduino para comunicarse con el sensor 
byte pinData = 36; //Variable Datos balanza
byte pinClk = 32; //Variable reloj balanza
float pesogato1 = 3;
float pesogato2 = 1;
int nivelagua; //Variable nivelagua
long duration; // Variable para la duración del viaje de la onda de sonido
int nivelcomida; // Variable para la medida de distancia
int humedad = 0; //Variable de humedad
float temperatura = 0;  //Variable de temperatura
int templimiteMIN = 22; //creo variable de temperatura MÍNIMA que podré modificar desde Smartphone. 
int templimiteMAX = 28; //creo variable de temperatura MÁXIMA que podré modificar desde Smartphone. 
int ventilador = 42; //Pin Salida Ventilador
int resistencia = 44; //Pin Entrada Ventilador
unsigned int flowCount; // Variable de la cuenta  de caudal
unsigned int caudalml; // Variable del caudal en mililitros 
unsigned long caudalmlTotal; // Variable del caudal total en ml 
unsigned long caudalmlTotalPrev; // Variable del caudal total Previo en ml 
unsigned long caudalmlTotalIntervalo; // Variable del caudal total en ml durante 1 s 
unsigned long caudalultimo = 0; // variable para medir el tiempo desde la última medida
unsigned long tiempoagua; //variable para medir el tiempo que ha pasado desde la medida del agua
unsigned long tiempocomida; //variable para medir el tiempo que ha pasado desde la medida de la comida
unsigned long tiempotemphum; //variable para medir el tiempo que ha pasado desde la medida de la temperatura y humedad
String readString; //Asignamos la palabra readString a una variable tipo cadena
char auth[] = BLYNK_AUTH_TOKEN;
MFRC522 mfrc522(SDA_PIN, RST_PIN);   // Creo instancia MFRC522.
Servo servocomida; //declaro la variable para controlar el servo
HX711 scale; // Creo instancia de balanza HK711.
LiquidCrystal_I2C lcd(0x27,16,4); //Creo instancia de LCD con 4 columnas

void setup() 
{
  pinMode(6,OUTPUT);  //Fijo salida Electroválvula como de salida.
  pinMode(trigger, OUTPUT); // Fijo el trigger de ultrasonidos como pin de salida
  pinMode(echo, INPUT); // Fijo el echo de ultrasonidos como pin de entrada
  pinMode(SDCARD_CS, OUTPUT);
  pinMode(ventilador,OUTPUT);  //Fijo salida ventilador como de salida.
  pinMode(resistencia,OUTPUT);  //Fijo salida resistencia como de salida.
  pinMode(pinCaudalimetro, INPUT); // Fijo el pin del caudalímetro como de entrada
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Serial.begin(9600);   // Inicio comunicación serie
  Serial1.begin(9600);   // Inicio comunicación serie
  servocomida.attach(9); //Asigno el servo a pin 9
  SPI.begin(); // inicializo SPI bus
  dht.begin();
  mfrc522.PCD_Init();   // Inicializo MFRC522
  Serial.println("Quite cualquier peso de la balanza ");
  Serial.println("Destarando...");
  scale.begin(pinData,pinClk);
  scale.set_scale(216000); //Usamos el factor de calibrado obtenido tras el tarado.
  scale.tare(); //El peso actual es considerado Tara.
  lcd.init();  //Inicializo LCD
  lcd.backlight();  //Enciendo lux de fondo de la LCD.
  Serial.println("Listo para pesar");
  Serial.println("Acerque chapa RFID sobre lector...");
  lcd.print("MEDIDAS RECIENTES:");
  Blynk.begin(auth);
}
void loop() 
{
  Blynk.run();
  temperatura = dht.readTemperature(); //Lee la temperatura
  Blynk.virtualWrite(V0,temperatura);
  nivelagua=analogRead(sensoragua)/9.5; //Asigno la lectura del sensor a la variable nivel agua y la convierto en ml usando el factor 9.5
  Blynk.virtualWrite(V1,nivelagua);
  medircomida();
  Blynk.virtualWrite(V2,nivelcomida);
  humedad = dht.readHumidity(); //Lee la humedad
  Blynk.virtualWrite(V3,humedad);
  Blynk.virtualWrite(V5,pesogato1);
  Blynk.virtualWrite(V6,pesogato2);
  datosLCD();
  if (millis() - tiempotemphum > 10000)
    {
      Serial.print("TEMPERATURA: ");
      Serial.print(temperatura); //Envía el dato de Temperatura por el puerto Serie0 al PC
      Serial.println("ºC");
      Serial.print("HUMEDAD: ");
      Serial.print(humedad);
      Serial.println("%");  // Envía el dato de Humedad por el puerto Serie0 al PC
      tiempotemphum = millis();
    }
  leerchapas();
  if(nivelagua<2)
    {
     soltaragua();
    }
  if(nivelagua<1 && millis() - tiempoagua > 10000)
    {
     Serial.print("Nivel BAJO de agua en bebedero:");
     Serial.println(nivelagua);
     Blynk.logEvent("poca_agua");
     tiempoagua = millis();
    }
  if(nivelcomida>10 && millis() - tiempocomida > 10000)
    {
    Serial.println("Nivel BAJO de comida en contenedor!");
    Serial1.print("Poca Comida!");
    Blynk.logEvent("poca_comida");
    tiempocomida = millis();
    }
  if(temperatura<templimiteMIN)//si la temperatura es menor que valor de la variable templimite Mínima apago ventilador y enciendo resistencia
    {
    digitalWrite(ventilador,LOW);
    digitalWrite(resistencia,HIGH);
    }
  else if(temperatura>=templimiteMIN && temperatura<=templimiteMAX)  //si la temperatura está entre los límites apago ventilador y resistencia
    {
    digitalWrite(ventilador,LOW); 
    digitalWrite(resistencia,LOW);
    }
  else if(temperatura>templimiteMAX)//si la temperatura es mayor que valor de la variable templimite Máxima enciendo ventilador y apago resistencia. 
    {
    digitalWrite(ventilador,HIGH);
    digitalWrite(resistencia,LOW); 
    } 
  while(Serial1.available()) //Verificamos si el puerto Serial 1 esta disponible
    {                             
    delay(3);
    char c = Serial1.read(); // Se leen los caracteres que ingresan por el puerto Serial1 por Bluetooth
    readString += c; //se acumulan cada uno de los caracteres en readString
    }
  if (readString.length() >0) //Se verifica que la variable contenga informacion
   { 
    Serial.println(readString); //se envia lo que tenga la variable al Serial0
    if (readString == "TEM")
      {
      EnviarTemperatura(); //llama la función para enviar la Temperatura del sensor DHT11
      } 
    if (readString == "HUM")
      {
      EnviarHumedad(); //llama la función para enviar la Humedad del sensor DHT11
      }  
    if (readString == "AGU")
      {
      EnviarAgua(); //llama la función para enviar nivel agua del sensor agua
      } 
    if (readString == "COM")
      {
      EnviarComida(); //llama la función para enviar el nivel de comida del ultrasonidos
      }  
    if (readString == "GRI")
      {
      Serial.println("ABRIENDO GRIFO..."); //Envía el dato por el puerto serie
      soltaragua(); //llama la función para abrir electroválvula
      } 
    if (readString == "ALI")
      {
      Serial.println("SOLTANDO COMIDA..."); //Envía el dato por el puerto serie
      girarservocomida2(); //llama la función para girar el servo según peso gato 2.
      } 
    if (readString.substring(0,3) == "MAX")
      {
      Serial.println("FIJANDO TEMPERATURA MÁXIMA"); //Se fija templimiteMaxima
      templimiteMAX=readString.substring(3,5).toInt(); //Fija la temp máxima al valor recibido
      } 
    if (readString.substring(0,3) == "MIN")
      {
      Serial.println("FIJANDO TEMPERATURA MÍNIMA"); //Se fija templimiteMaxima
      templimiteMIN=readString.substring(3,5).toInt(); //Fija la temp mínima al valor recibido
      }
  readString=""; // Se limpia la variable
   } 
}

void leerchapas()
{
  if ( ! mfrc522.PICC_IsNewCardPresent())   // Mira si hay nuevas chapas.
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) // Elige una de las chapas
  {
    return;
  }
  Serial.print("ID Chapa :"); //Muestra la ID en monitor serie
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  content.toUpperCase();
  if (content.substring(1) == "REDACTED")
  {
    pesogato1=scale.get_units(10);
    Serial.println("");
    Serial.println("Bienvenido Gato 1. Disfruta de la comida");
    Serial.print("Peso Gato 1: ");
    Serial.print(pesogato1);
    Serial.println(" Kgs");
    girarservocomida1();
  }
 else if (content.substring(1) == "REDACTED")
  {
    pesogato2=scale.get_units(10);
    Serial.println("");
    Serial.println("Bienvenido Gato 2. Disfruta de la comida");
    Serial.print("Peso Gato 2: ");
    Serial.print(pesogato2);
    Serial.println(" Kgs");
    girarservocomida2();
  }
 else   
  {
    Serial.println("Chapa No Autorizada:");
  }
} 

void girarservocomida1()
{
if (pesogato1<3)
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(6000); //espero 6s
   servocomida.write(90); //Paro servo
   }
else
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(4000); //espero 4s
   servocomida.write(90); //Paro servo
   }
}

void girarservocomida2()
{
if (pesogato2<1)
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(4000); //espero 4s
   servocomida.write(90); //Paro servo
   }
else
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(2000); //espero 2s
   servocomida.write(90); //Paro servo
   }
}

void soltaragua()
{
  digitalWrite(6,HIGH);
  flowCount = pulseIn(pinCaudalimetro, LOW); // Leo el acuenta de flujo
  caudalml = flowCount / 4500; // Convierto la cuenta de flujo a ml/min
  caudalmlTotal += caudalml; // Sumo el volumen añadido al total acumulado 
  if (millis() - caudalultimo > 500) //Si ha pasado más de 1s desde la última cuenta sumo el caudal 
  { 
    caudalultimo = millis(); // actualizo el tiempo desde la última lectura 
    caudalmlTotalIntervalo = caudalmlTotal - caudalmlTotalPrev; // calculo el caudal em ml/min
    caudalmlTotalPrev = caudalmlTotal; // actualizo el volumen total acumulado
    Serial.print("Caudal: ");
    Serial.print(caudalmlTotalIntervalo);
    Serial.println(" ml/min");
    Serial.print("Volumen: "); 
    Serial.print(caudalmlTotal);
    Serial.println(" ml");
  }
  delay(5000);
  digitalWrite(6,LOW);
}

void medircomida() //Función para medir comida por ultrasonidos
{
  digitalWrite(trigger, LOW); // Pongo el trigger a 0
  delayMicroseconds(2);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10); // Enciendo el trigger durante 10 microseconds
  digitalWrite(trigger, LOW);
  duration = pulseIn(echo, HIGH); // Leo el echo que me devuelve el tiempo de viaje de la onda de sonido en microsegundos
  nivelcomida = duration * 0.034 / 2; // Calculamos la distancia usando la velocidad del sonido y dividida entre 2 (ida y vuelta) 
}

void datosLCD()
{
 lcd.setCursor(0,1);
 lcd.print("Peso1 = ");
 lcd.setCursor(8,1);
 lcd.print(pesogato1);
 lcd.setCursor(11,1);
 lcd.print("Kg");
 lcd.setCursor(0,2);
 lcd.print("Peso2 = ");
 lcd.setCursor(8,2);
 lcd.print(pesogato2);
 lcd.setCursor(11,2);
 lcd.print("Kg");
 lcd.setCursor(0,3);
 lcd.print("T=");
 lcd.setCursor(2,3);
 lcd.print(temperatura);
 lcd.setCursor(6,3);
 lcd.print("C");
 lcd.setCursor(9,3);
 lcd.print("H=");
 lcd.setCursor(11,3);
 lcd.print(humedad);
 lcd.setCursor(13,3);
 lcd.print("%");
}

void EnviarTemperatura()
{
Serial.print("TEMPERATURA: ");
Serial.print(temperatura); //Envía el dato de Temperatura por el puerto Serie0 al PC
Serial.println("ºC");
Serial1.print(temperatura); //Envía el dato de Temperatura por el puerto Serie1 al Smartphone
}

void EnviarHumedad()
{
Serial.print("HUMEDAD: ");
Serial.print(humedad);
Serial.println("%");  // Envía el dato de Humedad por el puerto Serie0 al PC
Serial1.print(humedad); // Envía el dato de Humedad por el puerto Serie1 al Smartphone
}

void EnviarAgua()
{
Serial.print("NIVEL AGUA: ");
Serial.println(nivelagua); // Envía el dato de nivel de agua  por el puerto Serie0 al PC
Serial1.print(nivelagua); // Envía el dato de nivel de agua por el puerto Serie1 al Smartphone
}

void EnviarComida()
{
Serial.print("NIVEL COMIDA: ");
Serial.print(nivelcomida); // 
Serial.println("cm");  // Envía el dato de nivel de comida por el puerto Serie0 al PC
Serial1.print(nivelcomida); // Envía el dato de nivel de comida por el puerto Serie1 al Smartphone
}
BLYNK_WRITE(V4) // Se ejecuta cuando el valor del pin virtual V4 cambia
{
if(param.asInt() == 1)
  {
    servocomida.write(45); //Inicio movimiento servo
  }
else
  {
    servocomida.write(90); //Inicio movimiento servo
  }
}

Besides the Arduino Mega 2560, the system is powered by a 12V power supply and a 5V one. There is a 4 relay module to control the Electrovalve, the fan and the power resistor. There is a load cell tha weight the cats when they approach the feeder so that the RFID can read its tags and activate the servo for the proper duration depending on the weight.

Theres a DHT11 sensor to monitor temperature and humidity, a Velleman water level sensor for the water dispenser, an Ultrasonic sensor to detect the remaining food in the container. Everything worked fine until I decided to add a button on Blynk to dispense food on demand.

Thanks in advance for any help…

Okay, if you have this code up and running on a device now, you need to take it offline immediately.

You cannot have Blynk.virtualWrite commands in your void loop, you will flood the server.

Pete.

Ok, I did not know that. I have already shut it down.

My suggestion would be for you to familiarise yourself with Blynk on this hardware first, then start to add-in the other code.

You should read this…

and probably this…

because it looks like you around easily exceed the 100 events per 24 hour limit with your current code.

Pete.

Thanks for the info!! I have already put all my Blynk.virtualWrite commands outside of the void loop and include a Blynk Timer.

However, the problem of controlling the servo both from the RFID tags and from the Blynk button persists. Any ideas?

Not without seeing your revised code and the serial output that it generates, but it seems that you didn’t like this piece of advice…

Any reason why?

Pete.

Sorry if I conveyed that meaning. I did like that appreciate, reda the articles and modified my code accordingly. The following code works fine but now I would like to add a button on Blynk to activate the continuous servo:

#define BLYNK_TEMPLATE_ID "redacted"
#define BLYNK_DEVICE_NAME "redacted"
#define BLYNK_AUTH_TOKEN "redacted"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <MFRC522.h>
#include <Servo.h>
#include "HX711.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h> //cargamos la librería DHT
#define W5100_CS  10
#define SDCARD_CS 4
#define SDA_PIN 53 //Entrada SDA de RFID
#define RST_PIN 49  //Entrada RST de RFID
#define sensoragua A0  //Entrada sensoragua
#define echo 8 // Asigno el Echo a pin 8 de Arduino
#define trigger 7 //Asigno el Trigger a pin 7 de Arduino
#define DHTPIN 40 //Seleccionamos el pin 40 en el que se conectará el sensor de temperatura y humedad
#define DHTTYPE DHT11 //Se selecciona el DHT11
#define pinCaudalimetro 22 // Fijo el la entrada del caudalímetro a pin 22

DHT dht (DHTPIN,DHTTYPE); //Se inicia una variable usada por Arduino para comunicarse con el sensor 
byte pinData = 36; //Variable Datos balanza
byte pinClk = 32; //Variable reloj balanza
float pesogato1 = 3;
float pesogato2 = 1;
int nivelagua; //Variable nivelagua
long duration; // Variable para la duración del viaje de la onda de sonido
int nivelcomida; // Variable para la medida de distancia
int humedad = 0; //Variable de humedad
float temperatura = 0;  //Variable de temperatura
int templimiteMIN = 22; //creo variable de temperatura MÍNIMA que podré modificar desde Smartphone. 
int templimiteMAX = 28; //creo variable de temperatura MÁXIMA que podré modificar desde Smartphone. 
int ventilador = 42; //Pin Salida Ventilador
int resistencia = 44; //Pin Entrada Ventilador
unsigned int flowCount; // Variable de la cuenta  de caudal
unsigned int caudalml; // Variable del caudal en mililitros 
unsigned long caudalmlTotal; // Variable del caudal total en ml 
unsigned long caudalmlTotalPrev; // Variable del caudal total Previo en ml 
unsigned long caudalmlTotalIntervalo; // Variable del caudal total en ml durante 1 s 
unsigned long caudalultimo = 0; // variable para medir el tiempo desde la última medida
unsigned long tiempoagua; //variable para medir el tiempo que ha pasado desde la medida del agua
unsigned long tiempocomida; //variable para medir el tiempo que ha pasado desde la medida de la comida
unsigned long tiempotemphum; //variable para medir el tiempo que ha pasado desde la medida de la temperatura y humedad
String readString; //Asignamos la palabra readString a una variable tipo cadena
char auth[] = BLYNK_AUTH_TOKEN;

MFRC522 mfrc522(SDA_PIN, RST_PIN);   // Creo instancia MFRC522.
Servo servocomida; //declaro la variable para controlar el servo
HX711 scale; // Creo instancia de balanza HK711.
LiquidCrystal_I2C lcd(0x27,16,4); //Creo instancia de LCD con 4 columnas
BlynkTimer timer; // Anuncio un temporizador para Blynk

void setup() 
{
  pinMode(6,OUTPUT);  //Fijo salida Electroválvula como de salida.
  pinMode(trigger, OUTPUT); // Fijo el trigger de ultrasonidos como pin de salida
  pinMode(echo, INPUT); // Fijo el echo de ultrasonidos como pin de entrada
  pinMode(SDCARD_CS, OUTPUT);
  pinMode(ventilador,OUTPUT);  //Fijo salida ventilador como de salida.
  pinMode(resistencia,OUTPUT);  //Fijo salida resistencia como de salida.
  pinMode(pinCaudalimetro, INPUT); // Fijo el pin del caudalímetro como de entrada
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Serial.begin(9600);   // Inicio comunicación serie
  Serial1.begin(9600);   // Inicio comunicación serie
  servocomida.attach(9); //Asigno el servo a pin 9
  SPI.begin(); // inicializo SPI bus
  dht.begin();
  mfrc522.PCD_Init();   // Inicializo MFRC522
  Serial.println("Quite cualquier peso de la balanza ");
  Serial.println("Destarando...");
  scale.begin(pinData,pinClk);
  scale.set_scale(216000); //Usamos el factor de calibrado obtenido tras el tarado.
  scale.tare(); //El peso actual es considerado Tara.
  lcd.init();  //Inicializo LCD
  lcd.backlight();  //Enciendo lux de fondo de la LCD.
  Serial.println("Listo para pesar");
  Serial.println("Acerque chapa RFID sobre lector...");
  lcd.print("MEDIDAS RECIENTES:");
  Blynk.begin(auth);
  timer.setInterval(1000L, sensorDataSend); //el temporizador funciona cada 1s 
}
void loop() 
{
  Blynk.run();
  timer.run();// empiezo el temporizador
  temperatura = dht.readTemperature(); //Lee la temperatura
  nivelagua=analogRead(sensoragua)/9.5; //Asigno la lectura del sensor a la variable nivel agua y la convierto en ml usando el factor 9.5
  medircomida();
  humedad = dht.readHumidity(); //Lee la humedad
  datosLCD();
  if (millis() - tiempotemphum > 10000)
    {
      Serial.print("TEMPERATURA: ");
      Serial.print(temperatura); //Envía el dato de Temperatura por el puerto Serie0 al PC
      Serial.println("ºC");
      Serial.print("HUMEDAD: ");
      Serial.print(humedad);
      Serial.println("%");  // Envía el dato de Humedad por el puerto Serie0 al PC
      tiempotemphum = millis();
    }
  leerchapas();
  if(nivelagua<2)
    {
     soltaragua();
    }
  if(nivelagua<1 && millis() - tiempoagua > 10000)
    {
     Serial.print("Nivel BAJO de agua en bebedero:");
     Serial.println(nivelagua);
     Blynk.logEvent("poca_agua");
     tiempoagua = millis();
    }
  if(nivelcomida>10 && millis() - tiempocomida > 10000)
    {
    Serial.println("Nivel BAJO de comida en contenedor!");
    Serial1.print("Poca Comida!");
    Blynk.logEvent("poca_comida");
    tiempocomida = millis();
    }
  if(temperatura<templimiteMIN)//si la temperatura es menor que valor de la variable templimite Mínima apago ventilador y enciendo resistencia
    {
    digitalWrite(ventilador,LOW);
    digitalWrite(resistencia,HIGH);
    }
  else if(temperatura>=templimiteMIN && temperatura<=templimiteMAX)  //si la temperatura está entre los límites apago ventilador y resistencia
    {
    digitalWrite(ventilador,LOW); 
    digitalWrite(resistencia,LOW);
    }
  else if(temperatura>templimiteMAX)//si la temperatura es mayor que valor de la variable templimite Máxima enciendo ventilador y apago resistencia. 
    {
    digitalWrite(ventilador,HIGH);
    digitalWrite(resistencia,LOW); 
    } 
  while(Serial1.available()) //Verificamos si el puerto Serial 1 esta disponible
    {                             
    delay(3);
    char c = Serial1.read(); // Se leen los caracteres que ingresan por el puerto Serial1 por Bluetooth
    readString += c; //se acumulan cada uno de los caracteres en readString
    }
  if (readString.length() >0) //Se verifica que la variable contenga informacion
   { 
    Serial.println(readString); //se envia lo que tenga la variable al Serial0
    if (readString == "TEM")
      {
      EnviarTemperatura(); //llama la función para enviar la Temperatura del sensor DHT11
      } 
    if (readString == "HUM")
      {
      EnviarHumedad(); //llama la función para enviar la Humedad del sensor DHT11
      }  
    if (readString == "AGU")
      {
      EnviarAgua(); //llama la función para enviar nivel agua del sensor agua
      } 
    if (readString == "COM")
      {
      EnviarComida(); //llama la función para enviar el nivel de comida del ultrasonidos
      }  
    if (readString == "GRI")
      {
      Serial.println("ABRIENDO GRIFO..."); //Envía el dato por el puerto serie
      soltaragua(); //llama la función para abrir electroválvula
      } 
    if (readString == "ALI")
      {
      Serial.println("SOLTANDO COMIDA..."); //Envía el dato por el puerto serie
      girarservocomida2(); //llama la función para girar el servo según peso gato 2.
      } 
    if (readString.substring(0,3) == "MAX")
      {
      Serial.println("FIJANDO TEMPERATURA MÁXIMA"); //Se fija templimiteMaxima
      templimiteMAX=readString.substring(3,5).toInt(); //Fija la temp máxima al valor recibido
      } 
    if (readString.substring(0,3) == "MIN")
      {
      Serial.println("FIJANDO TEMPERATURA MÍNIMA"); //Se fija templimiteMaxima
      templimiteMIN=readString.substring(3,5).toInt(); //Fija la temp mínima al valor recibido
      }
  readString=""; // Se limpia la variable
   } 
}

void leerchapas()
{
  if ( ! mfrc522.PICC_IsNewCardPresent())   // Mira si hay nuevas chapas.
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) // Elige una de las chapas
  {
    return;
  }
  Serial.print("ID Chapa :"); //Muestra la ID en monitor serie
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  content.toUpperCase();
  if (content.substring(1) == "10 1A 7B A3")
  {
    pesogato1=scale.get_units(10);
    Serial.println("");
    Serial.println("Bienvenido Gato 1. Disfruta de la comida");
    Serial.print("Peso Gato 1: ");
    Serial.print(pesogato1);
    Serial.println(" Kgs");
    girarservocomida1();
  }
 else if (content.substring(1) == "7B FD 8F 63")
  {
    pesogato2=scale.get_units(10);
    Serial.println("");
    Serial.println("Bienvenido Gato 2. Disfruta de la comida");
    Serial.print("Peso Gato 2: ");
    Serial.print(pesogato2);
    Serial.println(" Kgs");
    girarservocomida2();
  }
 else   
  {
    Serial.println("Chapa No Autorizada:");
  }
} 

void girarservocomida1()
{
if (pesogato1<3)
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(6000); //espero 6s
   servocomida.write(90); //Paro servo
   }
else
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(4000); //espero 4s
   servocomida.write(90); //Paro servo
   }
}

void girarservocomida2()
{
if (pesogato2<1)
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(4000); //espero 4s
   servocomida.write(90); //Paro servo
   }
else
   {
   servocomida.write(45); //Inicio movimiento de servo
   delay(2000); //espero 2s
   servocomida.write(90); //Paro servo
   }
}

void soltaragua()
{
  digitalWrite(6,HIGH);
  flowCount = pulseIn(pinCaudalimetro, LOW); // Leo el acuenta de flujo
  caudalml = flowCount / 4500; // Convierto la cuenta de flujo a ml/min
  caudalmlTotal += caudalml; // Sumo el volumen añadido al total acumulado 
  if (millis() - caudalultimo > 500) //Si ha pasado más de 1s desde la última cuenta sumo el caudal 
  { 
    caudalultimo = millis(); // actualizo el tiempo desde la última lectura 
    caudalmlTotalIntervalo = caudalmlTotal - caudalmlTotalPrev; // calculo el caudal em ml/min
    caudalmlTotalPrev = caudalmlTotal; // actualizo el volumen total acumulado
    Serial.print("Caudal: ");
    Serial.print(caudalmlTotalIntervalo);
    Serial.println(" ml/min");
    Serial.print("Volumen: "); 
    Serial.print(caudalmlTotal);
    Serial.println(" ml");
  }
  delay(5000);
  digitalWrite(6,LOW);
}

void medircomida() //Función para medir comida por ultrasonidos
{
  digitalWrite(trigger, LOW); // Pongo el trigger a 0
  delayMicroseconds(2);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10); // Enciendo el trigger durante 10 microseconds
  digitalWrite(trigger, LOW);
  duration = pulseIn(echo, HIGH); // Leo el echo que me devuelve el tiempo de viaje de la onda de sonido en microsegundos
  nivelcomida = duration * 0.034 / 2; // Calculamos la distancia usando la velocidad del sonido y dividida entre 2 (ida y vuelta) 
}

void datosLCD()
{
 lcd.setCursor(0,1);
 lcd.print("Peso1 = ");
 lcd.setCursor(8,1);
 lcd.print(pesogato1);
 lcd.setCursor(11,1);
 lcd.print("Kg");
 lcd.setCursor(0,2);
 lcd.print("Peso2 = ");
 lcd.setCursor(8,2);
 lcd.print(pesogato2);
 lcd.setCursor(11,2);
 lcd.print("Kg");
 lcd.setCursor(0,3);
 lcd.print("T=");
 lcd.setCursor(2,3);
 lcd.print(temperatura);
 lcd.setCursor(6,3);
 lcd.print("C");
 lcd.setCursor(9,3);
 lcd.print("H=");
 lcd.setCursor(11,3);
 lcd.print(humedad);
 lcd.setCursor(13,3);
 lcd.print("%");
}

void EnviarTemperatura()
{
Serial.print("TEMPERATURA: ");
Serial.print(temperatura); //Envía el dato de Temperatura por el puerto Serie0 al PC
Serial.println("ºC");
Serial1.print(temperatura); //Envía el dato de Temperatura por el puerto Serie1 al Smartphone
}

void EnviarHumedad()
{
Serial.print("HUMEDAD: ");
Serial.print(humedad);
Serial.println("%");  // Envía el dato de Humedad por el puerto Serie0 al PC
Serial1.print(humedad); // Envía el dato de Humedad por el puerto Serie1 al Smartphone
}

void EnviarAgua()
{
Serial.print("NIVEL AGUA: ");
Serial.println(nivelagua); // Envía el dato de nivel de agua  por el puerto Serie0 al PC
Serial1.print(nivelagua); // Envía el dato de nivel de agua por el puerto Serie1 al Smartphone
}

void EnviarComida()
{
Serial.print("NIVEL COMIDA: ");
Serial.print(nivelcomida); // 
Serial.println("cm");  // Envía el dato de nivel de comida por el puerto Serie0 al PC
Serial1.print(nivelcomida); // Envía el dato de nivel de comida por el puerto Serie1 al Smartphone
}

void sensorDataSend()
{  
Blynk.virtualWrite(V0,temperatura); // leo el pin virtual V0
Blynk.virtualWrite(V1,nivelagua);
Blynk.virtualWrite(V2,nivelcomida);
Blynk.virtualWrite(V3,humedad);
Blynk.virtualWrite(V5,pesogato1);
Blynk.virtualWrite(V6,pesogato2);
}

I have tried adding the following code but doing this keeps the servo inactive even when approaching the RFID tag :

´´´
BLYNK_WRITE(V4) // Executes when the value of virtual pin 4 changes
{
if(param.asInt() == 1)
{
servocomida.write(45); //Servo start
}
if(param.asInt() == 0)
{
servocomida.write(90); //Servo stop
}
}

Well, you void loop is still a disaster area, so you clearly didn’t understand the “keep your void loop CLEAN” article that I provided.

There is no point in using BlynkTimer and then doing millis() comparisons to trigger functions. Remove the millis() stuff and use BlynkTimer instead.

You also have a considerable number of delay() commands in your sketch, and as the “keep your void loop…” article explains these are not allowed when using Blynk.

You’ve not made any changes to the Blynk.logEvent() code, so once you do get this sketch online you could exceed your daily limit of 100 events per 24 hour period within 16 minutes of being online.

You’ve chosen to ignore this…

and seem to have mis-understood this…

To be able to achieve this suggestion, you first of all have to strip-out all of the code that is not essential to getting online with Blynk using your hardware. That means you are probably looking at a sketch like this…

as your starting-point.

Pete.

Clearly I am lacking the knowledge of coding Arduino and Blynk efficiently. I will try to use Blynk timers instead of millis.

Regarding the Blynk.logEvent(), are you sure I would exceed the daily limit so quickly if there are only 2 Events which are both conditioned with an if that will rarely happen? Am I missing other events in the code?

if(nivelagua<1 && millis() - tiempoagua > 10000)
    {
     Serial.print("Nivel BAJO de agua en bebedero:");
     Serial.println(nivelagua);
     Blynk.logEvent("poca_agua");
     tiempoagua = millis();
    }
  if(nivelcomida>10 && millis() - tiempocomida > 10000)
    {
    Serial.println("Nivel BAJO de comida en contenedor!");
    Serial1.print("Poca Comida!");
    Blynk.logEvent("poca_comida");
    tiempocomida = millis();
    }

but when they do happen your code will send an event every 10 seconds.
Either event only needs to exist for 100 x 10 seconds (16 minutes) and you will have exceed your daily limit.
This is sloppy coding, and simple to fix by using a flag as explained in the tutorial I linked you to.

Pete.