Pages: [1]   Go Down
Author Topic: Error en control de temperatura  (Read 1118 times)
0 Members and 1 Guest are viewing this topic.
MEXICO
Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenas compañeros, les presento mi proyecto

intento hacer un control de temperatura con SetPoint variable el cual controlo desde push buttons
un display lcd muestra el valor actual de la temperatura obtenida del lm35 y mostrada cada 1 seg
y los push buttons al ser accionados deben bajar o subir el valor del SetPoint directamente....

el error es, que aun que deje presionado el push button, el valor del SetPoint solo cambia hasta
que se muestra la neva lectura de temperatura (en vez de cambiar al instante el valor del SetPoint)
como quien dice estan ligados en tiempo...
aqui el codigo espero haberme explicado
Quote
#include <LiquidCrystal.h>
float tempC=0 ;
int tempPin= 0;
int suma= 7;
int resta= 8;
int setpoint= 20;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(resta,INPUT_PULLUP);
  pinMode(suma,INPUT_PULLUP);
  lcd.begin(20, 4);
}

void loop()
{
 
  {

     if (digitalRead(suma)==HIGH)
  {
          {
            lcd.setCursor(0,1);
            lcd.print("                    ");
            lcd.setCursor(0,1);
            setpoint++;
            lcd.print("Set Point: ");
            lcd.print(setpoint);
            lcd.write(1);
          }
   }
     if (digitalRead(resta)==HIGH)
  {
          {
            lcd.setCursor(0,1);
            lcd.print("                    ");
            lcd.setCursor(0,1);
            setpoint--;
            lcd.print("Set Point: ");
            lcd.print(setpoint);
            lcd.write(1);
          }
   }
 }
 delay(150);
 
 {  tempC=(5*analogRead(tempPin)*100.0)/1024.0;
       lcd.setCursor(0, 0);
       lcd.print("                    ");
       lcd.setCursor(0, 0);
       lcd.print("Temp Act: ");
       lcd.print(tempC);
       lcd.write(1);
       delay(1000);
 }
}
saludos
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Estas usando un delay y mientras el micro esta haciendo el retardo no recibe ninguna pulsación de botón.
La manera facil es no usando el delay y la compleja usando interrupciones
Logged

MEXICO
Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pero si quito el delay, el display se vuelve loco, me podrías enseñar como compañero? saludos
Logged

Palencia, Spain
Online Online
God Member
*****
Karma: 25
Posts: 568
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

La opción ideal sería usar interrupciones. Básicamente lo que hace una interrupción es ejecutar una función cuando se produce un determinado evento hardware (al pulsar un botón, por ejemplo), con lo que una vez asignada esa función se ejecutará cuando se produzca ese evento, y no cuando la ejecución llegue a ese punto. Esto, quizás sea un poco complicado de momento, así que podemos analizar un poco otras opciones y de paso hacemos un poco de "crítica" (por supuesto, constructiva smiley) de tu código:
  • En primer lugar, ¿no te parece que el código de las condiciones "suma" y "resta" es el mismo? ¿no sería más sencillo poner el código que dibuja la pantalla en una función tipo pantallasetpoint()?
  • En segundo lugar, los delay, básicamente lo que hacen es "entretenter" al procesador haciéndole contar sus latidos, lo que resulta en "tiempo perdido" sin ejecutar ninguna instrucción de nuestro programa.
  • En lugar de usar delay, existe una función que se llama millis(), que devuelve un número unsigned long con los milisegundos transcurridos desde que el Arduino empezó a funcionar. En lugar de hacer esperar nuestro programa en un punto determinado, podemos anotar el valor de millis al principio del programa, luego, cada vez que el programa vuelva a pasar por el loop, comparamos el valor millis actual con el guardado, y si es mayor de x milisegundos, entonces guardamos el nuevo valor para las futuras comparaciones y llamamos alternativamente la función pantallasetpoint() o la pantallatemperatura(). Ten en cuenta que de esta forma, al no hacer delays, el loop del programa se repetirá un montón de veces hasta que pasen los 150 o los 1000 milisegundos, y en cada una de ellas podrás leer los botones.

El código quedaría más o menos (lo de depurarlo te lo dejo a tí)

#include <LiquidCrystal.h>
float tempC=0 ;
int tempPin= 0;
int suma= 7;
int resta= 8;
int setpoint= 20;
unsigned long milisguardados=0;
unsigned long milisactual=0;
unsigned long milisespera=150;
byte pantallaActu=0; // si es 0 dibujamos la pantallaSetup, si es 1, pantallaTemperatura


LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(resta,INPUT_PULLUP);
  pinMode(suma,INPUT_PULLUP);
  lcd.begin(20, 4);
}

void pantallaSetUp()
{
            lcd.setCursor(0,1);
            lcd.print("                    ");
            lcd.setCursor(0,1);
            // esta línea se comprueba en el loop setpoint++;
            lcd.print("Set Point: ");
            lcd.print(setpoint);
            lcd.write(1);
            pantallaActu=1;
            milisguardados=milisactual; //comenzamos a contar diferencia de milis desde cero.
            milisespera=150; //esta pantalla permanecerá 150 ms.
}

void pantallaTemperatura()

       tempC=(5*analogRead(tempPin)*100.0)/1024.0;
       lcd.setCursor(0, 0);
       lcd.print("                    ");
       lcd.setCursor(0, 0);
       lcd.print("Temp Act: ");
       lcd.print(tempC);
       lcd.write(1);
            pantallaActu=0;
            milisguardados=milisactual; //comenzamos a contar diferencia de milis desde cero.
            milisespera=1000; //esta pantalla permanecerá 1000 ms.
 }
loop
{
milisactual=millis();
if (digitalRead(suma)==HIGH)
      {
      setup++;
      pantallasetup();
      }

if (digitalRead(suma)==HIGH)
      {
      setup--;
      pantallasetup();
      }
if ((milisactual-milisguardados)>=milisespera)
     if (pantallaActu==0)
          pantallaSetup();
    else
         pantallaTemperatura();
}


El código seguro que tiene errores, pero creo que te puede servir de guía.
Saludos.
Logged

MEXICO
Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

buenas compañero, ya estoy entendiendo mas el problema que tiene el proyecto que estoy realizando
ya entendi que cuando yo pongo los delay es para "PAUSAR" el programa cargado y no para
mostrar los valos en el tiempo que le pongo a los delay,
eh buscado en foros y temas pero no encuentro a alguin que haya usado la funcion de  millis()
tengo entendido que esa es la que se debe usar de forma ideal envez de los delay.
entonces la pregunta seria...
como hacer que arduino muestre un valor cada cierto tiempo usando la funcion millis() ?
espero no molestarte compañero por tu atencion gracias

una vez aclare esto de los delay vi de nuevo tu mensaje y pude entender,
"En lugar de usar delay, existe una función que se llama millis(), que devuelve un número unsigned long con los milisegundos transcurridos desde que el Arduino empezó a funcionar. En lugar de hacer esperar nuestro programa en un punto determinado, podemos anotar el valor de millis al principio del programa, luego, cada vez que el programa vuelva a pasar por el loop, comparamos el valor millis actual con el guardado, y si es mayor de x milisegundos, entonces guardamos el nuevo valor para las futuras comparaciones y llamamos alternativamente la función pantallasetpoint() o la pantallatemperatura()."
voy a realizar las comparaciones espero y salgan bien saludos
Logged

Pages: [1]   Go Up
Jump to: