how to calibrate non-linear ADC reading?

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys

So I want to improve my non-linear 10bit ADC reading on avr, I am thinking this:

uint16_t ideal;
uint16_t actual;
uint8_t offset;

while(until all done)
{
  ideal = ref(x);
  x++;
  actual = adc_reading();
  offset = ideal - actual;
  //to-do: store actual to eeprom
  //to-do: store offset to eeprom
}

then look for the corresponding offset from the eeprom

if (adc_reading() == actual_in_eeprom())
  adc_actual = adc_reading() + offset_in_eeprom;

does it work? or do I need a better way?

and another question is, what counts as one write/ease in eeprom? is it every time I write a byte data into eeprom counts as one write cycle?

Thanks

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I want to improve my non-linear 10bit ADC reading
Why do you think that the ADC is non linear?

Is the source FEEDING the ADC non linear?

Quote:
is it every time I write a byte data into eeprom counts as one write cycle?
Yes.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
Why do you think that the ADC is non linear?

Is the source FEEDING the ADC non linear?[

it's connected to a variable load, and the supply voltage is variable as well

it shows on my meter, say:

DDM reading: 1   2   3   4   5   6   7   8   9   (v)
ADC reading: 0.9 2.1 3.2 3.9 4.9 6.1 7.1 7.9 8.9 (v)

something like that.

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
ADC reading: 0.9...
ADC reading can only be 0-1023, so how are you calculating the voltages? Are the readings continously changing up and down around the correct value?

And what makes you think that your DMM is 100% correct? :)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The formular for my calculation is:

Vout = (Vref / 1024) * adc_get_reading();

The reading is pretty stable, if the load and the supply is not changing, but if I get it right, you are suggesting that non linear ADC reading is very rare/not likely, so I will re check it and look for other possible cause

Thanks for your reply John, very appreciate it :)

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bug13avr wrote:

Vout = (Vref / 1024) * adc_get_reading();

I suppose you are using float Vref (e.g 5.0) or this would result in 0.
You are also using a voltage divider to be able to work with a range >5.
Is the Vref accurately set in the equation (for example it may be 4.95 and not 5v)?
Have you tuned the voltage divider to give an accurate result?
For example you may have 1K+1K resistors and expect to get half of the input voltage in output but in reality because of the resistor tolerance you may have 990 ohm +1020 ohmm which give a different result.

What exactly does this divider involve?
resitors (how high value) , an opamp ?

Is your Vref from filtered?

If speed is not a problem you can try to get multiple samples, add them and divide the result by the number of samples to get a mean.

Anther solution is oversampling
www.atmel.com/images/doc8003.pdf

By the way, I would probably use /1023

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is my experience. I setup a mega88 to read a milivolt calibrator in a temperature chamber. I oversampled by 64 and data logged via a serial port. The results were excellent and well within data sheet specifications.

There are inherent granularity issues at low ADC counts, that is math.

For fitting curves, multiple linear regression is sometimes used to translate data. In a linear regression, similar to your method, there is an offset and a gain term. Perhaps Google that.

It all starts with a mental vision.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Based on AVR experience and the details available:

If indeed those are the results when you read the voltages RIGHT AT THE AVR PIN, and the DMM isn't erratic itself (how have you checked this?), and reference and supply voltages and ground are steady (how have you checked this?), and there isn't excessive ripple on signal, supply, reference, ground (how have you checked this?) then:

-- I'd ensure that the signal had enough drive. If using e.g. 100k ohm voltage divider resistors...
-- I'd make sure that my ADC clock rate was proper
-- I'd double-convert high impedance channel(s), and use the second reading
-- I'd do a number of conversions in quick succession and use the average (addresses ripple)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, yeah--

Perhaps try to record to e.g. three significant digits on the meter. Also record your calculation to three digits (to see if it is a rounding or loss-of-precision situation). Also, perhaps record the ADC counts as well, to see if it is an ADC situation or an arithmetic/rounding situation.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alexan_e wrote:
bug13avr wrote:

Have you tuned the voltage divider to give an accurate result?

What exactly does this divider involve?
resitors (how high value) , an opamp ?

Is your Vref from filtered?

If speed is not a problem you can try to get multiple samples, add them and divide the result by the number of samples to get a mean.

Anther solution is oversampling
www.atmel.com/images/doc8003.pdf

Alex

the resistor divider I am using is 2 10K in series and 2 10K in parallel,that gives me 1/5 of the reading. those resistor are 0.1%, is that too low?

the voltage reference I am using is 2.048V precision reference, not filtered, but it was placed right next to the VREF pin.

I will definitely try out the oversampling technique, never heard of it before, thanks for the info :)

Thanks a lot

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I will definitely try out the oversampling technique,

What about the other half-dozen questions I raised?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you divider resistance is very close to the suggested input residtance 10k or less, consider using a small capacitor across the ADC input to present a low impedance to the input.

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

KitCarlson wrote:
Here is my experience. I setup a mega88 to read a milivolt calibrator in a temperature chamber. I oversampled by 64 and data logged via a serial port. The results were excellent and well within data sheet specifications.

There are inherent granularity issues at low ADC counts, that is math.

For fitting curves, multiple linear regression is sometimes used to translate data. In a linear regression, similar to your method, there is an offset and a gain term. Perhaps Google that.

Hi KitCarlson, thanks for the info, I will google the terms you mentions and look into it, thanks

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Based on AVR experience and the details available:

If indeed those are the results when you read the voltages RIGHT AT THE AVR PIN, and the DMM isn't erratic itself (how have you checked this?), and reference and supply voltages and ground are steady (how have you checked this?), and there isn't excessive ripple on signal, supply, reference, ground (how have you checked this?) then:

-- I'd ensure that the signal had enough drive. If using e.g. 100k ohm voltage divider resistors...
-- I'd make sure that my ADC clock rate was proper
-- I'd double-convert high impedance channel(s), and use the second reading
-- I'd do a number of conversions in quick succession and use the average (addresses ripple)

-- I don't have the mean to check my DDM, the most reliable voltage reference is the 2.048v I am using now, and it reads 2.040V.
-- the ADC clokc rate is about 62KHz
-- will try the double-convert high impedance if applicable, will check the datasheet first, as another channel is connected to a current sense chip.
-- will do average method.

Zhuhua Wu - Electronic Engineering Student

Last Edited: Sun. Dec 9, 2012 - 08:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

I will definitely try out the oversampling technique,

What about the other half-dozen questions I raised?

your respond time is faster than I expected :)

Zhuhua Wu - Electronic Engineering Student

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the over sampling technique works pretty good, I am happy with that.

And thanks all of your advice how to get a better ADC reading, I will implement those in my future projects.

Thanks a lot, really appreciated.

Zhuhua Wu - Electronic Engineering Student