No repite parte del loop RELE

Hola, soy novato en tema programacion y queria saber si alguien puede ayudarme con mi codigo.
Copie de una pagina la programacion para funcionar un caudalimetro con rele de corte. Para hacerlo funcionar tengo que ingresar la letra r dentro del puerto serie una vez que finaliza la tarea corta y puedo repetirla sin problemas. El problema viene que necesito programar 4 rele. Por el momento hice funcionar 2 en el mismo codigo pero a la hora de ejecutar el rele2 con un pusaldor ejecuta la tarea sin problemas y finaliza pero no la puedo repetir con el pusaldor y en el monitor serie aparece C⸮ .

Adjunto codigo:

volatile int NumPulsos; //variable para la cantidad de pulsos recibidos
volatile int NumPulsos2; //variable para la cantidad de pulsos recibidos Rele2
int PinSensor = 2;    //Sensor conectado en el pin 2
int PinSensor2 = 3;   //Sensor2 conectado en el pin 3  
int PULSADOR2 = 8;         // Reinicio RELE2
int RELE = 7;         //Rele 1 (Reles del 7 al 4)
int RELE2 = 6;        //Rele 2
int LITRO;            //Variable de corte de agua
int LITRO2;            //Variable de corte de agua Rele2
float factor_conversion=6.1; //para convertir de frecuencia a caudal
float factor_conversion2=5.12; //para convertir de frecuencia a caudal Rele 2
float volumen=0;
float volumen2=0;
long dt=0; //variación de tiempo por cada bucle
long dt2=0; //variación de tiempo por cada bucle Rele2
long t0=0; //millis() del bucle anterior 
long t2=0; //millis() del bucle anterior Rele2
//---Función que se ejecuta en interrupción---------------
void ContarPulsos () 
{ 
  NumPulsos++;  //incrementamos la variable de pulsos
} 

void ContarPulsos2 ()
{ 
     NumPulsos2++;  //incrementamos la variable de pulsos Rele 2
} 

//---Función para obtener frecuencia de los pulsos--------
int ObtenerFrecuecia() 
{
  int frecuencia;
  NumPulsos = 0;   //Ponemos a 0 el número de pulsos
  interrupts();    //Habilitamos las interrupciones
  delay(1000);   //muestra de 1 segundo
  noInterrupts(); //Deshabilitamos  las interrupciones
  frecuencia=NumPulsos; //Hz(pulsos por segundo)
  return frecuencia;
}

//---Función para obtener frecuencia de los pulsos RELE2--------
int ObtenerFrecuecia2() 
{
  int frecuencia2;
  NumPulsos2 = 0;   //Ponemos a 0 el número de pulsos
  interrupts();    //Habilitamos las interrupciones
  delay(1000);   //muestra de 1 segundo
  noInterrupts(); //Deshabilitamos  las interrupciones
  frecuencia2=NumPulsos2; //Hz(pulsos por segundo)
  return frecuencia2;
}
void setup() 
{ 
  
  Serial.begin(9600); 
  pinMode(PinSensor, INPUT); 
  pinMode(PinSensor2, INPUT);
  pinMode(PULSADOR2, INPUT);
  pinMode(RELE, OUTPUT);
  pinMode(RELE2, OUTPUT);
  attachInterrupt(0,ContarPulsos,RISING);//(Interrupción 0(Pin2),función,Flanco de subida)
  attachInterrupt(1,ContarPulsos2,RISING);//(Interrupción 0(Pin3),función,Flanco de subida)
  Serial.println ("Envie 'r' para restablecer el volumen a 0 Litros"); 
  t0=millis();
  t2=millis();
  } 

void loop ()    
{
  if (Serial.available()>0){ 
    if(Serial.read()=='r')volumen=0, digitalWrite (RELE, HIGH);//restablecemos el volumen si recibimos 'r'
  }
  {
    if (digitalRead(PULSADOR2) == HIGH){
      volumen2=0, digitalWrite(RELE2, HIGH);
    }
  }
  float frecuencia=ObtenerFrecuecia(); //obtenemos la frecuencia de los pulsos en Hz
  float caudal_L_m=frecuencia/factor_conversion; //calculamos el caudal en L/m
  dt=millis()-t0; //calculamos la variación de tiempo
  t0=millis();
  volumen=volumen+(caudal_L_m/60)*(dt/1000); // volumen(L)=caudal(L/s)*tiempo(s)
  {
    LITRO=volumen; //declaramos la variable volumen para hacer la comparacion
    if (LITRO >= 1){ //comparamos si la variable LITRO es igual o mayor a 1 litro
      digitalWrite(RELE, LOW);
    }
  }
  float frecuencia2=ObtenerFrecuecia2(); //obtenemos la frecuencia de los pulsos en Hz RELE2 
  float caudal_L_m2=frecuencia2/factor_conversion2; //calculamos el caudal en L/m RELE2
  dt2=millis()-t2; //calculamos la variación de tiempo RELE2 
  t2=millis();
  volumen2=volumen2+(caudal_L_m2/60)*(dt2/1000); //volumen(L)=caudal(L/s)*tiempo(s) RELE2
  {
    LITRO2=volumen2; //declaramos la variable volumen para hacer la comparacion RELE2
    if (LITRO2 >= 1){ //comparamos si la variable LITRO es igual o mayor a 1 litro RELE2
      digitalWrite(RELE2, LOW);
    }
  }
{

}
   //-----Enviamos por el puerto serie---------------
  Serial.print('\n'); //comando para el sato de linea
  Serial.print ("Caudal RELE1: "); 
  Serial.print (caudal_L_m,3); 
  Serial.print ("L/min\tVolumen: "); 
  Serial.print (volumen,3); 
  Serial.print (" L\t Litros: ");  
  Serial.println (LITRO);
  //Serial.print("\r"); //comando para el sato de linea con retorno de acarreo PROBAR
  
  Serial.print('\n'); //comando para el sato de linea
  Serial.print ("Caudal RELE2: "); 
  Serial.print (caudal_L_m2,3); 
  Serial.print ("L/min\tVolumen: "); 
  Serial.print (volumen2,3); 
  Serial.print (" L\t Litros: ");  
  Serial.println (LITRO2);
}

Gracias

Tenés unos cuantos errores, principalmente llaves donde no van.

Hay cosas de las que has copiado con las que no coincido, por ahora te corregí las llaves, probalo así a ver si va mejor

volatile int NumPulsos; //variable para la cantidad de pulsos recibidos
volatile int NumPulsos2; //variable para la cantidad de pulsos recibidos Rele2
int PinSensor = 2;    //Sensor conectado en el pin 2
int PinSensor2 = 3;   //Sensor2 conectado en el pin 3  
int PULSADOR2 = 8;         // Reinicio RELE2
int RELE = 7;         //Rele 1 (Reles del 7 al 4)
int RELE2 = 6;        //Rele 2
int LITRO;            //Variable de corte de agua
int LITRO2;            //Variable de corte de agua Rele2
float factor_conversion=6.1; //para convertir de frecuencia a caudal
float factor_conversion2=5.12; //para convertir de frecuencia a caudal Rele 2
float volumen=0;
float volumen2=0;
long dt=0; //variación de tiempo por cada bucle
long dt2=0; //variación de tiempo por cada bucle Rele2
long t0=0; //millis() del bucle anterior 
long t2=0; //millis() del bucle anterior Rele2
//---Función que se ejecuta en interrupción---------------
void ContarPulsos () 
{ 
  NumPulsos++;  //incrementamos la variable de pulsos
} 

void ContarPulsos2 ()
{ 
     NumPulsos2++;  //incrementamos la variable de pulsos Rele 2
} 

//---Función para obtener frecuencia de los pulsos--------
int ObtenerFrecuecia() 
{
  int frecuencia;
  NumPulsos = 0;   //Ponemos a 0 el número de pulsos
  interrupts();    //Habilitamos las interrupciones
  delay(1000);   //muestra de 1 segundo
  noInterrupts(); //Deshabilitamos  las interrupciones
  frecuencia=NumPulsos; //Hz(pulsos por segundo)
  return frecuencia;
}

//---Función para obtener frecuencia de los pulsos RELE2--------
int ObtenerFrecuecia2() 
{
  int frecuencia2;
  NumPulsos2 = 0;   //Ponemos a 0 el número de pulsos
  interrupts();    //Habilitamos las interrupciones
  delay(1000);   //muestra de 1 segundo
  noInterrupts(); //Deshabilitamos  las interrupciones
  frecuencia2=NumPulsos2; //Hz(pulsos por segundo)
  return frecuencia2;
}
void setup() 
{ 
  
  Serial.begin(9600); 
  pinMode(PinSensor, INPUT); 
  pinMode(PinSensor2, INPUT);
  pinMode(PULSADOR2, INPUT);
  pinMode(RELE, OUTPUT);
  pinMode(RELE2, OUTPUT);
  attachInterrupt(0,ContarPulsos,RISING);//(Interrupción 0(Pin2),función,Flanco de subida)
  attachInterrupt(1,ContarPulsos2,RISING);//(Interrupción 0(Pin3),función,Flanco de subida)
  Serial.println ("Envie 'r' para restablecer el volumen a 0 Litros"); 
  t0=millis();
  t2=millis();
} 

void loop ()    
{
  if (Serial.available()>0){ 
    if(Serial.read()=='r'){
      volumen=0;
      digitalWrite (RELE, HIGH);//restablecemos el volumen si recibimos 'r'
    }
  }
  if (digitalRead(PULSADOR2) == HIGH){
    volumen2=0;
    digitalWrite(RELE2, HIGH);
  }
  float frecuencia=ObtenerFrecuecia(); //obtenemos la frecuencia de los pulsos en Hz
  float caudal_L_m=frecuencia/factor_conversion; //calculamos el caudal en L/m
  dt=millis()-t0; //calculamos la variación de tiempo
  t0=millis();
  volumen=volumen+(caudal_L_m/60)*(dt/1000); // volumen(L)=caudal(L/s)*tiempo(s)
  LITRO=volumen; //declaramos la variable volumen para hacer la comparacion
  if (LITRO >= 1){ //comparamos si la variable LITRO es igual o mayor a 1 litro
      digitalWrite(RELE, LOW);
  }
  float frecuencia2=ObtenerFrecuecia2(); //obtenemos la frecuencia de los pulsos en Hz RELE2 
  float caudal_L_m2=frecuencia2/factor_conversion2; //calculamos el caudal en L/m RELE2
  dt2=millis()-t2; //calculamos la variación de tiempo RELE2 
  t2=millis();
  volumen2=volumen2+(caudal_L_m2/60)*(dt2/1000); //volumen(L)=caudal(L/s)*tiempo(s) RELE2
  LITRO2=volumen2; //declaramos la variable volumen para hacer la comparacion RELE2
  if (LITRO2 >= 1){ //comparamos si la variable LITRO es igual o mayor a 1 litro RELE2
      digitalWrite(RELE2, LOW);
  }

   //-----Enviamos por el puerto serie---------------
  Serial.print('\n'); //comando para el sato de linea
  Serial.print ("Caudal RELE1: "); 
  Serial.print (caudal_L_m,3); 
  Serial.print ("L/min\tVolumen: "); 
  Serial.print (volumen,3); 
  Serial.print (" L\t Litros: ");  
  Serial.println (LITRO);
  //Serial.print("\r"); //comando para el sato de linea con retorno de acarreo PROBAR
  
  Serial.print('\n'); //comando para el sato de linea
  Serial.print ("Caudal RELE2: "); 
  Serial.print (caudal_L_m2,3); 
  Serial.print ("L/min\tVolumen: "); 
  Serial.print (volumen2,3); 
  Serial.print (" L\t Litros: ");  
  Serial.println (LITRO2);
}

Saludos

gracias por tu respuesta, lo acabo de probar y ejecuta la tarea del RELE2 y termina sin problemas pero si quiero repetir dicha tarea no lo realiza apretando el pulsador. Te paso captura del mnitor serie con el simbolo nuevo que aparece al final.

La verdad que no termino de entender qué es lo que dices que no hace.
¿No se activa el relé 2?

Yo veo un gran problema con esos delay de 1 segundo que usas para muestrear, eso puede ser que evite que hagas lo que quieres.

si apreto de nuevo el pulsador del RELE2 no vuelve a ejecutar la tarea.

EN cambio si ejecuto la tarea del RELE1 ingresando la letra r por el monitor serie, puedo repetir la tarea las veces que quiera.
Mi problema es que no repite la tarea del RELE2 cuando finaliza.

Saludos

No nos entendemos...
La única tarea que hace el pulsador es poner volumen2 en 0 y poner la salida RELE2 en alto, que imagino que lo activa, nada más.

Por eso te pregunté ¿No activa el relé?
Mantén pulsado el botón por más de 2 segundos y dime si se activa.

cuando apreto el pulsador si activa el rele2, finaliza la tarea y funciona. Mi problema es que si quiero volver a repetir la tarea de presionar el boton y vuelva a encender el rele2 no lo hace. Para que vuelva a funcionar el boton tengo que volver a subir el codigo de arduino si quiero repetir la terea. Espero que se entienda. Saludos

Bueno, te cuento que lo simulé en Proteus

prueba

y funciona perfectamente.

Como no has subido tu circuito puse lo necesario para poder simular el funcionamiento del código.
En lugar de los relés puse LEDs pero a los fines de la simulación es lo mismo para ver que se activan las salidas. Y puse generadores de pulsos porque desconozco que es lo que usas para generarlos.

Como ya te dije

Me refiero a los que usas en ObtenerFrecuencia() y ObtenerFrecuencia2().

Y además

No me respondiste si lo probaste o no, pero yo si lo hice y tal como estaba previsto reacciona solo si lo mantienes pulsado, ya que por causa de los delays no lo va a leer hasta que no pasen esos 2 segundos y se repita el loop().

Y no te engañes, con la entrada por serial ocurre lo mismo pero como la "r" queda en el buffer serie la lee cuando puede.
¿Por qué crees que la impresión ocurre cada 2 segundos aproximadamente y no continuamente?
Eso ya te tendría que haber hecho sospechar que algo no deja que el código fluya libremente.

Por otro lado,

imagino que fue una exageración de tu parte ya que antes que eso siempre puedes simplemente pulsar el botón de Reset, ¿no?

Replantea esas dos funciones o llámalas solo cuando activas los relés para que no esté cada pocos microsegundos ejecutando los delays (que como sabrás, detienen la ejecución del programa).

Saludos

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.