TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: DarkVect en 17 de Abril de 2007, 09:29:13
-
Hola, el problemilla que tengo es que debo refrescar la información en un lcd cada segundo y cuando lo hago se nota el pardeo debido a la instrucción "\f" que borra la pantalla para poner la información modificada.
Esto no sería un problema si la información fuese en su mayor parte diferente a la que había, puesto que el propio cambio de caracteres enmascara el efecto, pero el caso es que tengo que mostrar el estado de dos variables y su nombre siempre aparece:
valor1=...
valor2=...
Con lo que al refrescar las variables, valor1 y valor2 parpadean. He pensado en escribir los valores a partir de la posición siguiente al = y que valor1 y valor2 no se refresquen, pero si, por ejemplo, valor1=88 y luego valor1=6 se mostraría 68, al no borrar la pantalla.
Existe alguna solución para esto? Borrar sólo a partir de algún punto o similar?
PD: Utilizo CCS y la librería flex_lcd.c
Gracias
-
Hola DarkVect!
Si queremos imprimir el 765 puedes hacer un printf con ese valor y ya está.
Si queremos imprimir el 76 puedes hacer un printf con ese valor pero con un espacio en blanco al final.
Si queremos imprimir el 7 puedes hacer un printf con ese valor pero con dos espacios en blanco al final.
Así se borrarán los restos anteriores en todos los casos y evitarás el parpadeo. Evidentemente antes de hacer el correspondiente printf tendrás quie ver si el valor a imprimir es menor que 10, está entre 10 y 100 o entre 100 y 1000. Así es como yo lo suelo hacer.
Un saludo desde Alicante.
-
Mejor usa la instruccion lcd_gotoxy(x,y) para cambiar solamente los valores que se modifican y no reescribir toda la pantalla cada vez.
-
Hola DarkVect, prueba con este ejemplo creo que te servirá:
void main() {
int valor1=0;
int valor2=240;
lcd_init();
lcd_putc("\fValor1= ");
lcd_gotoxy(1,2);
lcd_putc("Valor2= ");
while (TRUE) {
lcd_gotoxy(9,1);
printf(lcd_putc, "%3u", valor1);
lcd_gotoxy(9,2);
printf(lcd_putc, "%3u", valor2);
delay_ms(500);
valor1++;
valor2++;
}
}
saludos,
Mario
-
Los LCD también suelen tener memoria 'hacia la derecha de la pantalla'. De esa forma podrías escribir en la otra memoria y luego hacer el cambio de puntero para poder visualizar la nueva memoria.
Es un truco muy antiguo, usado constantemente en las PCs en casi todas las aplicaciones gráficas. Por eso uno no ve el 'dibujo'... porque se hace en la página no visible.
Saludos
-
En primer lugar, gracias a todos.
Azicuetano eso es lo que había pensado en el caso de que no se puediese borrar la pantalla a trozos, pero me parecía ineficiente 3 printf(...) por cada variable, aunque también se puede con uno solo y un string que según valor valga " " o " " o "".
Duende_azul no puedo hacer gotoxy por la misma razón que antes. O necesito tres if's para saber dónde poner un " " según valor. O siempre escribo " " antes de escibir la variable.
Primero provaré lo que dice Mario, supongo que es para imrprimir con 3 dígitos sea cual sea el valor. Mañana te cuento.
Maunix, tú estás varios niveles por encima de mis conocimientos y aunque entiendo lo que quieres decir no se ni por dónde empezar a la hora de programarlo. Doy gracias porque exista una librería como la flex_lcd.c así que imagina si me tengo que poner con la memoria del lcd. De todas formas te agradezco tus comentarios, pués se aprende mucho con ellos y quien sabe si algún podré llegar a dominarlos :) :)
Un saludo!!
-
Maunix, tú estás varios niveles por encima de mis conocimientos y aunque entiendo lo que quieres decir no se ni por dónde empezar a la hora de programarlo. Doy gracias porque exista una librería como la flex_lcd.c así que imagina si me tengo que poner con la memoria del lcd. De todas formas te agradezco tus comentarios, pués se aprende mucho con ellos y quien sabe si algún podré llegar a dominarlos :) :)
gracias por tus comentarios, de todas formas, no creo que tengas inconvenientes en dominar loq ue acabo de mencionar.
no es que yo sepa mucho mas, solo lo se 'antes' lo cual es diferente :) :)
-
Lo que pone Mario es correcto, y hasta podés completar con ceros si hace falta según la naturaleza del dato.
printf(lcd_putc, "%03u", valor1); // así de simple con solo agragar un cero.
Y...? Para hacer lo que dice maunix (dejar en el lcd lo que voy a mostrar a posteriori en otra ubicación)
Cómo se puede hacer??? intuyo que con escribir en direcciones fuera de pantalla ya está la primera parte, pero para mover el "puntero"... lo puedo hacer con alguna librería de C como ser lcd, lcd2, lcd flex???
O hay que modificar alguna???
De ser así sería interesante incluir esa opción en alguna de las librerías...
Otra pregunta más: Las librerías que usan transferencia de datos por 8 líneas presentan el mismo inconveniente respecto de las que usan sólo 4???
-
Bueno, ya lo tengo funcionando.
Finalmente he usado lo de poner %3u para los datos y los nombres de las variables los escribo fuera del bucle. El parpadeo ha desaparecido por completo :-/
Lo único es el efecto "raro" de tener dos espacios entre el nombre y el valor cuando este es inferior a 10, pero bueno, lo prefiero mil veces antes que el dichoso parpadeo.
Se que la solución definitiva sería la que propone azicuetano, pero voy justito de memoria y no puedo añadir las sentencias que implica.
Un saludo y mil gracias a todos!!
-
...
no es que yo sepa mucho mas, solo lo se 'antes' lo cual es diferente :) :)
...
dicho de otra manera Maunix cuando uno va ya tu vienes de regreso :D
-
En esta parte de mi libreria del LCD encuentras una forma de colocar el mensaje donde quieras, con pocas reformas.
Esta hecha para rotar el mensaje en pantalla, pero les servira si le cambian el numero de desplazamientos para llegar hasta el punto que desean... :mrgreen: :mrgreen:
// Otras definiciones para usar en lcd_send_byte
#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_DISPLAY_OFF 0x08
#define LCD_DISPLAY_ON 0x0C
#define LCD_Caracter_BLINK 0x0D
#define LCD_CURSOR_ON 0x0E
#define LCD_CURSOR_BLINK 0x0F
#define LCD_CURSOR_SHIFT_RIGHT 0x10
#define LCD_CURSOR_SHIFT_LEFT 0x14
#define LCD_DISPLAY_SHIFT_RIGHT 0x18
#define LCD_DISPLAY_SHIFT_LEFT 0x1C
void desplazar_display(int posiciones, boolean sentido)
{
// Primer parámetro: Numero de desplazamientos
// Segundo parámetro: Sentido del desplazamiento (TRUE=Derecha, FALSE=Izquierda)
int i,aux;
if (sentido) aux=LCD_DISPLAY_SHIFT_RIGHT; // Desplazamiento a la derecha
else aux=LCD_DISPLAY_SHIFT_LEFT;
for (i=1; i<=posiciones; i++)
{
lcd_send_byte(0,aux);
}
}
Las definiciones las copie todas porque son las que permite el LCD... :mrgreen: :mrgreen:
-
Gracias por la aportación MGLSOFT. Me copio esa parte para usarla en otra prueba que estoy haciendo, aunque creo que para el caso que nos atañe no la puedo utilizar porque me encuentro con el mismo problema que con lo que proponía azicuetano; tengo que conocer el número de posiciones a desplazar para utilizarla y eso me supone añadir if's al código.
Si estoy equivocado, por favor dímelo.
Un saludo!!
-
Es muy facil!!
Si la direccion inicial de la primer linea esta en 40H (confirmar si es asi con el LCD que usas) y el display es de 16 caracteres por linea, la primer posicion fuera del area de display sera 50H, escribes lo tuyo alli y luego lo desplazas la cantidad de posiciones que necesitas...
-
Se me ocurren algunas sugerencias
1) Si hay suficiente ram en el pic, grabar en un arreglo de chars lo que se quiere imprimir, y compararlo con lo que hay en el lcd (mediante operaciones de lectura) e ir cambiando solo los caracteres que deban cambiarse.
2) Aún mejor que 1, es el escribir 'fuera de la pantalla' visible alternativamente y hacer shifts izquierda o derecha del display para visualizar el nuevo resultado . Esto no debería demorar más que 1mseg que no creo que pueda notar el ojo humano.
Por ej. si hablamos de un display de 16x2.
a) Escribir de 0x00 a 0x0F y de 0x40 a 0x4F
b) luego escribir de 0x10 a 0x1F y de 0x50 a 0x5F.
c) llevar una imagen (con shifts del display) 16 veces a la derecha.
Luego se repite lo mismo, una y otra vez, pero la segunda vez actualizamos la 1er parte.
3) Que se apague el display (display off) y se actualize solo lo deseado y se vuelva a encender (display on). Aclaro que es el comando ON y OFF del display , no apagar el hardware con algún control sobre su VCC. Esto no lo he probado pero en una de esas simplifica el código.
-
OK!! Ahora entiendo lo de escribir fuera d ela pantalla. También me parece una buena opción, ya que siempre actualizaría fuera de pantalla y luego lo único que hay que hacer es moverlo todo hacia dentro.
Maunix, ¿cómo funciona eso del ON/OFF del lcd? Sería: hacer OFF, escribir, hacer ON, no?
De todas formas, como decía, lo "solucioné" con lo del %3u y se lo he mostrado a varia gente sin comentarles nada previamente y me han dicho que no lo han notado raro ni molesto.
Un saludo y mil gracias de nuevo!!
-
Maunix, ¿cómo funciona eso del ON/OFF del lcd? Sería: hacer OFF, escribir, hacer ON, no?
Sí, funcionaría de esa forma, aunque no lo he probado. Hacer off desde el comando no afecta a la memoria, simplemente a la parte que muestra el contenido.
Pero como dije antes, no lo he probado ya que nunca me vi en dicha necesidad.