TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Enigma en 28 de Abril de 2008, 02:16:40

Título: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 28 de Abril de 2008, 02:16:40
Hola que tal muchachos!!, estoy recien probando los comandos de la LCD en CCS y el 18F4550, pero tengo un problema, trato de mostrar el valor medido desde el ADC en la LCD y resulta que lo hace a medias... Pues si, a medias! :x... Si el potenciometro que está en la entrada del ADC marca 0,75 V, pues en la pantalla se me muestra 0. 5 V, si el POT marca 1.43V en la LCD se ve 1. 3 V y así sucesivamente!!! es decir, el primer numéro decimal nunca aparece.... Ya le he cambiado los modos de representación del float y nada... Ahora cuando mando eso por el hyperterminal todo se ve muy pero muy bien!! pero en la LCD se daña todo!!! Alguien sabe porque se produce esto?? Ah por cierto, si coloco el float para que lo muestre como exponencial, pues si muestra todo el numéro pero con el +e0.... :?


Por cierto para los que vayan a simular... Despues que aparezca el dibujito en la LCD, presionen el pulsador C o c, para observar el valor del ADC.......


He aquí una imágen de la simulación en Proteus!!!

(http://img263.imageshack.us/img263/2428/dibujonj5.jpg)

Y aquí el pedacito de programa que se encarga de enviar el dato a la LCD...

(http://img263.imageshack.us/img263/1661/dibujo1yo5.jpg)



Atte: Enigma... La llanerita de Guayana :-)

Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Nocturno en 28 de Abril de 2008, 02:46:12
Querida Llanerita,
el primer dígito del formato printf indica el nº total de dígitos que vas a representar, y el segundo el nº de decimales.
Yo lo haría así:
printf(lcd_putc,"Volt= %5.2f",dato);
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 28 de Abril de 2008, 03:27:50
Creo recordar que si en el numero total de dígitos a representar, le pones un número inferior al que va a salir, los dígitos que le faltan los pone él automáticamente. ¿no es así?
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 28 de Abril de 2008, 10:19:46
Querido Nocturno.... :lol:

Bueno ya intente eso, y la verdad tampoco muestra ese numero faltante!!!!! es por eso que recurri al foro, porque ya intente todo lo que sabia y pos nada!!!! :?

Aún sigue con ese error......

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Nocturno en 28 de Abril de 2008, 11:44:43
Ahora que lo miro bien también te faltan las letras "Vo". Me da que va a ser un error del Proteus.
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: micro_cadaver en 28 de Abril de 2008, 16:15:23
hola llanerita, modifica los delays de la libreria lcd16.c y revisa bien tus bucles porque tas haciendo rebundancia.
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: MGLSOFT en 28 de Abril de 2008, 17:12:01
Has probado de armarlo en la practica?? :mrgreen:
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: manex_1987 en 28 de Abril de 2008, 18:16:52
Yo voto porque es un error en proteus. A mi tambien me ha pasado eso miles de veces. A lo dicho. Menos proteus y mas protoboard.
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 28 de Abril de 2008, 23:27:16
Ya estoy empezando a creer lo mismo!!! voy a probar en vida real y luego les doy respuesta!!!! Gracias por sus opiniones!

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: poseidon20 en 29 de Abril de 2008, 01:52:03
Enigma, no aprendistes nada de tu experiencia del PWM en proteus?  :mrgreen: :mrgreen: :mrgreen: :mrgreen:. Concuerdo con los demas que a veces el porteus falla a la hora de simular cosas, por eso el descarte definitivo es la practica, aunque sea en le protoboard  :D.
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: manex_1987 en 29 de Abril de 2008, 03:49:57
Uf, y a veces ni con esas!  :P :P las puñeteras protoboard a altas frecuencias son odiosas...
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 29 de Abril de 2008, 13:03:05
Jejeje al parecer nunca aprendo!!! :mrgreen: es que siempre me había dio bien con las LCD`s y los pics en el proteus!!  :? Aunque pensandolo bien me iba bien pero era con el Proteus 7 y el 16F877A!!! Ummm!!!!!  :?

Ta bueno!! hoy probe, y está peooooorr pos no se muestra nada en pantalla! Dios!!! pero creo que se cual es el problema!!!!! Si es lo que pienso.. Les digo cuando lo resuelva!!....

Status: Probando y detectando fallas!!!.....

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: PalitroqueZ en 29 de Abril de 2008, 13:37:25
yo me niego a creer que sea un error de proteus, el proteus en cuestión de precisión ellos lo aclaran en el manual, son por unos cuantos ciclos de instrucción.

hace poco me llevé un chasco con el CCP2 en modo special trigger event, a pesar que el mplab-sim y el pic-simulator concordaban con el programa, en el isis no funcionaba, estuve a punto de desacreditarlo  :shock:

Después gracias al amigo Ralf2 descubrí un error en mi programa, y así como funcionó exitosamente en el proteus, funcionó en el protoboard.

moraleja: el mplab-sim y el pic-simulator fueron los equivocados en esta ocasión.

ahora lanzado hipotesis te pregunto enigma,

¿cuanto tiempo tarda en mostrar en pantalla ese valor, desde que  hace la conversión hasta validar el dato enviado a la lcd?

Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 29 de Abril de 2008, 14:06:29
... y ya puestos a preguntar. Estas usando una LCD de 4 líneas ¿la librería modificada que usas para el control de la LCD de 4 líneas está probada que funciona?
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 30 de Abril de 2008, 01:06:06
Hay muchachos les comento, que he cambiado mi programa!!! Lo simule en Proteus y funciona Bien solo con la salvedad de que cuando está refrescando el ADC pues lo hace mal, hace salticos y parpadea mucho!!!!

Lo probe en vida Real, y la LCD me bota pura basura!!!!!!!!!!!! se vuelve loca! no se que pueda ser, ya he montado el circuito dos veces y nada! en los dos que monte hace lo mismo!!! :? Bota puros simbolos extraños!! :5]

Respondiendo a las preguntas:

Palitroquez:

No mucho.... Algunas micro segundos, como 20 a lo mucho!!!!! :?

pocher:

Si, la Libreria sirve, ya ha sido probada!!!!! :lol:

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 30 de Abril de 2008, 03:04:41
¿y muestra todos los caracteres?
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: PalitroqueZ en 30 de Abril de 2008, 12:44:57
enigma, no te quedará mas remedio que ver el estado de los SFR dentro del ISIS,
carga el .cof, compilas y vas paso a paso viendo las lineas en C

cargas la ventana watch windows y vas metiendo los SFR de interés, luego con breakpoints de por medio vas viendo el estado de los registros.

Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 30 de Abril de 2008, 13:49:10
Otra posible prueba es dejar a la LCD solita con un miniprograma que escriba algo en las 4 líneas, así verás si la librería auxiliar funciona bien.

Yo lo acabo de hacer y ¡NO muestra los caracteres de principio de línea!

PD. Hecho y realizado con PROTEUS
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: PalitroqueZ en 30 de Abril de 2008, 14:31:57
probé el archivo que subiste y enseguida me salió unos mensajes que hay que ponerle atención:


del compilador:

(http://img501.imageshack.us/img501/5306/mensajecompiladorbg0.jpg)


del simulador:

(http://img139.imageshack.us/img139/2331/mensajeisisce4.jpg)


Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 01 de Mayo de 2008, 15:29:19
Hola chicos gracias por su gentil colaboración.... Aquí presento el informe de errores!!! acerca del programa...

Probado en vivo y directo:

Palitroquez, tenias razón.... ya verifique ese error... pero aún así en vida real la LCD me mostraba simbolos raros, es decir, me botaba mucha basura!!!! Monte de nuevo el circuito y daba lo mismo! Llegue a pensar que era el proto board... Toavia seguía botando simbolos extraños, como cuando las lineas de datos están invertidas o algo! las verifique y estaban correctas!!! En fin, le di, y con algunas sugerencias del amigo micro_cadaver, logre mejorr el programa en Proteus! es decir, ya me mostraba todas las letras en la LCD, y el error que señalo el amigo Palitrquez no se mostraba... Pero aún así cuando probaba en vida real, seguia la LCD echando broma... Mostrando sus acostumbrados simbolos extraños!!!!

Me arme de valor y empece a medir cada patica del pic, para ver si botaba los valores de voltajes correspondientes!, estaba bien, todo estaba funcionando muy bien en el pic... Luego fui a medir cada pin de la LCD, y note en uno de ellos algo raro... Cuando movi la LCD PUF!!! :shock: Empezo a mostrar todo muy bien! mostraba el voltaje, las palabras correctas! Salte de la alegria :-/... Pero luego cuando la solte, volvio a botar basura!! Y me dije bueno por lo menos se donde está el error!!! 

Cuando movia la LCD se mpostraba todo bien, pero si la soltaba se volvia a dañar, la saque la revise, y adivinen que??? :shock:

Todo el  problema fue ocasionado porque un bendito pin de la LCD habia perdido su soldadura :5]... Por eso la LCD se volvia loca!!! este pequeño pero gran desperfecto me hizo desvelarme, y perder valiosas horas de programación y arme y desarme del circuito!!! :?

En fin, esa es la historia!!!! Ahora si podré seguir avanzando!!!! :mrgreen:

Cabe destacar que esto no lo hubiera echo sin la ayuda de todos los foristas que se interesaron en ayudarme en mi problema! a todos ustedes Gracias!!!! :mrgreen:

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 02 de Mayo de 2008, 01:22:54
¿Puedes poner el programa con las correcciones para que te muestre todos los caracteres en la LCD con PROTEUS? ... me gustaría verlo.
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: micro_cadaver en 02 de Mayo de 2008, 15:29:48
hola llanerita, asi es el camino de los picmaniacos. la fuerza es intensa en ti.

 solo te falto quemar el pic jejejej  :-)

Título: Re: LCD - Enviar valor desde el ADC
Publicado por: PalitroqueZ en 03 de Mayo de 2008, 14:41:48
que chevere Enigma que lo hayas resuelto.   :-/ :-/ :-/

El otro problema con el que tenemos que lidiar: los factores físicos.

normalmente trato de que en los simuladores disminuya la cantidad de advertencias, por cierto la advertencia del compilador donde desactiva la interrupción es digna de hacerle un estudio (y siempre rezo para que no me salga en mis programas  :shock:)



Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 03 de Mayo de 2008, 18:43:25
Hola Pocher, si claro, lo colocaré... Le hice algunas modificaciones!!!!! También posee una modificación realizada por e amigo micro_cadaver :lol:

Palitroquez, porque rezas para ue no salga esa advertencia?? hablame más de eso si puedes por favor!!!!!

#include <18f4550.h>
#DEVICE ADC=8
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT,MCLR
#use fast_io (A)
#use fast_io (B)
#use fast_io (C)
#use fast_io (D)
#use delay(clock=4000000)
#include <LCD16.c>                                      // Libreria que controla los comandos de la LCD
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)          // Habilita las funciones RS232, velocidad a 9600 baudios
#byte RCON=0xFD0                                        // Registro que controla el reset por POR (POWER ON RESET)
#bit POR=RCON.1                                         // Bit de la bandera del Power On Reset
#bit IPEN=RCON.7                                        // Habilita la prioridad de las interrupciones
#byte PIR2=0xFA1                                        // Registro de control de las interrupciones
#byte INTCON1=0xFF2                                     // Registro de control de las interrupciones
#bit RBIF=INTCON1.0                                     // Bit de Interrupción por cambio en el puerto B (RB4-RB7).
#byte INTCON3=0xFF2                                     // Registro de control de interrupciones
#byte PIE1=0xF9D                                        // Registro de habilitación de interrupciones perifericas
#byte PIE2=0xFA0                                        // Registro de habilitación de interrupciones perifericas

#zero_ram
//::::::::::::::::::::::::::Declaración de variables:::::::::::::::::::::::::::::::::::::
float value,dato,value_antiguo;
int caracter;

//::::::::::::::::::::::::::Declaración de Funciones:::::::::::::::::::::::::::::::::::::
void menu(void);                                        // Función que me muestra el menú de opciones
void ajustar_trans(void);                                   // Función que calibra al transmisor
void  enviar_rs232(void);                               // Función que envia los datos vía RS232
void  enviar_rs485(void);                               // Función que envia los datos vía RS485

//::::::::::::::::::::::Interrupción por RB0:::::::::::::::::::::::::::::::::::::::::::::::::::

#INT_EXT
EXT_isr()
{
   menu();
}

//:::::::::::::::::::::::::::Programa Principal:::::::::::::::::::::::::::::::::::::::::::
void main(void)
{
         set_tris_a(0x01);                            // Puerto A, como b'00000001
         set_tris_c(0x00);                            // Puerto C, como b'11111111
         set_tris_b (0xFF);                           // Configura puerto b como entrada
         set_tris_d(0x00);                            // Puerto A, como b'00000000
         
         output_a(0);
         output_b(0);
         output_c(0);
         output_d(0);
         
         port_b_pullups(TRUE);                        // Activo las pullups
         enable_interrupts(global);                   // Habilito todas las interrupciones
         enable_interrupts(int_ext);                  // Activa máscara INTE (Activo interrupción po RB0)
         setup_port_a(AN0_ANALOG );                   // RA0 son analógicos y los demás son digitales
         setup_adc(ADC_CLOCK_INTERNAL );              // Tomará el dato contando el tiempo con el reloj interno
         ext_int_edge (H_TO_L);                       // Flag INTF si flanco de bajada.
         IPEN=1;                                      // Deshabilito la prioridad de las interrupciones
         RBIF=0;                                      // RB4-RB7 no provocó una interrupción externa por cambio
         PIE1=0x00;                                   // Deshabilito interrupciones por otros perifericos (CCP,USART, etc)
         PIE2=0x00;                                   // Deshabilito interrupciones por otros perifericos (USB, Oscilador, colisión, memoria, etc)
         if(POR==0)                                   // Reset por POR
         {
            output_high(PIN_C1);                      // Enciendo un led de prueba
            delay_ms(1000);                           // Una demora para que se estabilicen los voltajes
            POR=1;                                    // Limpio la bandera del POR
            output_low(PIN_C1);                       // Apago un led de prueba
         }
         lcd_init();                                  // Para inicializar el LCD

//*************************************************************
//*                     CICLO PRINCIPAL                       *
//*************************************************************


   lcd_enviar(LCD_COMANDO,LCD_CLEAR);       // Borro pantalla LCD
   delay_ms(5);                             // Retardo para el comando de la LCD
   lcd_enviar(LCD_COMANDO, LCD_CLEAR);      // Envía comando al LCD
   delay_ms(5);                             // Retardo para el comando de la LCD
   lcd_gotoxy(1,1);                         // Posiciona el cursor
   printf(lcd_putc,"  Transmisor");         // Visualiza mensaje
   lcd_gotoxy(1,2);                         // Posiciona el cursor
   printf(lcd_putc,"  de Presion ");        // Visualiza mensaje
   lcd_gotoxy(1,3);                         // Posiciona el cursor
   printf(lcd_putc,"  Diferencial");        // Visualiza mensaje
   delay_ms(3000);                          // Visualizo la información por 3 segundos
   
   lcd_enviar(LCD_COMANDO,LCD_CLEAR);       // Borro pantalla LCD
   delay_ms(5);                             // Retardo para el comando de la LCD
   lcd_gotoxy(1,1);                         // Posiciona el cursor
   printf(lcd_putc,"Realizado por:");       // Visualiza mensaje
   lcd_gotoxy(1,2);                         // Posiciona el cursor
   printf(lcd_putc,"Vargas Marlin");        // Visualiza mensaje
   delay_ms(50);                            // Retardo para el comando de la LCD
   delay_ms(3000);                          // Visualizo la información por 3 segundos

   lcd_enviar(LCD_COMANDO,LCD_CLEAR);           // Borro pantalla LCD
   delay_ms(5);                                 // Retardo para el comando de la LCD
   value_antiguo=0;
         while(true)
         {
            set_adc_channel(0);                          // El canal de adquisición del dato es el RA0
            delay_us(10);                                // Un retardo para capturar bien el dato
            value=read_adc();                            // Leo el dato
            dato=(value*5)/255;                          // Convierto el valor a decimal y lo guardo
           
            if(value!=value_antiguo)
            {
//               printf(lcd_putc,"\f");                       // Borro pantalla
               lcd_enviar(LCD_COMANDO,LCD_CLEAR);           // Borro pantalla LCD
               delay_ms(5);                                 // Retardo para el comando de la LCD

               lcd_gotoxy(1,1);                             // Posiciona el cursor
               printf(lcd_putc,"Volt= %2.2g",dato);         // Mando a mostrar el valor del conversor
               value_antiguo=value;
            }               

            if(input(PIN_B1)==0)                         // ¿Ajustar el transmisor?
               {
                  ajustar_trans();                       // Si, voy a la función ajustar
               }

            if(input(PIN_B2)==0)                         // ¿Enviar Via RS232?
               {
                  enviar_rs232();                        // Si, voy a la función que envia a través del RS232
               }

            if(input(PIN_B3)==0)                         // ¿Enviar via RS485?
               {
                  enviar_rs485();                        // Si,  voy a la función que envia a través del RS485
               }
           }

}
//::::::::::::::::::::::::::::Función que permite ver el memú de opciones::::::::::::::::::::::::::::::
     void menu(void)
      {
         lcd_enviar(LCD_COMANDO, LCD_CLEAR);               // Envía comando al LCD
         delay_ms(5);                                      // Retardo para el comando de la LCD
         lcd_gotoxy(1,1);                                  // Posiciona el cursor
         printf(lcd_putc,"   Menu");                       // Visualiza mensaje
         lcd_gotoxy(1,2);                                  // Posiciona el cursor
         printf(lcd_putc,"(A)Ajuste");                     // Visualiza mensaje
         lcd_gotoxy(1,3);                                  // Posiciona el cursor
         printf(lcd_putc,"(B)Envio RS232");                // Visualiza mensaje
         lcd_gotoxy(1,4);                                  // Posiciona el cursor
         printf(lcd_putc,"(C)Envio RS485");                // Visualiza mensaje
         delay_ms(50);                                     // Retardo para el comando de la LCD
         delay_ms(4000);                                   // Visualizo la información por 4 segundos
      }

//::::::::::::::::::::::::::::Función que permite calibrar el transmisor::::::::::::::::::::::::::::::
void ajustar_trans(void)
{
   output_high(PIN_C2);
   delay_ms(1000);
   output_low (PIN_C2);
}

//::::::::::::::::::::::::::::Función que permite enviar los datos via RS232::::::::::::::::::::::::::::::
void  enviar_rs232(void)
{
   output_high(PIN_C4);
   delay_ms(1000);
   output_low (PIN_C4);
}

//::::::::::::::::::::::::::::Función que permite enviar los datos via RS485::::::::::::::::::::::::::::::
void  enviar_rs485(void)
{
   output_high(PIN_C5);
   delay_ms(1000);
   output_low (PIN_C5);
}



Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: pocher en 04 de Mayo de 2008, 03:50:39
Gracias Enigma.

Ahora ya tengo claro porqué PROTEUS no mostraba los caracteres de principio de línea. Era por la frecuencia de oscilación, si le pones 20Mhz, como inicialmente tenías, no va bien ... lo máximo que admite funcionando bien y sacando todos los caracteres es 15Mhz.

Por cierto ¿has provado físicamente con 20Mhz?
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 05 de Mayo de 2008, 16:18:37
 :shock: Rayos no sabia ese pequeño detallito de Proteus y la frecuencia!!! Gracias por el dato! :mrgreen:

Bueno sabes que si probe con 20 Mhz, y la verdad no me mostraba el voltaje, supongo que ha de ser por el protoboard ya que con frecuencias altas pues a veces da errores!!!! Pero he sabido de gente y he visto circuitos que han funcionado bien con 20 Mhz... Lastima que el mio no fue uno de ellos!!! Además era la primera vez que trabajaba con 20 Mhz, siempre lo había hecho con 4Mz, y por lo visto con 4Mhz me seguiré quedando!!!! :g)

Atte: Enigma... La llanerita de Guayana :-)
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: PalitroqueZ en 05 de Mayo de 2008, 18:37:45
... porque rezas para ue no salga esa advertencia?? hablame más de eso si puedes por favor ...

claro si el compilador te desactiva una interrupción que habias planeado, ¿como haces? hay algo malo por allí.

Título: Re: LCD - Enviar valor desde el ADC
Publicado por: MGLSOFT en 05 de Mayo de 2008, 21:34:27
Nunca habias mencionado que usabas 20 Mhz, la libreria usa los delay_cycles() que realmente consumen ciclos de reloj, eso hace que entre 4 Mhz y 20 Mhz se ejecuten 5 veces mas rapido.

Prueba cambiar cada uno de los:
 delay_cycles(1);

por:

delay_us(1);

que tardan 1 microsegundo exacto sin importar el reloj que uses...
Eso es lo que tarda una instruccion delay_cycles() con el cristal a 4 Mhz... :mrgreen: :mrgreen: :mrgreen: :lol: :lol:
Título: Re: LCD - Enviar valor desde el ADC
Publicado por: Enigma en 06 de Mayo de 2008, 00:05:18
Umm... Tampoco sabia eso!!! gracias por ese consejo!! voy a implementarlo para el proximo circuito!!!

Atte: Enigma... La llanerita de Guayana :-)