Proceso Ciclico de un Relé

Buenas Tardes a todos,

Estoy implicado en un proyecto en el que objetivo es dosificar una cantidad concreta de liquido cada 3 segundos, la dosificación del liquido se realiza mediante una bomba peristaltica cuyo interior he alojado un pequeño switch que se va pulsando mediante los rodillos de la bomba, de tal modo que cuando cuando cuenta 4 pulsaciones la bomba ha girado una vuelta completa (que serian en este caso 10ml de liquido).

La bomba se activa inicialmente mediante un relé que lo activo a través de un pulsador, solo la primera pulsación, después la idea es que se repita la dosificación del liquido cada 3 segundo automáticamente.

No se si me he explicado bien, os dejo el código que he realizado, con el cual solo consigo dosificar una vez al pulsar el Boton.

const int botonlimpieza = 9;

const int botonswitch = 8; 

const int relay1 = 7;

bool flagBomba;

unsigned long ahora = 0;

bool valorBoton1, valorBotonAnt1 = false; 

bool valorBoton2, valorBotonAnt2 = false;

int contador = 0;


void setup() {
   
  pinMode(botonlimpieza,INPUT);
  
  pinMode(botonswitch,INPUT);

  pinMode(relay1,OUTPUT);

}

void loop() {
  
valorBoton1 = digitalRead(botonlimpieza);
valorBoton2 = digitalRead(botonswitch);

  if (valorBoton1 && !valorBotonAnt1) {
     flagBomba1 = true;       
  }
  valorBotonAnt1 = valorBoton1;

delay(10);

  if (valorBoton2 && !valorBotonAnt2){
      contador++;
          if (contador >= 4) {
              flagBomba = false;
              contador = 0;
          } 
  }
 
  valorBotonAnt2 = valorBoton2;


  if (flagBomba1 == true){
      digitalWrite(relay1, LOW);
       }  
  else{
    while (millis()-ahora<=3000){
      digitalWrite(relay1, HIGH); 
      
   ahora=millis();
       
}
}
}

Muchísimas gracias de antemano por vuestra atención.

Alguna sugerencia de alguien??

Sugerencia: máquinas de estados. Usar millis() dentro de un while, tal como lo usas, es lo mismo que usar un delay().

no debes usar while, eso es para cosas muy concretas:

const int botonlimpieza = 9;

const int botonswitch = 8; 

const int relay1 = 7;

bool flagBomba = false ; // es buena practica no dejar nada al azar 

unsigned long ahora = 0;

bool valorBoton1, valorBotonAnt1 = false; 

bool valorBoton2, valorBotonAnt2 = false;

int contador = 0;


void setup() {
   
  pinMode(botonlimpieza,INPUT);
  
  pinMode(botonswitch,INPUT);

  pinMode(relay1,OUTPUT);

}

void loop() {
  
valorBoton1 = digitalRead(botonlimpieza);
valorBoton2 = digitalRead(botonswitch);

  if (valorBoton1 && !valorBotonAnt1) {
     flagBomba1 = true;       
  }
  valorBotonAnt1 = valorBoton1;

//delay(10); quita los delays, para que el codigo sea mas preciso 

  if (valorBoton2 && !valorBotonAnt2){
      contador++;
          if (contador >= 4) {
              flagBomba = false;
              contador = 0;
          } 
  }
 
  valorBotonAnt2 = valorBoton2;


  if (flagBomba1 == true)  // yo lo escribiria al reves por que la bomba espera el tiempo, pero ya tu veras.
{
      digitalWrite(relay1, LOW);
       }  
else{
      if(millis()-ahora<=3000)
       {
           digitalWrite(relay1, HIGH);       
           ahora=millis();       
      }
}
}

-Alex.

Que realmente yo te recomendaria cambiar el codigo a algo mas estructurado como un switch case:

//pseudo codigo 

swith (case) 
caso 0: // inicio aqui
relay on 
caso = caso1; //me paso al siguiente escenario 

caso 1: 
// se han detectado 4 cambios en el switch? 
if( switch == 4) caso = 2; // me paso al siguiente 

caso 2: 
//me espero 4 segundos, vuelvo al incio 
if( milis - tiempo > 3 segundos) 
caso: case 0;

Espero te ayude.
-Alex.

Como ya te he comentado, airmounir, la solución pasa por usar máquinas de estados y millis(). Y en tu caso nada de for() ni de while().

Hay un par de cosas que no tengo claro de lo que planteas. Hablas de un pulsador para poner en marcha el sistema, pero no dices nada de cómo o cuándo ha de pararse completamente.

Otra cosa que me llama la atención es que me parece que tu programa no mira si ese pulsador está pulsado o no, sino que simplemente verifica que hay un cambio de estado. En principio no tiene mucha importancia, pero lo habitual es verificar el estado, no el cambio. Y para verificar si está pulsado o no, se ha de saber cómo está conectado.

Creo que haces algo similar con el switch, que miras que cambie 4 veces de estado, que no es lo mismo que cuatro pulsos. Un pulso se supone que tiene dos cambios de estado.

Otro detalle es que hablas de que se repita cada 3 segundos. ¿Ha de entenderse que cada tres segundos ha de iniciar una dosis o que una vez terminada una dosis ha de esperar tres segundos para empezar una nueva dosis? No sé si entiendes esta duda. Por ejemplo: si una dosis dura dos segundos, no es lo mismo esperar un segundo para comenzar la siguiente dosis (eso sería una dosis cada tres segundos), que esperar tres segundos antes de empezar la siguiente dosis (eso sería una dosis cada cinco segundos).