Mala lectura conversor de analogo digital

Buenas tarde a este gran foro.
como dice el titulo, tengo un programa realizado en ccs (o pic c) y resulta que a la hora de mostrar el valor analogo (que deberia ser 5v o menos ) muestra un valor totalemente extraño, sinmas preambulo podrian ayudarme

como ven es muy facil el programa, el problema creo que esta en la conversion o en el 1023 si no fui claro dejo un ejemplo coloco un 1 voltio y en valor análogo dice 12.82 (deberia decir 1v) y en el valor digital da 13120 cosa que la verdad no se por que GRACIAS

#include <main.h>
#include"flex_lcd.c"

void main()
{
float valor;
float valordig;


//configuracion del canal analogico
setup_adc_ports(AN0_TO_AN2|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32);

set_tris_a(0xFF);
lcd_init();
lcd_gotoxy(3,1);
lcd_putc("voltimetro");
delay_ms(250);



while(TRUE)
{
//asigana el canal 0 al conversor o leer el canal 0
set_adc_channel(0);
delay_us(10);
valordig=read_adc();
delay_ms(1);
lcd_gotoxy(1,1);
printf (lcd_putc,"V-DIG, es:%f",valordig);
valor=valordig/1023;
lcd_gotoxy(1,2);
printf (lcd_putc,"V-ANA, es:%f",valor);
delay_ms(100);



}

}
 
Es que tu programa esta incorrecto en el siguiente sentido:

El valor que vas a obtener en read_adc() es 0-1023 si tenes el conversor configurado en 10 bits. Hasta ahi OK.

Como decis VSS_VDD en la config, esto indica 0-5v (los 5v del pic tienen que ser exactos ojo ahi)

entonces: 5v / 1024 = 0,0048828125 volts por cada unidad que te devuelva read_adc

deberias hacer algo como:

valor = 0,0048828125 * read_adc();

Para obtener una lectura expresada en voltios.
 
gracias por responder, intente lo que me dijiste y lastimosamente no da por ejemplo lo pongo 2.45v y me muestra en la lcd algo como 156.56 le modifique esa parte y no mas mira

pd: tendra algo que ver que son flotantes? te dejo una captura para que observes GRACIAS de nuevo

while(TRUE)
{
//asigana el canal 0 al conversor o leer el canal 0
set_adc_channel(0);
delay_us(10);
valordig=read_adc();
delay_ms(1);
lcd_gotoxy(1,1);
printf (lcd_putc,"V-DIG, es:%f",valordig);
valor=read_adc()*0.0048828125;
lcd_gotoxy(1,2);
printf (lcd_putc,"V-ANA, es:%f",valor);
delay_ms(100);
}
}
 

Adjuntos

  • Sin título.png
    Sin título.png
    172.4 KB · Visitas: 15
precisamente eso ya lo intente y da un valor totalmente distinto. Ahora que lo pienso como es un pic 18f4550 el profesor nos dijo (hace como 2 años) algo tenia que ver con 10 o 8 bits podria ser eso lo que esta mal
 
Puede ser, incluye en el código justo después del #include

#device ADC=10

Porque por experiencia propia, el CCS pone 8 bits por defecto.
 
gracias por responder basicamente no me deja colocar es enunciado me da los siguientes errores
*** Error 23 "main.c" Line 3(8,9): Can not set this option this far into the code
*** Error 48 "main.c" Line 3(9,12): Expecting a (
*** Error 43 "main.c" Line 3(13,15): Expecting a declaration
 
Los niveles son 1024, lo que son 1023 es la lectura máxima.

La unidad de c/nivel será Vcc/1024 o en este caso 5v/1024 y obviamente nunca se podrá llegar a leer 5v, sino 4,99v.
 
Gracias por responder podrás proponerme alguna solución es que la verdad no encuentro la solución he intentado con valor que lee *5 /1024 GRACIAS
 
Tenés que hacer como dijo el amigo seaarg, directamente multiplicarlo por esa constante de conversión, en vez de hacer la división (evitás esa operación que a la larga no es más que una constante). Por otro lado tenés que usar la variable adecuada, por ej. la variable que arrojará la conversión sería conveniente "castearla" a flotante, es decir:

Código:
valor = 0,0048828125 * (float)(read_adc());

Y obviamente la variable "valor" deberá ser flotante. O usar una variable flotante previa:

Código:
variable_flotante=read_adc();
variable_flotante= 0,0048828125 * variable_flotante;

Yo la otra alternativa que uso para evitar flotante es usar "unsigned long int" y tratarlo como un entero, es decir:

Código:
variable_long_int=read_adc();
variable_long_int= 488 * variable_long_int;

Después resulta mucho más sencillo trabajar con esa variable a la hora de imprimirla en el LCD sin necesidad de usar algún sprintf o algo similar. si hay que tener en cuenta el truncamiento de decimales. Como resultado en vez de obtener 4,9951...; obtenés 499224, te alcanza para truncar en los 2 1eros decimales.
 
Última edición:
Gracias a todos por responder el error era un poco tonto, tenia que darle click derecho en el main, "open file at coursor" y cambiar y cambiar el ADC que por defecto es 16 por un 10 mil gracias.

Ahora podria hacer una pregunta mas es que basicamente lo que intento hacer es hacer un sensor de temperatura que guarde los datos, estuve investigando un poco como guardar esos datos y creo que la mejor opcion es Valores Separados por Comas (.CSV) ustedes que opinan y si es asi sabrian algun tutorial?

ademas me podrian recomendar un sensor de temperatura no muy caro (estuve pensando en una termosonda o termocupla o termopar) es para ambiente con temperaturas entre 10 y -10 grados centigrados
GRACIAS
 
Como dice cosme, el problema ya no esta tanto en la logica sino en los tipos de variables. Nunca tenes que confiar en las conversiones implicitas porque me he dado cuenta que en C de PIC es peor aun que en C de PC :)

Tambien ojo con las variables float porque hacen recortes y conversiones varias que pueden variar el resultado final. Probablemente no te quede otra que usarlas, pero en ese caso, hace los cast correctos.

A proposito: Cuando yo te explique lo de mas arriba, puse read_adc() como termino en la ecuacion para simplificar pero no lo tomes tan literal! en tu codigo terminaste haciendo 2 lecturas al ADC que no tienen sentido. Hace solo 1

Proba con esto (lo hago de memoria asi que puede haber algo mal)

Código:
unsigned int16 valordig;
float valor;

while(TRUE)
{
//asigana el canal 0 al conversor o leer el canal 0
set_adc_channel(0);
delay_us(10);
valordig=read_adc();
delay_ms(1);
lcd_gotoxy(1,1);
printf (lcd_putc,"V-DIG, es:%Lu",valordig);
valor=(((float)valordig) * 0.0048828125);
lcd_gotoxy(1,2);
printf (lcd_putc,"V-ANA, es:%f",valor);
delay_ms(100); 
}
}

Ups! termine de guardar este mensaje y aparecio el tuyo diciendo que lo solucionaste.
 
Atrás
Arriba