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.

[SOLVED] ADC : need to sense in millivolts

Status
Not open for further replies.

Raady Here

Full Member level 5
Joined
Jun 8, 2013
Messages
242
Helped
26
Reputation
52
Reaction score
26
Trophy points
28
Location
India
Activity points
1,571
PIC30f5011, MPLAB 8.8,

HI,
I am reading voltages which vary from 2 millivolt to 4.8v

I have configured adc and reading the value aprox.
but getting huge error while reading milli volts.

Fluke reading(v)----adc reading(v) error
3.012----------------3.008----------------4 mv
1.002----------------0.991----------------11 mv
0.503----------------0.495----------------18 mv
0.210----------------0.189----------------21 mv
0.080----------------0.001----------------79 mv
0.070 -0.001--------0.000----------------not detected

how can we sense the correct value, because my application has millivolt sensitivity ?
how to configure so that adc will be able to reading even below 70 mv also ?

Regards,
Raady.


Code:
#define OPV 5.017
#define samples 1024
#define adc12bit 4096
#define mf (OPV/samples/adc12bit) // multiplying factor


void int_adc(void)
{
    ....
    ....
   ADPCFG = 0x7FFF; // Selecting inputs AN15
   ADCSSL = 0x8000; // Scan Select AN15.
   IEC0bits.ADIE = 1; // ADC interrupt is enabled.
   ADCON1bits.ADON = 1; // Turn on ADC Module.
}

void __attribute__((__interrupt__,no_auto_psv)) _ADCInterrupt(void)
{
  adc_temp_R += ADCBUF2;
  i++;
  if(i > samples)
  {
   adc_Voltage = (float)adc_temp_R * mf;
   adc_temp_R = 0;
   i = 0;
  }
 } 
       Flag.adc = 0;
}

/* ADC Timer Interrupt Handler */
void __attribute__((__interrupt__,auto_psv)) _T3Interrupt(void)
{
   if(Flag.adc == 0 )
   {
      Flag.adc=1;
      IFS0bits.ADIF = 0;
   }
   IFS0bits.T3IF = 0; //Clear Timer3 interrupt flag
}
 
Last edited:

Several things:
1) The ADC is a 12-bit device which, assuming your reference voltage is 5volts would IDEALLY give you 1.2mV resolution. If you're expecting "millivolt sensitivity" this won't work
2) Even though the ADC is 12-bits, it's Effective-Number-Of-Bits (ENOB) is about 11 bits, which means the absolute BEST resolution you can expect is about 2.4 mV.

There are many other factors you should consider. How much noise is getting into your analog path? How are you driving the ADC? What is your voltage reference? From your measurements above, it looks like you have a gain error, since the error voltage changes over the input range. (if you had an offset error, you'd see the same difference over the whole range)

Without seeing a schematic, I would first suspect the problem has something to do with how you are driving the input to the ADC.
 
Hi,

use a second adc channel. Amplify your input signal with a gain of 10..50. I´d use 32 if possible then calculations are simple.
Mind to limit the opamp output voltage to the max ADC input voltage.

So if reading of first ADC is below 20 LSB then switch to second channel.
If reading of second channel is beyond 700 switch to first ADC channel.

******

Some ADCs or ucontrollers have built in PGAs. If so then use it.

***

Or you can use external ADC,

*****

According to your ADC readings it seems to me that the PIC has much gnd current (driving LEDs?). This may cause ground bounce.
Maybe you can use differential measurement (between two ADC inputs) to ged rid of the ground offset. But this may not increase resolution.
Or you can switch off as much as possible port pin loads for the short time of sampling.

To increase resolution you may average a lot of readings. But mind that this does not increase precision, as long as you don´t use external dither...

Klaus
 

Without seeing a schematic, I would first suspect the problem has something to do with how you are driving the input to the ADC.

There are many other factors you should consider. How much noise is getting into your analog path? How are you driving the ADC? What is your voltage reference? From your measurements above, it looks like you have a gain error, since the error voltage changes over the input range. (if you had an offset error, you'd see the same difference over the whole range)

The analog pin is directly connected to the ADC pin of the uC, as the voltage never go beyond 4.400 V.
operating voltage on fluke 5.017,
if the voltage on the analog pin is 4.404 and is the same at uC input as well, but there is a 1 mV variation for the lower voltage(mv).
so i can say there are not huge loses.

Several things:
1) The ADC is a 12-bit device which, assuming your reference voltage is 5volts would IDEALLY give you 1.2mV resolution. If you're expecting "millivolt sensitivity" this won't work
2) Even though the ADC is 12-bits, it's Effective-Number-Of-Bits (ENOB) is about 11 bits, which means the absolute BEST resolution you can expect is about 2.4 mV.

the best resolution is 2.4 mv as you said but it should be able to detect the range values below 70 mv then (up to 5mv and above)
when the voltage is 70mv or below the adc value is shown 0.0000, where in i expect to show atleast with some error.
will there be any other method for detect milli volt ranges as the currently used adc calculation is fine for voltges more than 3.1v( +- 2mv)

- - - Updated - - -

I´d use 32 if possible then calculations are simple.
my uC has no 32 bit adc, 10 bit and 12 bit only.
So if reading of first ADC is below 20 LSB then switch to second channel.
If reading of second channel is beyond 700 switch to first ADC channel.
do you mean configuring two adc channels to measure 700 mv above and below ?
According to your ADC readings it seems to me that the PIC has much gnd current (driving LEDs?). This may cause ground bounce.
yes there are 5 leds which will be driven, and for voltage are dropping by 300 mv when those are on , so i making my adc reading when they are off only and once i read the adc i switch on them back.

- - - Updated - - -

those leds are the indication for the parameter i am measuring, should i compl;etely avoid the circuit ??
 

You still haven't told us WHAT is driving the input of the ADC. It's not just "The analog pin". You've got SOMETHING connected to that pin (hopefully), and if it's not low impedance, you are going to have problems. The ADC has a capacitor on its input which needs to be charged, and the time it takes to charge is going to be affected by the source impedance, and thus will affect accuracy. You should drive the input with an opamp, or make sure you are giving the ADC enough time to charge its input cap before it does a conversion. But I would definitely suggest an opamp.
 

I'm missing a declaration of adc_temp_R. Is it long (int32)?

The observed behaviour could be explained by a respective high noise level (several 100 mVpp) superimposed to the DC input voltage. It would produce a bias in averaging operation as soon as some samples exceed 0 V in negative direction. Looking at the individual ADC samples can clarify the doubt.
 

What do you use as reference signals to the ADC?

If the -VRef is not 0V or is noisy, you will have problems in the lower level region.
 

Hi,

Amplify your input signal with a gain of 10..50. I´d use 32 if...

gain of 32 is simple to calculte, because it is shifting 5 bits right (or left)


So if reading of first ADC is below 20 LSB then switch to second channel.
If reading of second channel is beyond 700 switch to first ADC channel.

this is for a 10 bit ADC, (i calculate the following with 10 bit and VRef = 5V)

with gain = 1 you have a range of 5V

with Gain 32 then range of channel2 = VRef/32 = 156 mV. (but you can not use the full range because of voltage limiter. ) Maybe you can use it up to 100 or 120 mV
Resolution here is 156mv/1024 = 153uV.

With your given adc readings there is an offset voltage and as barry suggested a gain problem.
Check what the ADC readings are with a fixed voltage divider (1 / 20 or so) and a 1uF ceramic cap from ADCinput to GND.

***
those leds are the indication for the parameter i am measuring, should i compl;etely avoid the circuit ??

If anode of LED is fixed to VCC and the ucontroller drives the low side, then the LED current must go through the uControllers GND pins. This will cause a voltage drop - called ground bounce. This gives offset errors in ADC reading.

Especially with your configuration you can use the LEDs with cathode externally connected to GND and the uController drives the high side. Then no LED current flows through tne ucontroller GND pins.
For sure the same current now flows trhough the VCC pins. but the ADC refers to GND and not to VCC so it gives no error.

With additional BJT you could drive the LEDs externally, so the LED current is´t driven by the ucontroller.

But switching OFF during sampling is also good.

Klaus
 

If you have the time and the facilities, it would be helpful to send your ADC readings directly to a DAC output.
Drive the ADC input-circuit ( where, I agree, the problem most likely lies) with various analog signals and compare the two.

This has helped me more than once.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top