Estoy intentando leer un sensor de temperatura (Lm35) de mi ADC pic16f887. La cosa es que estoy obteniendo una diferencia de aproximadamente +/- 15 ticks en los resultados. ¿Se espera esto? ¿Debo estar haciendo el medio de varias adquisiciones?
El Lm35 da la temperatura en mv, donde 10mv = 1 grado celsius. El rango va desde (20mv a 1.5v), aproximadamente 2º a 150º. Debido a que en teoría el ADC tiene una precisión de 0.5º. (1024 ticks = 5v de los cuales obtenemos 307 ticks = 1.5v y como 150 grados 150/307 = 0.5º).
Para mejorar esta precisión de medio grado, he agregado un diodo Zener de 2.5v a vref + con un capacitor 10uc. Así, el circuito final que tengo es este.
Pero todavía estoy obteniendo variaciones de + -15 tic. variatons, ¡lo cual es mucho en grados!
Y el código que estoy usando es este.
#include <xc.h>
#include <pic16f887.h>
#define _XTAL_FREQ 8000000
#pragma config FOSC = INTRC_CLKOUT, WDTE = OFF, PWRTE = OFF
#pragma config MCLRE = ON, CP = OFF, CPD = OFF, BOREN = OFF
#pragma config IESO = ON, FCMEN = ON, LVP = OFF
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
void uart_init(const long int baudrate) {
SPBRG = 12;
TXEN = 1;
SPEN = 1;
SYNC = 0;
TRISC6 = 0;
TRISC7 = 1;
}
void uart_write(char data) {
while (!TRMT) {}
TXREG = data;
}
uchar uart_tx_empty() {
return (uchar)TRMT;
}
void uart_write_l(char *text, uint size) {
for (int i = 0; i < size; i++) {
uart_write(text[i]);
}
}
ushort read_adc() {
ADON = 1;
__delay_ms(100);
GO_DONE = 1;
while (GO_DONE) {}
ADON = 0;
ushort res = 0;
res = ADRESH << 8;
res |= ADRESL;
return res;
}
void main(void) {
uart_init(9600);
ANS0 = 1;
TRISA0 = 1;
PORTD = 0; // Set led port
TRISD = 0; // LED Output
OSCCON = 0x70; // 8mhz internal clock
ADFM = 1; // right justified
VCFG0 = 1; // Vref+
ADCON0 = 0b11000000;
while (1) {
ushort result = read_adc();
char *arr = (char *)&result;
uart_write_l(arr, 2);
RD1 = 1;
__delay_ms(500);
RD1 = 0;
__delay_ms(500);
}
return;
}