Llenador de Botellas. Caudalimetro + Electrovalvula

Hola querida gente de arduino hace poco me estoy metiendo en lo que es el mundo de Arduino.
Mi proyecto en si es hacer un llenador de botellas que en teoría corte solo al llegar por ejemplo a 500ml.

Conectando el caudalimetro con una pantalla LCD me marca cuantos litros han pasado y tengo un código para que haga eso...

Pero lo que yo necesito es que por ejemplo cuando llegue a 500ml la electrovalvula se corte. no es necesario que sea taaaan preciso porque es obvio que no lo va a ser, pero masomenos un estimado.. se que es posible, pero la verdad no se me ocurre como..

También lo que estaría genial sería adicionarle un teclado numero que por ejemplo poniendo

1 + # se llene una botella a 500ml
2 + # se llene una botella con 1L
y así sucesivamente

Espero me puedan ayudar, muchas gracias :slight_smile:

Se me ocurren dos cosas ,aprovechar los pulsos que pueda darte el caudalimetro para ir contandolos y sabiendo que cantidad de liquido equivale cada pulso ,pues seria cuestion de multiplicar y comparar (y eso ya lo estas haciendo si te marca los litros en la lcd) y la segunda hacerlo por tiempo cronometrando el tiempo de llenado hasta la cantidad que necesites y que la electrovalvula funcione durante ese tiempo.Lo del menu lo veo facil ,te haces un array de caracteres para las cantidades y un array de byte/int/long segun lo que guardes, que se correspondan con los tiempos que has calculado o con los pulsos que equivalentes a las cantidades y aprovechas la lcd para hacer el menu junto con uno o dos pulsadores.

jose:
Se me ocurren dos cosas ,aprovechar los pulsos que pueda darte el caudalimetro para ir contandolos y sabiendo que cantidad de liquido equivale cada pulso ,pues seria cuestion de multiplicar y comparar (y eso ya lo estas haciendo si te marca los litros en la lcd) y la segunda hacerlo por tiempo cronometrando el tiempo de llenado hasta la cantidad que necesites y que la electrovalvula funcione durante ese tiempo.Lo del menu lo veo facil ,te haces un array de caracteres para las cantidades y un array de byte/int/long segun lo que guardes, que se correspondan con los tiempos que has calculado o con los pulsos que equivalentes a las cantidades y aprovechas la lcd para hacer el menu junto con uno o dos pulsadores.

Por tiempo no me serviría porque no es para pasar solamente agua.. Cuando pase algun liquido un poco mas espeso ya no me serviria y no puedo estar poniendo un tiempo diferente para cada liquido jajaja, como te comentaba tengo el codigo que te muestra en pantalla los litros que pasan y anoche consegui un codigo de algo similar a lo que busco..

Apretando un boton larga cierta cantidad de agua, lo unico que no tiene es que aparezcan los datos en la LCD.

Si alguien es tan amable, puedo pasar el codigo que conseguí y le agregan que muestre en la lcd lo que pasa..

Usa los pulsos del caudalímetro para tener un margen de maniobra. Ni siquiera necesitas traducirlos a litros. Tu sabras para monitereo que son tal cosa pero internamiente saber que a los 1222 pulsos ya tienes la botella llena es mejor que usar un valor que por redondeo de mas error.
Tu control dira.. si es mayor a 1222 pulsos entonces detener el llenado
Asi que será lo mismo que lo haga a los 1223 o 1225.
Igualmente no creo que pase si lo programas bien y no usas delay().

Resumiendo, haz las conversiones para que el operador sepa el caudal pero las operaciones de control lo haces sin ellas.
Se comprende?

surbyte:
Usa los pulsos del caudalímetro para tener un margen de maniobra. Ni siquiera necesitas traducirlos a litros. Tu sabras para monitereo que son tal cosa pero internamiente saber que a los 1222 pulsos ya tienes la botella llena es mejor que usar un valor que por redondeo de mas error.
Tu control dira.. si es mayor a 1222 pulsos entonces detener el llenado
Asi que será lo mismo que lo haga a los 1223 o 1225.
Igualmente no creo que pase si lo programas bien y no usas delay().

Resumiendo, haz las conversiones para que el operador sepa el caudal pero las operaciones de control lo haces sin ellas.
Se comprende?

Si. No me interesa si es por pulsos o lo q sea. Sino que la electrovalvula corte a mi valor predeterminado

La electroválvula cortará en el valor que tu le indiques.
Pasa directamente a la prueba porque no requiere mucha ciencia.

Prueba el caudalímetro, asegurate que mide correctamente.
Luego prueba el rele y la electroválvula y asegúrate que su accionamiento no genere reseteos del Arduino.

Si eso ocurre debemos ver como alimentas la electroválvula y de que tipo es.
Si es de DC debe tener un diodo en antiparalelo. Si es de AC debe tener un snubber (Resistencias y capacitor de valores determinados).

[quote author=surbyte date=1486851575 link=msg=3127600]
La electroválvula cortará en el valor que tu le indiques.
Pasa directamente a la prueba porque no requiere mucha ciencia.

Prueba el caudalímetro, asegurate que mide correctamente.
Luego prueba el rele y la electroválvula y asegúrate que su accionamiento no genere reseteos del Arduino.

Si eso ocurre debemos ver como alimentas la electroválvula y de que tipo es.
Si es de DC debe tener un diodo en antiparalelo. Si es de AC debe tener un snubber (Resistencias y capacitor de valores determinados).

Muchisimas Gracias por tus respuestas.

Tengo este codigo que saque de un post.

// CONSTANTES
const int pinBoton = 7;         // Pin del Boton
const int pinLedRojo = 9;       // Pin del Led Rojo
const int pinLedAzul = 10;       // Pin del Led Azul
const int pinLedVerde = 11;      // Pin del Led Verde
const int pinRele = 12;          // Pin del Rele
const int pinCaudalimetro = 2;  // Pin del Caudalimetro
const int pinBotonStart = 13;    // Pin del Boton
const double TOPE3L = 3;  // Tope de señales para 3L
const double TOPE4L = 4;  // Tope de señales para 4L
const int ROJO = 1;
const int AZUL = 2;
const int VERDE = 3;

// VARIABLES
int estadoLed = 1;  // Led en Rojo
volatile int pulsos;
double caudalTope;
double litrosLeidos;

int estadoCaudalimetro;
int ultimoEstadoCaudalimetro;

int lectura;                   // Lectura boton
int estadoBoton;               // Lectura del boton
int ultimoEstadoBoton = HIGH;  // Lectura anterior del boton

long ultimoRebote = 0;  // Ultima vez que se presiono el boton
long delayRebote = 5;   // Tiempo de rebote

int lecturaSt;                   // Lectura boton
int estadoBotonSt;               // Lectura del boton
int ultimoEstadoBotonSt = HIGH;  // Lectura anterior del boton

long ultimoReboteSt = 0;  // Ultima vez que se presiono el boton
long delayReboteSt = 5;   // Tiempo de rebote

void setup() {

pinMode(pinBoton, INPUT);
pinMode(pinBotonStart, INPUT);
pinMode(pinLedRojo, OUTPUT);
pinMode(pinLedAzul, OUTPUT);
pinMode(pinLedVerde, OUTPUT);
pinMode(pinRele, OUTPUT);
pinMode(pinCaudalimetro, INPUT);

digitalWrite(pinLedRojo, HIGH);
digitalWrite(pinLedAzul, LOW);
digitalWrite(pinLedVerde, LOW);
caudalTope = TOPE3L;
attachInterrupt(0, leoPulsos, RISING); //Vinculo la interrupcion 0 a la funcion leoPulsos
Serial.begin(9600);
}

void leoPulsos () { // Esta funcion agrega un pulso cuando se detecta una interrupcion
pulsos++;
}

boolean debounce(boolean last, int pin) { // Función antirebote
boolean current = digitalRead(pin);

if (last != current) {
  delay(5);
  current = digitalRead(pin);
}
return current;
}

void loop() {

int lectura = digitalRead(pinBoton);

if (lectura != ultimoEstadoBoton) {
  ultimoRebote = millis();
}

if ((millis() - ultimoRebote) > delayRebote) {
  if (lectura != estadoBoton) {
    estadoBoton = lectura;

    if (estadoBoton == LOW) {
      switch (estadoLed) {
        case ROJO:
          digitalWrite(pinLedRojo, LOW);
          digitalWrite(pinLedAzul, HIGH);
          caudalTope = TOPE4L;
          estadoLed = AZUL;
          break;
        case AZUL:
          digitalWrite(pinLedAzul, LOW);
          digitalWrite(pinLedRojo, HIGH);
          caudalTope = TOPE3L;
          estadoLed = ROJO;
          break;
      }
    }
  }
}

int lecturaSt = digitalRead(pinBotonStart);

if (lecturaSt != ultimoEstadoBotonSt) {
  ultimoReboteSt = millis();
}

if ((millis() - ultimoReboteSt) > delayReboteSt) {
  if (lecturaSt != estadoBotonSt) {
    estadoBotonSt = lecturaSt;

    if (estadoBotonSt == LOW) {
      // ABRO ELECTROVALVULA
      digitalWrite(pinRele, HIGH);
      // SETEO EL LED EN VERDE - CARGA EN PROCESO
      digitalWrite(pinLedAzul, LOW);
      digitalWrite(pinLedRojo, LOW);
      digitalWrite(pinLedVerde, HIGH);
      pulsos = 0;
      litrosLeidos = 0;
      // CONTROLO LA CARGA        
      while (litrosLeidos < caudalTope) {
        sei();
        delay(1000); // Espero un segundo
        cli();
        litrosLeidos = litrosLeidos + ((pulsos / 5.5) / 60); // (Pulsos en un segundo) / 5.5Q, = tasa de flujo en LxM luego divido por 60 para saber cuantos litros pasaron en un segundo
        Serial.print (litrosLeidos, DEC); 
        Serial.print (" L/seg\r\n"); 
      }

      // CIERRO LA ELECTROVALVULA
      digitalWrite(pinRele, LOW);

      // APAGO EL LED VERDE
      digitalWrite(pinLedVerde, LOW);
      // SETEO EL LED EN EL ESTADO ANTERIOR
      if (estadoLed == ROJO) {
        digitalWrite(pinLedRojo, HIGH);
      } else {
        digitalWrite(pinLedAzul, HIGH);
      }
    }
  }
}

ultimoEstadoBoton = lectura;
ultimoEstadoBotonSt = lecturaSt;
}

Y me pareció genial. A mi parecer me funcionaria bien.

Tengo electrovalvula de 12v. Corriente Continua.
En base a ese código como puedo seleccionar que un tope sea por ejemplo 500ml?

coges 500 ml del liquido que quieras medir ,los metes por el circuito a traves del caudalimetro,miras cuantos pulsos te ha generado y ya sabes cual es tu objetivo.

Por favor, si un hilo dice que tiene mas de 120 dias sin movimientos no lo revivas!!
Crea un hilo nuevo pero no en esta sección por favor, sino en software o Hardware y si no sabes cual usar usa la sección General.
Ahora lee las normas del foro y luego crea un hilo con tu consulta.
Hilo cerrado, pregunta borrada poque no aporta nada al hilo en cuestión.