Problemas para mostrar datos serial y LCD al mismo tiempo

Buenas noches a todos. Primer post que realizo por aqui. Me presento soy nahuel de argentina y bueno estoy iniciando lentamente en el mundo del arduino, tenganme paciencia jaja.

Les comento que tengo un codigo para un caudalimetro que funciona sin problemas mostrando datos por el monitor serie. Ahora le quise agregar la visualizacion a travez de un LCD2004 I2C y tengo dos problemas, uno que al agregar la linea de codigo del LCD en el loop por debajo de las variables float me quedo sin datos en el serial monitor, y por otro lado tampoco logro ver datos en el lcd de lo que agregue. Ahora lo que esta antes del float si lo logro ver sin problemas tanto lo que esta anexado en el void loop como lo que esta en el void setup.

Cabe destacar que tanto el arduino MEGA2560 como el sensor de caudal YF-S201 como la pantalla I2C 2004 funcionan correctamente en forma separada. Osea ya lo eh usado con otros codigos y esta todo funcionando bien.

Hay algo que estoy haciendo mal, alguna linea omitida o mal posicionada. Desde ya agradezco cualquier ayuda que pueden darme.

Muchas gracias.

Dejo aqui el codigo original para serial monitor y mas abajo el codigo modificado para el LCD.

Saludos!

const int sensorPin = 18;
const int measureInterval = 1000;
volatile int pulseConter;

// YF-S201
const float factorK = 7.5;


void ISRCountPulse()
{
   pulseConter++;
}

float GetFrequency()
{
   pulseConter = 0;

   interrupts();
   delay(measureInterval);
   noInterrupts();

   return (float)pulseConter * 1000 / measureInterval;
}

void setup()
{
   Serial.begin(9600);
   attachInterrupt(digitalPinToInterrupt(sensorPin), ISRCountPulse, RISING);
}

void loop()
{
   // obtener frecuencia en Hz
   float frequency = GetFrequency();

   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;

   Serial.print("Frecuencia: ");
   Serial.print(frequency, 0);
   Serial.print(" (Hz)\tCaudal: ");
   Serial.print(flow_Lmin, 3);
   Serial.println(" (L/min)");
}

Codigo modificado LCD:

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

LiquidCrystal_I2C lcd(0x27,20,4);

const int sensorPin = 18;
const int measureInterval = 1000;
volatile int pulseConter;

// YF-S201
const float factorK = 7.5;


void ISRCountPulse()
{
   pulseConter++;
}

float GetFrequency()
{
   pulseConter = 0;

   interrupts();
   delay(measureInterval);
   noInterrupts();

   return (float)pulseConter * 1000 / measureInterval;
}

void setup()
{
   
   Serial.begin(9600);
   lcd.init(); 
   lcd.backlight(); 
   lcd.setCursor(4,0);             // apuntamos el cursor a la primera fila y primer caracter
   lcd.print("Caudalimetro");
   attachInterrupt(digitalPinToInterrupt(sensorPin), ISRCountPulse, RISING);
}

void loop()
{
    
   // obtener frecuencia en Hz
   float frequency = GetFrequency();

   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;

   Serial.print("Frecuencia: ");
   Serial.print(frequency, 0);
   Serial.print(" (Hz)\tCaudal: ");
   Serial.print(flow_Lmin, 3);
   Serial.println(" (L/min)");
   lcd.setCursor(7,1);
   lcd.print("YF-S201");
   lcd.setCursor(0,4);
   lcd.print(flow_Lmin);  

}

¿Comprobaste que el LCD se encuentre en la direccion 0x27?

Ademas de lo que dice @PeterKantTropus ,esa pantalla puede ir en la direccion 0x3F, la linea:

 lcd.setCursor(0,4);

Oye que solo tienes 4 lineas y enpiezan en la 0 deberia ser

 lcd.setCursor(0,3);

Como maximo. Saludos.

Hola peter que tal. Si señor, realice el scan del LCD, y bueno como comente antes ya comprobé en forma separada que funcione bien el LCD mostrando datos. Inclusive si ves el segundo codigo en el setup tengo puesto un envio al LCD y ese lo puedo ver problemas. El tema esta en lo que pongo en el loop para que se visualize junto al serial monitor.

gonpezzi que tal. Si la observacion que hiciste es correcto, al momento de pegar el codigo no lo vi , pero bueno probe con 0,3 / 0,2 y tampoco. Y es mas tampoco logro ver la otra variable la del (7,1).

Todo lo que ponga por debajo de la variable float en el loop no me lo toma en el LCD, si lo coloco antes si me lo envia al LCD. Pero bueno yo necesito enviar al LCD la variable float_Lmin

saludos!

Esto puede ser una fuente errores (no digo que esto sea el problema), pero hacer calculos mezclando integers y float es una mala idea.

return (float)pulseConter * 1000.0 / (float) measureInterval ;`

Ahora si ese fuera el problema porque cuando utilizo la visualizacion a travez del serial monitor no tengo ningun problema?

saludos!

El monitor serie va a su bola. Haz una prueba imprime en esa posición un numero entero cualquiera a ver que hace.

No dije que ese sea tu problema, solo que puede dar resultados inesperados en tu calculo.
De la forma que estas calculando la frecuencia, agregaría en el setup , justo por debajo del Attachinterrupt un noInterrupts();

gonpezzi, por mas que agregue un numero entero no me lo muestra. La unica forma que me muestre algo es si lo agrego en el loop antes del float asi:

void loop()
{

lcd.setCursor(0,2);
lcd.print("8");

// obtener frecuencia en Hz
float frequency = GetFrequency();

// calcular caudal L/min
float flow_Lmin = frequency / factorK;

Serial.print("Frecuencia: ");
Serial.print(frequency, 0);
Serial.print(" (Hz)\tCaudal: ");
Serial.print(flow_Lmin, 3);
Serial.println(" (L/min)");
lcd.setCursor(7,1);
lcd.print("5");

peter, si intente ponerle pero no cambia nada y mirando el codigo anterior que le copie a gonpezzi directamente me elimina el 8 de la pantalla.

Me referia a algo asi

int AAA=1234;
lcd.setCursor(7,1);
lcd.print(AAA);

¿Intentaste cambiar de pin para la interrupción?

ahi agregue esa linea que pusiste vos pero no hace nada che, osea no muestra esa variable si la coloco despues del float, si la coloco antes si me muestra el 1234 en pantalla.

No entiendo demasiado pero porque sera que si lo pongo antes si lo muestra y si lo pongo despues no.

si, tengo un mega, ya probe en el 2,3,18,19, lo probe con el codigo original que monitorea por serie y funciona sin problema en todos los pines que mencione recien.

Acabo de encontrar mi Mega. El problema es el noInterrupts() de getfrecuenciy() comentandola funciona. La documentación de noInterrupts() da a entender que algunas funciones dependientes de interrupciones no funcionaran.

Peter te acabas de convertir en mi hereo loco ajjaj... Ahi le borre el nointerrup y ahora si funciona.. Muchisimas gracias a ambos por la buena onda.

En realidad me parece una forma extraña de medir un frecuencia y ese delay te puede traer problemas en el futuro. Busca alguna manera de hacerlo con millis.
Saludos.

Esa rutina, me refiero a getFrequency(), ya presentó el mismo problema en otro tema que publicaron hace muy pocos días.
Está mal utilizado el par de sentencias interrupts()/ noInterrupts().
Primero porque no tiene sentido habilitar interrupciones que deberían ya estar habilitadas desde el encendido.
Segundo porque es lógico que si se deshabilitan las interrupciones va a haber procesos que van a dejar de ejecutarse.

Entiendo que la idea es lograr precisión durante el delay() pero por el contrario, durante ese tiempo se van a ejecutar todas las interrupciones que hayan sido desatendidas antes.
Y si prestan atención, en el único punto del código donde se habilitan es justo antes del delay().

Lo sorprendente es que esa rutina, tal cual está aquí, está hasta en la página de Luis Llamas (que es o ha sido fuente de consulta para muchos de los que hablamos español) y nunca la corrigió.

Agrego:
Lo que a mi parecer sería lo correcto

float GetFrequency()
{
   pulseConter = 0;
   delay(measureInterval);
   noInterrupts();
   float frec =  pulseConter * 1000 / measureInterval;
   interrupts();
   return frec;

}

De este modo, por precaución, se evita que pulseConter se pueda incrementar durante el cálculo de frec .

Saludos