Encontrar valor máximo y mostrarlo en una pantalla LCD

Buen día. Espero me puedan ayudar en esto.

Estoy intentando hacer un código que me muestre el valor máximo que obtiene del punto A0 del Arduino Uno en una pantalla LCD.

El código que tengo actualmente funciona, pero solamente me muestra un valor, lo que busco es que me muestre constantemente el valor máximo generado, puede ser en un intervalo de 1 segundo.

Este es mi código:

#include <LiquidCrystal.h>
LiquidCrystal lcd(2,3,4,5,6,7);


int valorADC;
int pot = A0;
float voltaje = 0.0;
int var;
volatile unsigned muestreoActual = 0;  // variables para definición del tiempo de muestreo
volatile unsigned muestreoAnterior = 0;
volatile unsigned deltaMuestreo = 0;
float maxi = 0;  // valor máximo <== Inicializar con un valor muy bajo para asegurarnos que la primera vez actualiza el máximo
float mini = 1023; // valor mínimo <== Inicializar con un valor muy alto para asegurarnos que la primera vez actualiza el mínimo


int k = 1000; // tiempo de muestreo

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
  
  pinMode(A0, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Smart Metering");
  
}

void loop() {
  // put your main code here, to run repeatedly:
  
muestreoActual = millis();
deltaMuestreo = (double)muestreoActual - muestreoAnterior; // delta de muestreo 


if ( deltaMuestreo >= k)       // se asegura el tiempo de muestreo
  {
    Serial.println(millis());   //verificación de tiempo por comunicación serial
    muestreoAnterior = muestreoActual;  //actualización del tiempo Anterior
    
    
  }

analogReference(INTERNAL);
valorADC = analogRead(A0);
voltaje = valorADC *(1.1 / 1023.0)* 2 ;
float corriente;
corriente = voltaje * 100;
lcd.setCursor(0,1);
lcd.print("Corriente= ");
float corriente_real = voltaje * 0.7071; // valor rms / real
if (corriente_real > maxi)
 {
  
  Serial.println(corriente_real);
  Serial.println(maxi);
  maxi = corriente_real;
  
 }
  
  
lcd.print(maxi);




}

Adicional, se tiene que usar millis para el intervalo del tiempo.
Gracias de antemano

Bueno, hay algunas variables mal definidas, las referidas a "tiempo" deben ser unsigned long porque ese es el tipo devuelto por millis(), incluso k.
Es innecesario que las definas como volatile en este contexto, volatile se utiliza generalmente (aunque no siempre) cuando se trabaja con interrupciones .
Esta instrucción

deltaMuestreo = (double)muestreoActual - muestreoAnterior; // delta de muestreo 

está mal porque deltaMuestreo es unsigned long y no puedes cambiar su tipo a double

Prueba esto a ver si es lo que quieres

#include <LiquidCrystal.h>
LiquidCrystal lcd(2,3,4,5,6,7);

int valorADC;
int pot = A0;
float voltaje = 0.0;
float corriente = 0.0;
float corriente_real = 0.0;
int var;
unsigned long muestreoActual = 0;  // variables para definición del tiempo de muestreo
unsigned long muestreoAnterior = 0;
unsigned long deltaMuestreo = 0;
float maxi = 0.0;  // valor máximo <== Inicializar con un valor muy bajo para asegurarnos que la primera vez actualiza el máximo
float mini = 1023.0; // valor mínimo <== Inicializar con un valor muy alto para asegurarnos que la primera vez actualiza el mínimo
unsigned long k = 1000UL; // tiempo de muestreo

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pot, INPUT);
  analogReference(INTERNAL);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Smart Metering");
}

void loop() {
  // put your main code here, to run repeatedly:
  
  muestreoActual = millis();
  deltaMuestreo = muestreoActual - 
  muestreoAnterior; // delta de muestreo 
  if ( deltaMuestreo >= k) {      // se asegura el tiempo de muestreo
    Serial.println(millis());   //verificación de tiempo por comunicación serial
    muestreoAnterior = muestreoActual;  //actualización del tiempo Anterior
//   analogReference(INTERNAL);
    valorADC = analogRead(A0);
    voltaje = valorADC *(1.1 / 1023.0)* 2 ;
    corriente = voltaje * 100;
    lcd.setCursor(0,1);
    lcd.print("Corriente= ");
    corriente_real = voltaje * 0.7071; // valor rms / real
    if (corriente_real > maxi){
      maxi = corriente_real;
      Serial.println(corriente_real);
      Serial.println(maxi);
      lcd.print(maxi);
    }
  }
}

Lógicamente te va a mostrar el valor máximo de toda la medición hasta que lo reinicies.

Saludos

PD: Edité el código según la observación de @Surbyte ya que se me había escapado ese detalle.

Esta como volatile unsigned que no se que termina siendo.
Volatile se usa cuando una variable es compartida con rutinas de interrupcción.
Todas las variables que se usen con millis() deben ser unsigned long.

Otro tema.

analogReference(INTERNAL);  // mover al setup()

se coloca en el setup a menos que por alguna razón hagas cambios en el loop pero no es tu caso.

@Surbyte acabo de probar

unsigned variable = 0;

y pareciera que por defecto lo toma como unsigned int ya que

sizeof(variable)

devuelve 2.

:thinking:

Saludos y gracias por hacer notar lo de analogReference(), lo había pasado por alto

Hola @gatul gracias por responder, estoy simulando el código en Proteus 8, usando Arduino 8 y no me arroja ningún dato en la pantalla LCD.

Inserto la imagen de la simulación del Proteus, espero tu pronta respuesta.

Los valores que tiene el sensor son: 161m en amplitude y 60 en frecuencia

Sin embargo debería imprimir cada vez corriente_real es mayor a maxi.
¿Por consola tampoco imprime?

Corrijo un par de detalles

#include <LiquidCrystal.h>
LiquidCrystal lcd(2,3,4,5,6,7);

int valorADC;
int pot = A0;
float voltaje = 0.0;
float corriente = 0.0;
float corriente_real = 0.0;
int var;
unsigned long muestreoActual = 0;  // variables para definición del tiempo de muestreo
unsigned long muestreoAnterior = 0;
unsigned long deltaMuestreo = 0;
float maxi = 0.0;  // valor máximo <== Inicializar con un valor muy bajo para asegurarnos que la primera vez actualiza el máximo
float mini = 1023.0; // valor mínimo <== Inicializar con un valor muy alto para asegurarnos que la primera vez actualiza el mínimo
unsigned long k = 1000UL; // tiempo de muestreo

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
//  pinMode(pot, INPUT);  // es innecesario cuando se usa como analógico
  analogReference(INTERNAL);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Smart Metering");
}

void loop() {
  // put your main code here, to run repeatedly:
  
  muestreoActual = millis();
  deltaMuestreo = muestreoActual - 
  muestreoAnterior; // delta de muestreo 
  if ( deltaMuestreo >= k) {      // se asegura el tiempo de muestreo
    Serial.println(millis());   //verificación de tiempo por comunicación serial
    muestreoAnterior = muestreoActual;  //actualización del tiempo Anterior
    valorADC = analogRead(pot);
    voltaje = valorADC *(1.1 / 1023.0)* 2.0 ;
    corriente = voltaje * 100.0;
    lcd.setCursor(0,1);
    lcd.print("Corriente= ");
    corriente_real = voltaje * 0.7071; // valor rms / real
    if (corriente_real > maxi){
      maxi = corriente_real;
      Serial.println(corriente_real);
      Serial.println(maxi);
      lcd.setCursor(11,1);
      lcd.print(maxi);
    }
  }
}

Ahora que veo el esquema, si conectas la entrada de alterna directamente al pin analógico así como en la simulación en un arduino real, despídete del pin analógico (como mínimo).
No puedes ingresar señales negativas al pin entonces en el primer semiciclo negativo... adiós.

1 Like

En la vida real estoy conectando a través del sensor SCT013

Ok.
No se como lo conectaste pero por las dudas pegale un vistazo a este enlace donde explica como conectarlo directamente a un arduino.

Saludos

Gracias por tu ayuda!