I'm trying to read a temperature sensor (Lm35) from my pic16f887 ADC. The thing is I'm getting a difference of about +/- 15 ticks in the results. Is this expected? Should I be doing the mean of several acquisitions?
The Lm35 gives temperature in mv, where 10mv = 1 celsius degree. The range goes from (20mv to 1.5v), roughly 2º to 150º. Because this in theory the ADC has an accuracy of 0.5º. (1024 ticks = 5v from which we get 307 ticks = 1.5v and since this is 150 degrees 150/307 = 0.5º).
To improve on this half a degree accuracy I've added a 2.5v zener diode to vref+ with a 10uc capacitor. Thus the final circuit I have is this.
simulate this circuit – Schematic created using CircuitLab
But I'm still getting variatons of +-15 ticks variatons, which is a lot in degrees!
And the code I'm using is this.
#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;
}