View previous topic :: View next topic |
Author |
Message |
codewrecker2
Joined: 23 Dec 2005 Posts: 23
|
ADC variation |
Posted: Mon Jun 05, 2006 5:19 am |
|
|
hi guyz.I am using pic 16f689 having 10bit a/d .I have a analog voltage which varies in the range of 0.5 to 4.5V.When i convert this into digital,the value seems to vary a lot ,even though the analog voltage is constant throughout.even 0.02V difference between readings is bad for me .why is this variance ? is it noise or the a/d resolution at play? any way around this?thanx in advance. |
|
|
Ttelmah Guest
|
|
Posted: Mon Jun 05, 2006 6:59 am |
|
|
It could be a whole range of things:
1) Noise in the Vref. Obvious one.
2) Noise in the source. Again obvious.
Note on both of these that signal routing, is critical. How are the sources buffered?. What signals are nearby?. How are the lines routed?. Use of a guard ground round the analog pins may need to be considered.
3) Wrong clock selection. Note the comments about the internal RC clock in the data sheet.
4) What the processor is doing while the sample is taken?. The processor itself can develop internal noise during the sampling process. This is why 'sleeping' the processor during the ADC reading, may be necessary to get the best resolution.
With a signal brought in, on shielded cable, to a buffer op-amp, with a virtual ground round the input pins, and then routed to the ADC input, using a bandgap reference, with careful layout round all these pins, one bit repeatability is relatively easy.
Best Wishes |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Jun 05, 2006 9:25 am |
|
|
We do not have enough information to be able to help you, more concretely,
we do not know what hardware you are using nor the code of your program.
With little information everything what we can do is to suppose.
Humberto |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Re: ADC variation |
Posted: Mon Jun 05, 2006 10:07 am |
|
|
codewrecker2 wrote: | is it noise or the a/d resolution at play? |
It's noise. Tha A/D resolution is 0.005V in the worst case, when Vref=+5V.
codewrecker2 wrote: | any way around this? |
The quickest way around this is ading a low-pass filter. It can be either digital (like averaging). Or an analog RC or LC. But it's better to remove the noise source rather than trying to reduce the noise that have already got into your system. At this point, unfortunately, we know next to nothing about your hardware and we don't know what your potential noise sources might be. |
|
|
codewrecker2
Joined: 23 Dec 2005 Posts: 23
|
|
Posted: Tue Jun 06, 2006 5:56 am |
|
|
I have a honeywell pressure sensor which feeds the analog signal to the pic. Therez a mosfet close to the analog pin which switches a 12 V dc motor which pumps into the sensor.These are some snippets of the code.
Code: |
#include <16F689.h>
#device *=16 ADC=10
#include<stdio.h>
#include "lcd.h"
#FUSES NOWDT, INTRC_IO, NOPROTECT,NOBROWNOUT,NOMCLR, NOCPD,PUT, NOIESO, NOFCMEN //CONFIG word
#use delay(clock=8000000)
|
the A/D routines:
Code: |
#separate
void adc_init(void)
{
setup_adc( ADC_CLOCK_DIV_32 ); //Fosc/32-->conversion clock freq. for 4Us TAD(min=1.6Us)
set_adc_channel( 3 ); //right justified. A/D module turned on,channel3 selected
}
//////////////////////
////*ADC READING*////
////////////////////
void adc_read(void)
{
unsigned long y;
float decivolts;
unsigned char outString[10];
delay_ms(100); //acquisition delay= amplifier time +cap.charging time
GO=1; //start conversion
while(GO)continue; //poll GO for cobversion completion
ADIF=0;
y=Read_ADC(ADC_READ_ONLY);
lcd_home();
sprintf(outString,".%ld.",y);
lcd_puts(outstring);
lcd_home2();
sprintf(outString,".%4x.",y);
lcd_puts(outstring);
}
|
-------------------------------------------------
hope this makes it a little clearer 4 u guyz |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
More questions. Specific ones. |
Posted: Tue Jun 06, 2006 12:28 pm |
|
|
codewrecker2 wrote: | Therez a mosfet close to the analog pin which switches a 12 V dc motor which pumps into the sensor. |
You are not making a call to setup_adc_ports() in the code you've posted. What are you using as Vref for the ADC?
Do you see unwanted variations in your ADC readings, when your motor is off?
Is the output of your pressure sensor ratiometric or absolute? (Just curious, what's the part number for it?)
Does the PIC and the pressure sensor use the same power supply rail? |
|
|
codewrecker2
Joined: 23 Dec 2005 Posts: 23
|
|
Posted: Tue Jun 06, 2006 11:04 pm |
|
|
sorry for not mentioning b4,the reason why i didnt have setup_adc_port() was because i had set ports manually this way:
Code: |
#separate
void port_init (void)
{
OUTPUT_A(0x00);
ANSEL=0x0C;
ANSELH=0x07;
SET_TRIS_A(0x1F);
OUTPUT_B(0x00);
SET_TRIS_B(0x30);
OUTPUT_C(0x00);
SET_TRIS_C(0xC0);
port_a_pullups(FALSE);
WPUB=0x00;
CM1C0N0=0x00;
CM2CON0=0x00;
}
|
The sensor gives a stable analog o/p in the range of 0.5 to 4.5V and has same power rail and a common ground with that of the pic. I havnt defined vref in setup_adc because i thought by default its VDD.
the readings are taken when the motor is off . |
|
|
|