Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos » Arduino y Raspberry Pi
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

23/03/2014 #1


Problemas con LCD (Arduino)
Hola.
Tengo problemas al momento de imprimir números en el display lcd, ya que cuando pongo un número grande, por ejemplo el 10000 y después imprimo otro, por ejemplo 253, los ceros del otro número se quedan y me imprime 25300
Ya lo intenté borrar con el comando lcd.clear() y solo provoca que el lcd parpadeé y no muestra ningún dato.
¿Cual será el error?
23/03/2014 #2
Moderador

Avatar de D@rkbytes

elohim0492 dijo: Ver Mensaje
Hola.
Tengo problemas al momento de imprimir números en el display lcd, ya que cuando pongo un número grande, por ejemplo el 10000 y después imprimo otro, por ejemplo 253, los ceros del otro número se quedan y me imprime 25300
Ya lo intenté borrar con el comando lcd.clear() y solo provoca que el lcd parpadeé y no muestra ningún dato.
¿Cual será el error?
Ese problema es muy común al mostrar cantidades sin formato en la pantalla.
No sé de programación en Arduino, pero para que eso no suceda debes asignar cuantos dígitos se deben mostrar conforme al tamaño del tipo de variable que estés usando.

Es decir, si usas una variable del tipo Byte (255) debes mostrar 3 dígitos (000)
Por lo tanto, si el resultado es 12, se verá en pantalla 012 y así no tendrás problemas con los números que hayan sido escritos anteriormente en la pantalla.
Lo mismo se debe hacer para otro tipo de tamaño de variables.
Por ejemplo, una variable de 16 Bits (0 a 65535) que tiene 5 dígitos, el número 12 se mostrará como 00012

En C de CCS para hacer lo que te menciono sería de esta forma:
printf(lcd_putc,"Resultado: %05LU",Mi_Variable);

Donde 05 son los ceros a mostrar como formato en pantalla y LU es Long Unsigned Integer. (Tipo de variable)

De esta forma ya no tienes por qué estar borrando la pantalla y evitas el parpadeo.

Suerte.
23/03/2014 #3


gracias por el dato, pero lo malo es que esa sintaxis no sirve en arduinoT_T
23/03/2014 #4
Moderador

Avatar de D@rkbytes

elohim0492 dijo: Ver Mensaje
gracias por el dato, pero lo malo es que esa sintaxis no sirve en arduinoT_T
Debe haber, no creo que los diseñadores de Arduino hayan pasado algo tan importante por alto.

También puedes sustituir los números sobrantes por espacios en blanco.
23/03/2014 #5

Avatar de chclau

Proba escribiendo una logica que haga que el LCD se limpie solo si el dato nuevo es distinto del anterior.

Si el LCD todavia parpadea mucho, podes limpiar el display solo si el dato nuevo es distinto del anterior en algun porcentaje que te resulte comodo para tu aplicacion.
23/03/2014 #6

Avatar de jmth

Es raro que no te funcione el LCD clear, a mí nunca me ha dado ningún problema. Igual poniendo algún delay entre dato y dato...

Si no, prueba a poner lcd.write("\f Palabra"), es lo que usamos en el CCS también para limpiar la pantalla completa, he probado en el arduino y no lo he puesto en la lcd, pero compila bien.
27/03/2014 #7


Hola intenta con un "if" que cuando el valor sea menor que un numero de 4 o 5 digitos te imprima en el lugar o posicion de los "0" te imprima " " (nada). No se si me entendiste.
20/09/2016 #8

Avatar de ivan03488

Hola gente, les comento que estoy haciendo un programita con un arduino uno porque se quemo el micro de mi estación de soldado, ya pude hacer andar todo, pero tengo un problema con el lcd.
Como la bomba de aire es de 220 tengo que hacer un pwm sincronizado con la fase para que ande bien, pero mi problema es que cuando refresco el lcd demora mucho y me hace saltos en el pwm, mi consulta es si se puede hacer algo para que el print de la librería del lcd no me demore tanto tiempo.

Desde ya muchas gracias
20/09/2016 #9

Avatar de Ardogan

ivan03488 dijo: Ver Mensaje
Hola gente, les comento que estoy haciendo un programita con un arduino uno porque se quemo el micro de mi estación de soldado, ya pude hacer andar todo, pero tengo un problema con el lcd.
Como la bomba de aire es de 220 tengo que hacer un pwm sincronizado con la fase para que ande bien, pero mi problema es que cuando refresco el lcd demora mucho y me hace saltos en el pwm, mi consulta es si se puede hacer algo para que el print de la librería del lcd no me demore tanto tiempo.

Desde ya muchas gracias
No depende tanto del LCD sino de tu esquema de ejecución de código (me lo anoto como tema para un próximo video ).

En este caso hay una tarea de alta prioridad (pwm sincronizado) y una de baja prioridad (actualizar el LCD).
Hablo de tareas pero no hace falta matar el mosquito con un cañon como usar un RTOS ni nada de eso.

Una posibilidad es ejecutar tu tarea de alta prioridad en una rutina de interrupción, por ejemplo, la interrupción de un timer o el cruce por cero de la tensión a sincronizar vía interrupción de puerto.

Si lo planteamos en código:

Código PHP:
void main (void) {
    
//Inicialización etc etc, activar la interrupción de tarea prioritaria

    
while(1) {
        
//Tarea de baja prioridad:
        
LcdPrintf("bla bla bla");
    }
}

//Funcion llamada por interrupción o directamente copiar el cuerpo a la ISR
void TareaPrioritaria(void) {
    
cicloTrabajo algunaCuentaMuyComplicadaQueDesconozco;
    
SetearPWM(cicloTrabajo);

Si es posible o no hacer algo así, no podría decirlo sin más información, ¿te puede servir algo así?
20/09/2016 #10

Avatar de ivan03488

si, claro me recontra sirve, yo de hecho estaba haciendo todo lo contrario, por lo que entiendo lo ideal seria usar la interrupcion en la pata que tengo para detectar el cruce por 0 y en esa interrupcion hacer lo de el pwm y el resto en el eje central del programa, no?.
porque yo estaba poniendo lo del cruce en el eje del programa y un timer con el refresco del lcd.
ahora hago lo que me decis y lo subo, igualmente aca te paso el programa que me trae problemas, esta un poco complicado porque no lo comentarie

Código PHP:
#include <LiquidCrystal.h>
#include <TimerOne.h>
#include <Wire.h>
#include <PID_v1.h>
#include <string.h>

#define boton_down 2
#define boton_up 1
#define boton_set 16
#define face 3
#define FanHotGun 4
#define Rele 5
#define HotGun 6
#define Lapiz 7
#define tiempo2 1
#define rebotes 10

int cantidad_rebotes_up=0;
int cantidad_rebotes_down=0;
int cantidad_rebotes_set=0;
int estado_actual 0;
int estado_anterior 0;
int estado_set =0;
int estado_up 0;
int estado_down 0;
int estado_set_a =0;
int estado_up_a 0;
int estado_down_a 0;
int estado 0;
int tiempo1 00;
int periodo 0;
float multiplo0.828;
float suma0;
float porse =0;
int temp1=0;
int temp2=0;
int flag_set_a=0;
int flag_up_a=0;
int flag_down_a=0;
int flag_set=0;
int flag_up=0;
int flag_down=0;
int conteo_timer =0;
int modo_set =0;
int conteo_modo=0;
int pistola_on =0;
int temperatura_p =350;
int temperatura_s =300;
LiquidCrystal  lcd(8910111213);
int barrido=1;
int boton_a=0;
int boton_b=0;
int fun_on=1;


void setup() 
{
        
pinMode(faceINPUT);
        
pinMode(boton_downINPUT);
        
pinMode(boton_upINPUT);
        
pinMode(boton_setINPUT);
        
pinMode(FanHotGunOUTPUT);    //FanHotGun
        
pinMode(HotGunOUTPUT);    //FanHotGun
        
periodo pulseIn(faceLOW);
        
periodo periodo 2;
        
lcd.begin(162);
        
digitalWrite(HotGunHIGH);
        
delay(500);
        
tiempo1 periodo;
        
Timer1.initialize(10000);
        
Timer1.attachInterrupt(pantalla);
}

void pantalla ()
{   
        
        
        
String temperatura1 String (temp1);
        
String temperatura2 String (temp2);
        
String temperaturaSoldador String (temperatura_s);
        
String temperaturaPistola String (temperatura_p);
        
String aire String((tiempo1-periodo)/200);
        
        
        
        switch(
modo_set)
        {
          case 
0:
          {
             
String renglon1 String("S C:" temperatura1);
             
String renglon2 String("P C:" temperatura2 "AIRE:" aire);
             
             
lcd.setCursor(00);
             
lcd.print(renglon1);
             
lcd.setCursor(01);
             
lcd.print(renglon2);
             break;
          }
          case 
1:
          {
             
String renglon1 String("Soldador");
             
String renglon2 String("C:" temperaturaSoldador);
              
             
lcd.setCursor(00);
             
lcd.print(renglon1);
             
lcd.setCursor(01);
             
lcd.print(renglon2);
 
             break;
          }
          case 
2:
          {
             
String renglon1 String("Pistola");
             
String renglon2 String("C:" temperaturaPistola);
              
             
lcd.setCursor(00);
             
lcd.print(renglon1);
             
lcd.setCursor(01);
             
lcd.print(renglon2);
             break;
          }
          case 
3:
          {
             
String renglon1 String("Aire");
             
String renglon2 String("N:" aire);
              
             
lcd.setCursor(00);
             
lcd.print(renglon1);
             
lcd.setCursor(01);
             
lcd.print(renglon2);
             break;
          }
        }

             
}

void teclado ()

              
estado_up digitalRead(boton_up);
              if (
estado_up == && estado_up_a == 1)
              {
                  
cantidad_rebotes_up++;
                  if (
cantidad_rebotes_up>=rebotes)
                   
flag_up_a=1;
                   
              }
              else
              {
                if (
flag_up_a == 1)
                {
                  
flag_up_a=0;
                  
flag_up=1;
                }
                
cantidad_rebotes_up=0;
              }
              
estado_up_a=estado_up;

              
estado_down digitalRead(boton_down);
              if (
estado_down == && estado_down_a == 1)
              {
                  
cantidad_rebotes_down++;
                  if (
cantidad_rebotes_down>=rebotes)
                    
flag_down_a=1;
              }
              else
              {
                if (
flag_down_a == 1)
                {
                  
flag_down_a=0;
                  
flag_down=1;
                }
                
cantidad_rebotes_down=0;
              }
              
estado_down_a estado_down;

              
estado_set digitalRead(boton_set);
              if (
estado_set == && estado_set_a == 1)
              {
                  
cantidad_rebotes_set++;
                  if (
cantidad_rebotes_set>=rebotes)
                    
flag_set_a=1;
              }
              else
              {
                if (
flag_set_a == 1)
                {
                  
flag_set_a=0;
                  
flag_set=1;
                }
                
cantidad_rebotes_set=0;   
              }
              
estado_set_a estado_set;  


              
estado_anterior estado_actual;
              
estado_actual digitalRead(face);
              
temp1=analogRead(1);
              
temp2=multiplo*analogRead(0)+suma;
}

int leer_teclado ()
{
  
int return_tecla=0;
  if (
flag_up==1)
  {
    
return_tecla=1;
    
flag_up=0;
  }
  if (
flag_down==1)
  {
    
return_tecla=2;
    
flag_down=0;
  }
  if (
flag_set==1)
  {
    
return_tecla=3;
    
flag_set=0;
  }
  return (
return_tecla);
}



void loop() 
{
  
teclado();
  
        if (
estado == 0)
        {
            if (
estado_actual == && estado_anterior == 0)
            {
                
estado_anterior estado_actual;
                
estado 1;
            }
            if (
fun_on==0)
              
estado=4;
        }
      
        if (
estado == 1)
        {
          
noInterrupts();
            
delayMicroseconds (tiempo1);
            
digitalWrite(FanHotGunLOW);
            
delayMicroseconds (tiempo2);
            
digitalWrite(FanHotGunHIGH);
          
            
estado 2;
        }
        if (
estado == 2)
        {
            if (
estado_actual == && estado_anterior == 1)
            {
                
estado_anterior estado_actual;
                
estado 3;
            }
            
estado_anterior digitalRead(face);
        }
        if (
estado == 3)
        {
           
            
delayMicroseconds (tiempo1);
            
digitalWrite(FanHotGunLOW);
            
delayMicroseconds (tiempo2);
            
digitalWrite(FanHotGunHIGH);
           
interrupts();
            
estado 4;
        }
        if (
estado == 4)
        {
          if (
pistola_on==1)
          {
              
fun_on=1;
              if  (
temp2<temperatura_p )
               
digitalWrite(HotGunLOW);
              if  (
temp2>temperatura_p)
               
digitalWrite(HotGunHIGH);
          }
          else
          {
              if  (
temp2 <= 100)
                
fun_on=0;
              
tiempo1 periodo;
              
digitalWrite(HotGunHIGH);
          }
          
estado 5;
        }
        
//****************************************************************************botones//
        
        
if (estado == 5)
        {
          
          
        
            
         
estado 6;
        }
        if (
estado == 6)
        {
          switch (
leer_teclado())
          {
              case 
1:
                  if (
modo_set == 1)
                      
temperatura_s temperatura_s 10;
                  if (
modo_set == 2)
                      
temperatura_p temperatura_p 10;
                  if (
modo_set == 3)
                     
tiempo1 tiempo1 200;
                  if (
modo_set == 0)
                  {
                    if (
pistola_on == 0)
                      
pistola_on 1;
                    else
                      
pistola_on 0;
                  }
                    
               break;
    
               case 
2:
                  if (
modo_set == 1)
                      
temperatura_s temperatura_s 10;
                  if (
modo_set == 2)
                      
temperatura_p temperatura_p 10;
                  if (
modo_set == 3)
                     
tiempo1 tiempo1 200;
               break;
    
               case 
3:
                    
                      if (
modo_set >= 3)
                        
modo_set 0;
                      else
                        
modo_set++;
                    
               break;
          }
          
estado 0;
        }      

20/09/2016 #11

Avatar de Ardogan

ivan03488 dijo: Ver Mensaje
si, claro me recontra sirve, yo de hecho estaba haciendo todo lo contrario, por lo que entiendo lo ideal seria usar la interrupcion en la pata que tengo para detectar el cruce por 0 y en esa interrupcion hacer lo de el pwm y el resto en el eje central del programa, no?.
porque yo estaba poniendo lo del cruce en el eje del programa y un timer con el refresco del lcd.
Claaaaro , lo que pasa es que la interrupción siempre tiene prioridad sobre el programa principal. El código viene ejecutando el while(1) del main lo más tranquilo, hasta que llega una interrupción, deja todo lo que está haciendo, y se dedica de lleno a la interrupción.

Es como cuando estás trabajando y te llaman porque tu madre tuvo un accidente... interrumpís/largás todo y vas a ver que pasó hasta saber que está atendida.
Vos lo estabas haciendo como cuando estás mirando el partido del Domingo y la bienamada esposa se poner a contarnos que a fulanito le pasó esto o aquello... a esa interrupción la ignoramos sin problema .

Pero no, tu caso es el accidente de mamá, no el anterior.
Eso siempre y cuando las interrupciones estén habilitadas.
Le damos más importancia a setear el pwm porque la línea de 220V no espera a nadie. 50 Hz no parece mucho, pero es un ciclo cada 20ms, no lo hagamos esperar más de algún que otro milisegundo, no?.
En cambio el mensaje en la pantallita... ni vamos a notar si tarda 10, 50, o 100 milisegundos en presentar el mensaje.

ivan03488 dijo: Ver Mensaje
... leo el código sin entrar en mucho detalle ...
Aja... bueno, tiene sabor a Arduino no?. No estoy familiarizado con las cosas internas de la librería LCD y PID, pero creo que no es mucho suponer que es todo programación secuencial (que internamente no usan interrupciones y que las funciones retornan solo cuando se completo la función, es decir, no hay llamadas asíncronas).

Me gusta que hayas hecho algo en base a estados .

Agrego tarea de teclado:
  1. Actualizar PWM con detección de cruce por cero: prioridad más alta.
  2. Leer teclado: que nos gustaría que se ejecute en un intervalo T para no perdernos una pulsación del usuario. Prioridad media
  3. Mostrar el mensaje en pantalla LCD: prioridad baja.
Pero diría que conviene tener solo 2 tareas, teclado y pantalla en el loop(), y seteo de pwm en la interrupción.

Es más, también podría disparar la actualización de teclado y pantalla por interrupción, pero en la rutina de interrupción de actualización de pantalla y teclado seteamos un flag y volvemos bien rápido. De esa forma también podés configurar para que la actualización se haga 10 veces por segundo, o 20 veces por segundo para el teclado y 5 veces por segundo para la pantalla... pero eso último sería agregar un poco de complejidad, por ahora digamos que teclado y pantalla se actualizan 10 veces por segundo al unísono.



La estructura del código podría ser algo como:


Código PHP:
void setup() {

    
//...
    //configurar interrupción de pwm -> puerto de I/O
    //configurar interrupción de teclado y pantalla -> timer

    
HabilitarInterrupciones();
}

volatile unsigned int actualizarTecladoPantalla 0;

void loop (void) {
    if (
actualizarTecladoPantalla) {
        
actualizarTecladoPantalla 0;
        
teclado(); //lee puertos, actualiza variables de entrada al pid
        
        
if(sePresionoAlgunaTecla) {
            
RecalcularPID();    //los valores calculados los utiliza la rutina de interrupción de seteo de pwm
        
}

        
pantalla(); //se imprimen los valores de pantalla
    
}

}

void RecalcularPID(void) {
    
cicloPWM cuentaQueLeeValoresSeteadosPorTeclado();
}

void InterrupcionCrucePorCero(void) {
    
timerSetearCicloDeTrabajo(cicloPWM);
}

void InterrupcionPorTimerActualizacionTecladoPantalla(void) {
    
actualizarTecladoPantalla 1;


No sé si se entiende la idea.
20/09/2016 #12

Avatar de ivan03488

Muchas gracias, si es con arduino, porque no me quería poner a fabricar las librerías de un micro, y las librerías que tengo es de un lpc 1769 que es demasiado para esto jaja. Si, gracias a un profesor de la facultad que prácticamente nos pegaba cuando usábamos un while o alguna función bloqueante, me acostumbre a los estados, y la verdad que me encanta. te comento que ya esta andando perfecto y cuando me haga un tiempito junto toda la info y lo subo, porque estuve como 1 semana con un montón de trabajos atascados y tengo que librarme de eso primero.

Muchísimas gracias
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Arduino y Raspberry Pi

Cerrar
Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos » Arduino y Raspberry Pi

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.