Go Down

Topic: Problema con proyecto caudalimetro y salida pulsos para automata (Read 1 time) previous topic - next topic

Zharion

Buenas, el proyecto que estoy realizando en un arduino uno, es para medir el flujo de agua con un Caudalímetro con sensor de flujo YF-S201 y una pantalla LCD 2004 para visualizar la cantidad de agua. Hasta aquí todo correcto, he mirado por internet ejemplos por internet y he conseguido leer la información del sensor de flujo YF-S201 y sacar la informacion en la pantalla LCD 2004, es problema es cuando conecto un relé de estado solido y la idea es que cada 450 pulsaciones del sensor YF-S201 que equivale a 1 litro de agua, se produzca una pulsación del rele en estado solido, el problema es que no hace dicha pulsación en salida para activar dicho relé, lo he mirado varias veces el programa y mirado ejemplo en bastantes sitios pero no consigo hacer funcionar la salida.

Os pongo el programa que tengo realizado en el arduino uno.

Code: [Select]
/*  TITULO: Caudalímetro con sensor de flujo YF-S201 y LCD 2004.
   
    DESCRIPCIÓN DEL PROGRAMA

    Con este programa vamos a poder medir el caudal de agua en L/hora, así como el volumen total en litros  que pasa por el sensor, visualizando los valores a través de un LCD 2004.


    ESQUEMA DE CONEXION

                                      +-----+
         +----[PWR]-------------------| USB |--+
         |                            +-----+  |
         |         GND/RST2  [ ][ ]            |
         |       MOSI2/SCK2  [ ][ ]  A5/SCL[ ] |   
         |          5V/MISO2 [ ][ ]  A4/SDA[ ] |   
         |                             AREF[ ] |
         |                              GND[ ] |
         | [ ]N/C                    SCK/13[ ] |
         | [ ]IOREF                 MISO/12[ ] |
         | [ ]RST                   MOSI/11[ ]~|
         | [ ]3V3    +---+               10[ ]~|
         | [ ]5v    -| A |-               9[ ]~|
         | [ ]GND   -| R |-               8[X] |   [Pin salida2] Salida a relé estado solido (señal a automata)
         | [ ]GND   -| D |-                    |
         | [ ]Vin   -| U |-               7[X] |   [Pin salida1] Salida a relé estado solido (señal a automata)
         |          -| I |-               6[ ]~|
         | [ ]A0    -| N |-               5[ ]~|
         | [ ]A1    -| O |-               4[ ] |
         | [ ]A2     +---+           INT1/3[X]~|   Cable amarillo del sensor 2 de flujo YF-S201
         | [ ]A3                     INT0/2[X] |   Cable Amarillo del sensor 1 de flujo YF-S201
 SDA     | [X]A4/SDA  RST SCK MISO     TX>1[ ] |
 SCL     | [X]A5/SCL  [ ] [ ] [ ]      RX<0[ ] |
         |            [ ] [ ] [ ]              |
         |  UNO_R3    GND MOSI 5V  ____________/
          \_______________________/

  NOTAS:

     - La alimentación y la masa del módulo LCM 2004 I2C V1 van directamente conectadas a VCC (+5V) y GND  respectivamente.
     - Conexiones del sensor de flujo YF-S201:
     - Cable Rojo -> +5V de Arduino.
     - Cable Negro -> GND de Arduino.
     - Cable Amarillo del sensor 1 de flujo YF-S201 a pin 2
     - Cable amarillo del sensor 2 de flujo YF-S201 a pin 3
     - Conexiones del Rele Estado Solido (cantidad 2 reles)
     - Conexión de polo negativo a GND de arduino
     - Conexion de polo positivo a respectivo pin 7 y 8 

 - Conexiones del Rele Estado Solido (cantidad 2 reles)
     - Conexión de polo negativo a GND de arduino
     - Conexion de polo positivo a pin 7 [/tt][Pin salida2] Salida a relé estado solido (señal a automata)
     - Conexión de polo positivo a pin 8 [Pin salida2] Salida a relé estado solido (señal a automata)
 - Conexiones pantalla LCD
     - A4 - SDA
     - A5 - SCL
*/

// Importar librerías

#include <Wire.h> // Librería comunicación I2C
#include <LiquidCrystal_I2C.h> // Librería LCD I2C

// Declaración del objeto para el LCD
// Poner la dirección del LCD a 0x20 para display 20x4 (A0=0, A1=0, A2=0)
// Terminales de conexión del LCD
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int sensor1       = 2;            // Pin digital para el sensor de flujo YF-S201
int litros_Hora1;                       // Variable que almacena el caudal (L/hora)
volatile int pulsos1    = 0;            // Variable que almacena el número de pulsos
unsigned long tiempoAnterior1     = 0;  // Variable para calcular el tiempo transcurrido
unsigned long pulsos_Acumulados1  = 0;  // Variable que almacena el número de pulsos acumulados
float litros1;                          // Variable que almacena el número de litros acumulados
const int sensor2       = 3;            // Pin digital para el sensor de flujo YF-S201
int litros_Hora2;                       // Variable que almacena el caudal (L/hora)
volatile int pulsos2    = 0;            // Variable que almacena el número de pulsos
unsigned long tiempoAnterior2     = 0;  // Variable para calcular el tiempo transcurrido
unsigned long pulsos_Acumulados2  = 0;  // Variable que almacena el número de pulsos acumulados
float litros2;                          // Variable que almacena el número de litros acumulados
int salida1             = 7;            // Señal salida arduino hacia automata de contador decanter 1
int salida2             = 8;            // Señal salida arduino hacia automata de contador decanter 2
int Contador1;
int Contador2;

// Rutina de servicio de la interrupción (ISR)
void flujo1() {
    Pulsos1++; // Incrementa en una unidad el número de pulsos
}

void flujo2() {
    pulsos2++; // Incrementa en una unidad el número de pulsos
}

void setup() {
  pinMode(sensor1, INPUT_PULLUP);       // Pin digital como entrada con conexión PULL-UP interna
  pinMode(sensor2, INPUT_PULLUP);       // Pin digital como entrada con conexión PULL-UP interna
  pinMode(salida1, OUTPUT);             // Pin digital como salida
  pinMode(salida2, OUTPUT);             // Pin digital como salida
  lcd.init();
  lcd.backlight();
  interrupts();                         // Habilito las interrupciones

  // Interrupción INT0, llama a la ISR llamada "flujo" en cada flanco de subida en el pin digital 2
  attachInterrupt(digitalPinToInterrupt(sensor1), flujo1, RISING);
  attachInterrupt(digitalPinToInterrupt(sensor2), flujo2, RISING);
 
  tiempoAnterior1 = millis(); // Guardo el tiempo que tarda el ejecutarse el setup
  tiempoAnterior2 = millis(); // Guardo el tiempo que tarda el ejecutarse el setup
}

void loop ()
{
  // Cada segundo calculamos e imprimimos el caudal y el número de litros consumidos
  if (millis() - tiempoAnterior1 > 1000)
     if (millis() - tiempoAnterior2 > 1000)   {
        // Realizo los cálculos
        tiempoAnterior1     = millis(); // Actualizo el nuevo tiempo
        pulsos_Acumulados1 += pulsos1; // Número de pulsos acumulados
        litros_Hora1        = (pulsos1 * 60 / 7.5); // Q = frecuencia * 60/ 7.5 (L/Hora)
        litros1             = pulsos_Acumulados1 * 1.0 / 450; // Cada 450 pulsos son un litro
        pulsos1             = 0; // Pongo nuevamente el número de pulsos a cero
        // Realizo los cálculos
        tiempoAnterior2     = millis(); // Actualizo el nuevo tiempo
        pulsos_Acumulados2 += pulsos2; // Número de pulsos acumulados
        litros_Hora2        = (pulsos2 * 60 / 7.5); // Q = frecuencia * 60/ 7.5 (L/Hora)
        litros2             = pulsos_Acumulados2 * 1.0 / 450; // Cada 450 pulsos son un litro
        pulsos2             = 0; // Pongo nuevamente el número de pulsos a cero

        // Llamada a la función que muestra los resultados en el LCD 2004
        LCD_2004();
    }
 
  if (digitalRead(sensor1) ==HIGH) {
      if (digitalRead(sensor1) == LOW) {
          Contador1++;
          delay(50); 
      }
  }
 
  if (Contador1 == 450) {
      digitalWrite(salida1,HIGH);
      Contador1=0;
      delay(50);
      digitalWrite(salida1,LOW);
  }

  if (digitalRead(sensor2) ==HIGH) {
      if (digitalRead(sensor2) ==LOW) {
          Contador2++;
          delay(50); 
      }
  }

  if (Contador2==450){
      digitalWrite(salida2,HIGH);
      Contador2=0;
      delay(50);
      digitalWrite(salida2,LOW);
  } 
}

// Función que muestra los resultados en el LCD 2004
void LCD_2004() {
  // Imprimo la cabecera del sistema
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("         DECANTER 1");
  lcd.setCursor(0, 2);
  lcd.print("DECANTER 2");
  // Presento los valores a través del LCD 2004
  lcd.setCursor(9, 1);
  // Imprimo el caudal en L/hora
  lcd.print(litros_Hora1, DEC);
  lcd.print(" L/Hora");
  lcd.setCursor(0, 3);
  // Imprimo el caudal en L/hora
  lcd.print(litros_Hora2, DEC);
  lcd.print(" L/Hora");
}

jafox007

Hola, yo creo que hay que revisar los if anidados, por ejemplo

Code: [Select]
  if(digitalRead(sensor1) ==HIGH)
    {
      if (digitalRead(sensor1) ==LOW)
        {
          Contador1++;
          delay(50);
         }
    }


en este codigo el sensor 1 tiene que estar en high y justo al entrar al if pasar a low, si no se salta el contador++, no se si me explico bien.

Zharion

esta puesto asi por que la idea es que cuando sensor pasa de high a low es cuando hace el contaje, al menos esa era mi idea

jafox007

Eso se llama Flanco de bajada, mirate este hilo y nos cuentas.

surbyte

No entiendo para que vuelves a controlar los flancos si para eso tienes las interrupciones.
pulsos1 y pulsos2 cuentan sin errores los pulsos
Cada 450 pulsos tienes 1 litro y quieres comandar el rele
Pues bien, dentro de los primeros if donde calculas el caudal tomas la decisión porque estas haciendo lo mismo luego pero con errores.

Lo mejor sería usar las interrupcciones para no perder pulsos.

Code: [Select]

// esto en globales
volatile int pulsos1L   = 0;
volatile int pulsos2L   = 0;
bool fSalida1 = false;
bool fSalida2 = false;

// estas son las dos rutinas de interrupción modificadas.
// Rutina de servicio de la interrupción (ISR)
void flujo1() {
    Pulsos1++; // Incrementa en una unidad el número de pulsos
    if (pulsos1L++==450) {
        fSalida1 = true;
        pulsos1L = 0;
    }
}

void flujo2() {
    pulsos2++; // Incrementa en una unidad el número de pulsos
    if (pulsos2L++==450) {
        fSalida2 = true;
        pulsos2L = 0;
    }


}

// en el loop

void loop ()
{
  // Cada segundo calculamos e imprimimos el caudal y el número de litros consumidos
  if (millis() - tiempoAnterior1 > 1000)
     if (millis() - tiempoAnterior2 > 1000)   {
        // Realizo los cálculos
        tiempoAnterior1     = millis(); // Actualizo el nuevo tiempo
        pulsos_Acumulados1 += pulsos1; // Número de pulsos acumulados
        litros_Hora1        = (pulsos1 * 60 / 7.5); // Q = frecuencia * 60/ 7.5 (L/Hora)
        litros1             = pulsos_Acumulados1 * 1.0 / 450; // Cada 450 pulsos son un litro
        pulsos1             = 0; // Pongo nuevamente el número de pulsos a cero
        // Realizo los cálculos
        tiempoAnterior2     = millis(); // Actualizo el nuevo tiempo
        pulsos_Acumulados2 += pulsos2; // Número de pulsos acumulados
        litros_Hora2        = (pulsos2 * 60 / 7.5); // Q = frecuencia * 60/ 7.5 (L/Hora)
        litros2             = pulsos_Acumulados2 * 1.0 / 450; // Cada 450 pulsos son un litro
        pulsos2             = 0; // Pongo nuevamente el número de pulsos a cero

        // Llamada a la función que muestra los resultados en el LCD 2004
        LCD_2004();
    }
 
  if (fSalida1){
      digitalWrite(salida1,HIGH);
      delay(50);
      digitalWrite(salida1,LOW);
      fSalida1 = false;
  } 

  if (fSalida2){
      digitalWrite(salida2,HIGH);
      delay(50);
      digitalWrite(salida2,LOW);
      fSalida2 = false;
  } 
}

Go Up