Problema lcd grafico

Hola estoy haciendo un voltímetro , amperímetro y para poder medir frecuencia con el lcd grafico y el problema que tengo que no logro hacer que deje de parpadear los dígitos, no se como cambiar la forma de mostrarlo ya que en cada refresco se mueven mucho y no se como hacer para que queden quietos si me pueden ayudar se agradece .

Código:
#include <16f887.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay (clock = 4MHz)
#include <HDM64GS12.c>
#include <graphics.c>
 void main(){
   int16 voltajeADC, voltajeADC_ant,
          cpsADC,cpsADC_ant,
          corrienteADC, corrienteADC_ant;
   setup_adc_ports(san0|san1|san2|VSS_VDD);
    setup_adc(ADC_CLOCK_DIV_2);
    char cps[]="CPS";
    char volt[]="V";
    char amper[]="A";
    char voltaje[9];
  char minuto[9];
    char corriente[9];
 
   glcd_init(ON);
   glcd_line(0, 40, 125, 40, ON);
    glcd_text57(45,12,volt,1,off);
   glcd_text57(105,12,amper,1,Off);
     glcd_text57(105,55,cps,1,Off);
   while(true){
      set_adc_channel(0);
     delay_us(20);
     voltajeADC=read_adc();
      if(voltajeADC_ant != voltajeADC){
           delay_ms(150);
         glcd_text57(5, 3, voltaje, 2, OFF);
         delay_ms(100);
         sprintf(voltaje, "%4.1f", (float)voltajeADC*50/1023.0);
       voltaje[4] = '\0';
         glcd_text57(5, 3, voltaje, 2, ON);  
       voltajeADC_ant=voltajeADC;
        delay_ms(100);
      }
 
      set_adc_channel(1);
       delay_us(20);
       corrienteADC=read_adc();
      if(corrienteADC_ant != corrienteADC){
         glcd_text57(65, 3, corriente, 2, OFF);
        delay_ms(10);
       sprintf(corriente, "%4.1f", (float)corrienteADC*50/1023.0);
          corriente[4] = '\0';
          glcd_text57(65, 3, corriente, 2, ON);        
          corrienteADC_ant=corrienteADC;
 
     }
 
     set_adc_channel(2);
 
     delay_us(20);
 
     cpsADC=read_adc();
 
     if(cpsADC_ant != cpsADC){
          glcd_text57(30, 40, minuto, 3, OFF);
         delay_ms(10);
         sprintf(minuto, "%02.1f", (float)cpsADC*50/1023.0);
         minuto[4] = '\0';
 
         glcd_text57(30, 40, minuto, 3, ON);
 
        cpsADC_ant=cpsADC;        
 
    }
   }
 
}
 

Adjuntos

  • voltimetro lcd grafico pic 16f887.rar
    38.6 KB · Visitas: 2
Última edición por un moderador:
Una manera de lograrlo es refrescar solamente si la nueva medicion es diferente de la anterior segun un valor de ventana. O sea, no comparar que sea diferente sino solo que sea diferente por un valor delta. Yo comenzaria con un valor de delta de al menos dos o tres digitos menos significativos.

Despues podes jugar con el valor de ventana a uno o hasta medio digito significativo.

Otra manera de hacer lo mismo, o parecido, es promediar varias mediciones a lo largo de un tiempo determinado, digamos 250ms, para filtrar las variaciones muy chicas por ruidos de todo tipo que no sirve de nada mostrar, como ya lo experimentaste.
 
¿Cómo sería en el código? Yo estuve probando esto y no me funcionó.
PHP:
set_adc_channel(2); 
delay_us(20);
cpsadc=0;
for(var1=0;var1<500;var1++)
{
cpsadc=cpsadc+ read_adc();
delay_us(62); 
}
cpsADC_ant=cpsadc/500;
glcd_text57(30, 40, minuto, 3, ON);

sprintf(minuto, "%1.1f", (float)cpsADC_ant* 50 / 1023);
minuto[5] = '\0';
 
Última edición por un moderador:
Trata que los lapsos de refrescar sean cada tantos milisegundos, relativamente pequeños a fin que el parpadeo sea imperceptible a la vista.
 
a 1era vista, saca los tres delay que estan en la lectura (los dos de 100ms y el de 150ms)... aunque yo personalmente sacaria todos menos los de 20uS que estan despues de adquirir el dato analogico... dejalo en 2uS... prueba y comenta
 
Ya hice esa prueba y no me da resultado.
Tengo que tratar de sacar promedios o implementar otro tipo de lectura o muestreo para que no parpadee tanto. Gracias.
 
Última edición por un moderador:
Hola...buen dia... aclarame algo... parpadea el valor de la variable o la pantalla completa?
Si es la variable, si, podrias hacer algo como te recomendaron... si es la pantalla completa, saxale todas las pausas y dejale solo la del adc en 2us y adiciona solo una de 100ms en el el ultimo paso antes de volver a cero el programa
 
Hola buen día mira atentamente este trozo de código y tu mismo veras donde esta el error.

Código:
#include <16F887.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include <HDM64GS12.c>
#include <graphics.c>
void main(){
   int16 voltajeADC, voltajeADC_ant,
         corrienteADC, corrienteADC_ant;
   setup_adc_ports(sAN0|sAN1|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   char nombre[]="Electgpl";
   char parametro[]="   [V]       [A]   ";
   char voltaje[9];
   char corriente[9];
   glcd_init(ON);
   glcd_rect(1, 1, 127, 63, NO, ON);
   glcd_rect(3, 3, 125, 13, NO, ON);
   glcd_text57(41, 5, nombre, 1, ON);
   glcd_rect(3, 15, 125, 25, NO, ON);
   glcd_text57(8, 17, parametro, 1, ON);
   glcd_rect(3, 27, 125, 61, NO, ON);
   while(true){
      set_adc_channel(0);
      delay_us(10);
      voltajeADC=read_adc();
      if(voltajeADC_ant != voltajeADC){
         glcd_text57(13, 38, voltaje, 2, OFF);
         sprintf(voltaje, "%1.2f", (float)voltajeADC*5/1023.0);
         voltaje[4] = '\0';
         glcd_text57(13, 38, voltaje, 2, ON);  
         voltajeADC_ant=voltajeADC;
      }
      set_adc_channel(1);
      delay_us(10);
      corrienteADC=read_adc();
      if(corrienteADC_ant != corrienteADC){
         glcd_text57(70, 38, corriente, 2, OFF);
         sprintf(corriente, "%1.2f", (float)corrienteADC*5/1023.0);
         corriente[4] = '\0';
         glcd_text57(70, 38, corriente, 2, ON);  
         corrienteADC_ant=corrienteADC;
      }  
   }
}

Maki.
 
Última edición:
PHP:
set_adc_channel(0);  leo el canal 
      delay_us(10);      tiempo de lectura
      voltajeADC=read_adc(); guardo el valor adc en la variable 
      if(voltajeADC_ant != voltajeADC){         si voltajeadc_ant es difente a voltajeadc apago voltaje 
         glcd_text57(13, 38, voltaje, 2, OFF);
         sprintf(voltaje, "%1.2f", (float)voltajeADC*5/1023.0); muestro la variable voltaje y hago la convercion
         voltaje[4] = '\0';      esta línea es para limitar los dígitos 
         glcd_text57(13, 38, voltaje, 2, ON);  enciendo voltaje
         voltajeADC_ant=voltajeADC; vuelvo al comienzo
Así interpreto el código. Estoy errado en algo.


#use delay(clock=20000000)

Estaba trabajando con 4 MHz. ¿Esto puede ser causante de que los dígitos parpadeen en cada cambio de lectura?
 
Última edición por un moderador:
Hola. Buen día. Aclárame algo.
¿Parpadea el valor de la variable o la pantalla completa?
Si es la variable, si, podrías hacer algo como te recomendaron.
Si es la pantalla completa, sácale todas las pausas y déjale sólo la del ADC en 2 us y adiciona sólo una de 100ms en el el último paso antes de volver a cero el programa.
Me parpadea la variable, hace como una bandera que se está moviendo siempre y no logro poder hacer el código para sacar promedios, son más difícil que los LCD comunes. Saludos.

---------- Actualizado ----------

PHP:
set_adc_channel(2); 
delay_us(20);
cpsadc=0;
for(var1=0;var1<500;var1++)
{
cpsadc=cpsadc+ read_adc();
delay_us(62); 
}
cpsADC_ant=cpsadc/500;
glcd_text57(30, 40, minuto, 3, ON);

sprintf(minuto, "%1.1f", (float)cpsADC_ant* 50 / 1023);
minuto[5] = '\0';
¿Por-qué no puedo sacar promedios con este código?
No me muestra nada en la pantalla. ¿Qué puede ser?
 
Última edición por un moderador:
hola amigos del foro, después de varios días intentado vuelvo a molestar ya que me ignoraron por completo, estuve probando largas horas y tratando de ver varios ejemplos en internet ya que mi cable a tierra es intentar programar, pude lograr sacar el movimiento de los dígitos y les pido ayuda ya se que están ocupados y mis preguntas son de un nivel muy bajo pero es lo que puedo hacer, como hago para que se muestren mas lentos los dígitos o poder sacar promedios para que se muestre mejos , gracias a todos por leer

Código:
#include <16f887.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay (clock = 20MHz)
#include <HDM64GS12.c>
#include <graphics.c>
void main(){
   int16 voltajeADC, voltajeADC_ant,
          cpsADC,cpsADC_ant,
          corrienteADC, corrienteADC_ant;
   setup_adc_ports(san0|san1|san2|VSS_VDD);
    setup_adc(ADC_CLOCK_DIV_2);
    char cps[]="CPS";
    char volt[]="V";
    char amper[]="A";
    char voltaje[9];
  char minuto[9];
    char corriente[9];
 
   glcd_init(ON);
   glcd_line(0, 25, 125, 25, ON);
    glcd_text57(45,12,volt,1,off);
   glcd_text57(105,12,amper,1,Off);
     glcd_text57(105,55,cps,1,Off);
   while(true){
      set_adc_channel(0);
     delay_us(10);
     voltajeADC=read_adc();
      if(voltajeADC_ant != voltajeADC){
         glcd_text57(5, 3, voltaje, 2, OFF);
         sprintf(voltaje, "%4.1f", (float)voltajeADC*50/1023.0);
       voltaje[4] = '\0';
         glcd_text57(5, 3, voltaje, 2, ON);  
       voltajeADC_ant=voltajeADC;
       }
 
      set_adc_channel(1);
      delay_us(10);
      corrienteADC=read_adc();
     if(corrienteADC_ant != corrienteADC){
        glcd_text57(65, 3, corriente, 2, OFF);
       sprintf(corriente, "%4.1f", (float)corrienteADC*50/1023.0);
         corriente[4] = '\0';
         glcd_text57(65, 3, corriente, 2, ON);        
         corrienteADC_ant=corrienteADC;
     }
     set_adc_channel(2);
     delay_us(10);
     cpsADC=read_adc();
     if(cpsADC_ant != cpsADC){
         glcd_text57(30, 40, minuto, 3, OFF);
        sprintf(minuto, "%02.1f", (float)cpsADC*50/1023.0);
        minuto[4] = '\0';
         glcd_text57(30, 40, minuto, 3, ON);
        cpsADC_ant=cpsADC;        
 
    }
   }
 
}
 
Atrás
Arriba