Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me fix my unstable ADC

Status
Not open for further replies.

zanor

Member level 4
Joined
Feb 17, 2006
Messages
79
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Norway
Activity points
2,039
Hi!

I'm using ADC on 16f819 and bit banging the result to my PC. But the adc result is so unstable, it keeps jumping up and down(ex. 950 jumps between 947 and 953).

I have connected a 1k pot to the inputs.

here's my mikroC code:
Code:
unsigned short data = 0, ro = 1;
unsigned short *er;

void Comm_WriteConst(const unsigned char *s)
{
  while(*s)
    {
      Soft_Uart_Write(*s) ;
      s++ ;
    }
}

void SENDB(char sendme) {
  Soft_UART_Write(sendme);
}

void WAITB() {
    while(*er) {
      data = Soft_UART_Read(er);
    }
    ro = 1;
}

void main() {
  er = &ro;

  OSCCON = 0xFF;
  TRISA = 0xFF;
  TRISB = 0b00000010;
  PORTA = 0b00000000;
  PORTB = 0b00000000;

  ADCON0 = 0b01000001;  // Max 20MHz, Channel 0, ADC ON
  ADCON1 = 0b01000000;  // 4 analogue channels and
                        // Left Justified (ADRESH = 8Bit result)
                        
  Soft_UART_Init(PORTB, 1, 0, 9600, 0);
  Delay_ms(10);

  while(1) {

   WAITB();
   
   if(data == 'a')
   {
     SENDB('a');
     
      ADCON0 = 0b01000001;
      Delay_ms(1);
      ADCON0 = 0b01000101;
      while(ADCON0 & 0x4);
      SENDB(ADRESH);
      SENDB(ADRESL);
      
      ADCON0 = 0b01001001;
      Delay_ms(1);
      ADCON0 = 0b01001101;
      while(ADCON0 & 0x4);
      SENDB(ADRESH);
   }


  }


}


Doeas anyone have clue about what to do to make this stable? Or is ADC just this unstable?
BTW, I'm running the 8MHz internal osc.

EDIT: And when I tie the input pin directly to ground I read 0 - 4. This can't be right, or?
 

pic adc averaging

check vcc, vref decouplig (100nf+10uf)
ensure that you have correct impedance at adc input
try to see noise at adc in (scope)
easiest way is to use averaging
 

adc unstable display output pic

Since you are using more than 8 Bits of resolution you should have a propper layout. A two layer PCB with a solid ground plane. Decoupling caps should be considered as well.
Do you have an RC filter in your ADC input ?
What supplies the Analog Vcc ?

Farshid
 

unstable adc

1. Layout is critically important. Keep digital circuitry away from analog signals.

2. With up to 1KΩ source impedance (from your pot), you must provide some capacitance at the adc input to help reduce noise that will inevitably couple onto your input signal.

3. Don't use digital vcc (or its divided voltage, via pot) as the source for your analog input. Similarly, try to think of a way to get a clean ground on the grounded end of your pot. See number 1.

4. Consider using digital averaging. For example, sum together 16 consecutive adc samples and then right-shift the sum by 4 bits (this divides the sum by 16 without a bunch of math).
 

pic noisy adc

thanks for your replies.

So what you are realy saying is that I'm just lucky to have such good result on my breadboard? hehe
Tried with a 1uF cap on adc input but didnt help.
 

pic adc adresh adresl averaging

Yes, you have been lucky to get such good results! Try out some of the ideas listed above and you will probably get better results, although there are fundamental limitations to noise performance when the adc is integrated into the same device that contains digital circuitry such as cpu, timers, interrupt controller, serial comm, ...
 

pic18f adc

take few samples (maybe 100) and average them and then send that on PC
 

pic adc source impedance

hi
1) use low pass filter at th input of ADC.
2) use isolated ground on your Project. (DC-DC converter is best choice)
3) u can also use DSP Algoritms to reduce the input side noise.
 

pic16f877 adc output unstable

part from another thread:

Noise cancellation in software:
Oversampling will help to cancel random noise
16 samples averaged will reduce noise by (√16=4) to ¼
256 samples ..........................................(√256=16) to 1/16
according to sampling theory!!

16 samples require 4bit right shift of addition total
256 samples - discard LSByte of total ..... simple and very effective

regards Polymath

Added after 14 minutes:

With PIC you can use RC clock for ADC clock source
disable COMMS
start ADC
put PIC in SLEEP to minimise digital noise
WAKE PIC on ADC DONE interupt
enable COMMS & send data

ensure acquisition time is maintained between samples
(see ADC on data sheet)
and required delay when switching between analogue sources

If mains hum is a problem adjust sample rate to auto-cancel hum

just reread your posting - does the output change cyclically ie. hunts up and down regularly if so suspect mains hum on input/reference.
 

isolate gnd channel of adc

everything anybody mentioned here is true but still
i did several pic adc with common ground, no lpf, only bypass c and never had problem with such high noise. breadboard with bypass c only gives me abt 1-2 bit noise maximum. so probably there is other problem
regards

cancel
 

reduce noise at the input of adc

cancel said:
i did several pic adc with common ground, no lpf, only bypass c and never had problem with such high noise. breadboard with bypass c only gives me abt 1-2 bit noise maximum
And that is approximately the level of noise seen by zanor: 947 to 953 is ±3 counts.
 

pic adc unstable reading

ok .. i was not clear total diff of 3 (not+-3) which is half of mentioned here. Try to decrease ad clock afaik your settings are ma 10mhz now.
 

POLYMATH you mentioned about the output change can u explain

I have the exactly the same problem you mentioned.

"just reread your posting - does the output change cyclically ie. hunts up and down regularly if so suspect mains hum on input/reference."

I'm triying to drive led with PWM pulses according to the value i read from adc(10kohm pot from AN0 input). I use pic 16F877A (4Mhz crystal). I use 10 bit adc in that pic. But i only use 8bit of that. So that makes 0-255 range and i can directly change PWM duty cycle which has same range.

My problem is i see the led blinking. It should be dimming the led with those pulses but it dimms and blinks at the same time.

When i add a 100ms delay after the function (which i use to change duty cycle) i see a ripple on my PWM pulses and it runs on those pulses faster than pulses. This ripple has a cycle as u mentioned. So i put a 47nF ceramic capacitor between pics output pin and GND. But it didnt worked.

Can u plz explain why does it happens so regularly(with cycle). I'm sure that problem is my adc. Time is running out for me. This is a professional project and i have to complete it before the deadline. So i will be very glad if people who has experiance on that issue can help me.

Thanks to all.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top