Antes que nada, me corrijo a mi mismo, cuando uno obtiene aleatoriedad en los 2 bits menos significativos tiene una inexactitud máxima de +-4LSb, y no de -+2LSb como habia dicho en mi otro mensaje, eso me pasa por escribir rápido
MLO, si realmente en tu ADC no puedes obtener mejor exactitud que las centenas entonces estas teniendo graves problemas con la adquisición de datos. Bien, como ya he dicho anteriormente, este error puede ser por una mala implementación de la toma de datos por SW, en general le podes errar definiendo mal la frecuencia de oscilacion o bien no realizando el código según el procedimiento recomendado, sobre todo esta ultima equivocación se comete cuando se multiplexan los canales de lectura del ADC o bien se intentan tomar muestras seguidas en el mismo canal. Bien, el oscilador RC interno tiene dos problemas a saber: Tiene un periodo de 4 us, en realidad oscila entre 2 y 6 us, y por lo tanto no se rige bajo un frecuencia exacta y es un reloj relativamente lento sabiendo que con el reloj del PIC podemos obtener tiempos menores al us (por mas que violemos las especificaciones del ADC convirtiendo a estos periodos, sin embargo los he utilizadon en ciertos casos cuando necesite sacrificar bits de precision por un muestreo mas rápido) El otro problema es que no debe utilizarse si el PIC esta funcionando a frecuencias mayores de 1 MHz, nunca he leido porque, debe ser que existen ciertos circuitos en el ADC que siempre funcionan regidos bajo el reloj de cristal y el oscilador RC comienza a tener una deriva en su frecuencia respecto a la de estos circuitos, falseando la medición. Entonces me dirán ahora que el oscilador RC es una porqueria y que para que lo pusieron ahi, pues bien, el oscilador RC se utiliza para convertir con el ADC mientras el PIC esta durmiendo, es un método que yo utilizo bastante y con la que se obtiene la mayor precisión posible con el ADC del PIC. Aquí expongo el código para ese método, obviamente habra que realizar las correciones correspondientes para utilizarlo con nuestro circuito:
// En la carga inicial del PIC colocamos:
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
// Luego para cada conversión ejecutamos el código asi:
disable_interrupts(GLOBAL);
enable_interrupts(INT_AD);
clear_interrupt(INT_AD);
read_adc(ADC_START_ONLY);
sleep();
delay_cycles(1);
Valor = read_adc(ADC_READ_ONLY);
disable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
Bien, algunas herramientas que puedes implementar bajo SW y que no agregan precisión a la lectura pero si estabilidad en la misma (obviamente sacrificando muestreos) son el MA (moving average, el promediar valores por asi decirlo) y los filtros digitales FIR o IIR (En general con un filtro FIR pasabajos de primer orden es suficiente). No se confundan, estos metodos solo deben ser aplicados cuando ya hemos optimizado al máximo el HW acondicionador de la señal y el SW y la variación aleatoria es inherente a la función matemática generadora de la señal.
Aunque tu código este realmente mal y el método que utilizes sea incorrecto (no digo que sea lo que estas haciendo MLO, solo estoy suponiendo el peor de los casos
) es muy raro que esto te produzca semejante variación en los valores de lectura del ADc, por lo que yo supongo que estas errando en el HW, un tema que es demasiado extenso para tratar en este post, además de que estoy algo apurado y quiero tocar la pregunta de scientist. Será para el proximo mensaje
Scientist, no hay un prescalador definido para una frecuencia de reloj determinado, en general hay que tratar de obtener el menor tiempo de muestreo sin descender por el valor de TAD minimo que especifica Microchip (esto si quieres obtener una resolución igual a la fundamental del ADC). El valor de TAD minimo depende del PIC que estes utilizando, en general para la linea de 16F y la serie estandar C de Microchip, es de 1.6 us. Ah, me olvidaba, el TAD es el tiempo que se utiliza como referencia en los ADC y se denomina como el tiempo de conversión requerido para un bit. Supongamos este valor y ahora
veamos todas las opciones que tienes:
2 x Tosc (adc_clock_div_2) = 2 x (1/ 4 . 10^6 Hz) = 500 ns = VIOLA EL TAD MINIMO, NO UTILIZAR
8 x Tosc (adc_clock_div_8) = 8 x (1/ 4 . 10^6 Hz) = 2 us
32 x Tosc (adc_clock_div_32) = 32 x (1/ 4 . 10^6 Hz) = 8 us
Oscilador RC (adc_clock_internal) = 2 a 6 us = NO UTILIZAR EN ESTE CASO
Utiliza el adc_clock_div_8 para un tiempo de muestreo minimo pero recuerda revisar primero el datasheet de tu PIC para verificar los valores minimos de TAD. Espero haber sido claro con mis explicaciones.
Nos estamos escribiendo.