Jump to content
43oh

ADC10 TestCode


Recommended Posts

While searching an ADC samplecode for the g2231 I found one that made use of the floating point lib to get an accurate reading of the ADC return value. As the g2231 is a 2k chip that is a silly thing to do.

 

The goal for the code was to get an accuracy that is similar to a 4 digit DMM. Ok, let's think about this. When using the internal reference (2.5V) the resolution we can get is 2.5V / 1024 = 0.002441 Volt. We can see that the last digit will jump because 10 BIT is not enough. Ok, let's try the 2nd reference with 1.5V / 1024 = 0.001468. Not to bad but still not good enough. Also I'de like to have a range from 0-2.5 V.

 

By testing the code I mentioned before a constant had been used to make the reading look accurate, however, as there was only one constant in use to correct the ADC the result was quite poor compared to a DMM. As we all know in real life there is no perfect ADC and if we only have the linear errors in mind we will find at least an offset and a gain error.

 

So the problem to solve looked like:

- avoid floating point

- get the accuracy of floating point

- correct the ADC errors

- get more then 10 BIT out of the g2231

 

The following code will do what we need and the codesize is only 576 Byte. I used a well know oversampling technique to get 12 BIT out of the ADC and calculate all corrections by fixed point arithmetic. Instead of calculating on a base by 10 I used base 2 instead as this will allow us to get the result by a simple shift operation. Once the code was working I could still see some jumps in the last digit caused by a ripple of arround 4 mVolt caused by the poor USB powersource of the Launchpad. So I have added also a low pass filter in Software to get rid of the remaining noise.

 

The ADC result will be displayed @ the MSP430 USB Application COM Port. I have used the Soft. Uart code by NJC but slightly modified it to have a putChar function.

 

To adjust your ADC and get the RawValues (AdcRawHigh, AdcRawLow) for the calculation of the constants use

"return (AvgSum >> 8);" instead of the original return statement "return AdcVal;" and ignore the decimal point. In function "AdcValOut" use "while (m != 4)" to display all digits of the RawValues.

So here we are, let me share this code snippet with you. Please try out the code and let me know your findings.

 

Have fun,

 

Bernd

g2231AdcTestCode.c

Link to post
Share on other sites

Hi Rob,

 

you didn't check the given code, I do not make use of floating point. I found an example that did it but of course it make no sense at all. I do all corrections by fixed point arithmetic and simple shift operations.

 

Bernd

Link to post
Share on other sites

Rob,

 

I followed the given link but to be honest, I can not see any error correction at all.

 

Second option is internal Vref (1.5V or 2.5V) which is much better choice but the result has to be also calculated.

 

Of course and my example shows how to do it in a very effective way by also getting a 12 BIT result + Filter.

Link to post
Share on other sites

Don't get me wrong, I think you did a great job with your code, I am just suggesting another way of dealing with the calculation problem and no, I do not have any error correction or averaging in my example.

Personally, I am not a big fan of oversampling, I just think getting 12bit resolution from a 10bit ADC is a little bit (or 2bit) silly :)

Link to post
Share on other sites

Hi Rob,

I just think getting 12bit resolution from a 10bit ADC is a little bit (or 2bit) silly

I don't think so as I already explained before the resolution we can get is 2.5V / 1024 = 0.002441 Volt = 2.44 mVolt. For a 4 digit DMM you need a resolution of 1 mVolt so we need oversampling here.

 

Lets have a look at your explanation...

(2500mV/1024) * ADC10ME It's actually 2500/1023, but for simplicity let's use 1024...

2500/1023 is wrong even if you find such an example calculation in some data sheets. You have to count the 0 as well.

Example:

 

0000000000 is your 1st return code from a 10 BIT ADC

0000000001

0000...........

1111111111 is your last

 

so from 0 - 1023 = 1024 and your calculation is correct :-) The maximum return value is 1023 but the steps that a 10 BIT ADC can do is 1024.

 

Cheers,

 

Bernd

Link to post
Share on other sites
Hi Rob,

I just think getting 12bit resolution from a 10bit ADC is a little bit (or 2bit) silly

I don't think so as I already explained before the resolution we can get is 2.5V / 1024 = 0.002441 Volt = 2.44 mVolt. For a 4 digit DMM you need a resolution of 1 mVolt so we need oversampling here.

Just because you need 1mV resolution, doesn't mean you can get it. Oversampling works by assumption and it works best for things like audio or video signals, where there's a constant change, and not so well for measuring, especially when DC is involved.

 

For example, you have a 4bit ADC, from 0V-15V. You oversample it to get 6bit resolution, or 0.25V.

When the voltage falls from 1V down to 0V in let's say sampletime * 4, you'll get the following readings: 0.75V, 0.5V, 0.25V, 0V.

Now, when your voltage falls from 1V down to 0.6V, then back up to 1V, and back to 0.6V, your reading will be steady 1V.

Then when it falls to 0.4V, your readings will be... 0.75V, 0.5V, 0.25V, 0V and will stay at 0V.

So it looks like accuracy is there, but it's false.

When I get some time, I will support it with drawings.

 

Lets have a look at your explanation...

(2500mV/1024) * ADC10ME It's actually 2500/1023, but for simplicity let's use 1024...

2500/1023 is wrong even if you find such an example calculation in some data sheets. You have to count the 0 as well.

Example:

 

0000000000 is your 1st return code from a 10 BIT ADC

0000000001

0000...........

1111111111 is your last

 

so from 0 - 1023 = 1024 and your calculation is correct :-) The maximum return value is 1023 but the steps that a 10 BIT ADC can do is 1024.

Cheers,

Bernd

My calculations are correct, but not with 1024, 1023 should be used.

Here's 2bit example, reference voltage is 4V.

 

Resolution according calculations you are suggesting: 4V/4(2bit) = 1V, so

00=0V, 01=1V, 10=2V, 11=3V, looks like 4V will be displayed as 3V.

 

According to calculations that should be used, 4V/(4(2bit)-1)=1.33V, and

00=0V, 01=1.33V, 10=2.66, 11=4V, full range from 0v-4V.

 

Here's another example, 3bit, 8V ref.

000-001-010-011-100-101-110-111

bad, 8V/8(3bit) 0V-1V-2V-3V-4V-5V-6V-7V

good, 8V/(8(3bit)-1) 0V-1.14V-2.29V-3.43V-4.57V-5.71V-6.86V-8V

 

As you can see, you have to always subtract one when calculating steps, otherwise you will get the number of possible values, not the step.

 

And I think I will stick to datasheets.

Link to post
Share on other sites

Mh, intersting discussion :-)

 

Ok, let's take a 2 BIT ADC and let's assume a range of 0-4 V.

 

The result we get:

 

ADC Value

0V +

|

00 |

|

1V +

|

01 |

|

2V +

|

10 |

|

3V +

|

11 |

|

4V +

 

So the ADC will divide the range from 0-4 V in 4 portions, each has a range of 1V. The key point is how many different numbers can be generated by 2 BIT's and that's exactly 4 because 0 is a number as well.

 

Keep in mind that an ADC return value does not stand for a sepcific Voltage, it stands for a range of Volt. If the return value of the ADC is 10 (decimal = 2) then the Voltage is somewhere in the range between 2V - 3V. Where exactly ? we dont know.

 

Let's think about a 10 BIT ADC. This time you will get 4/1024 portions. The range of each portion will become smaller but this does not mean that we have less then 1024. However, the last ADC Value will be 1024-1. So think about it.

 

In respect to the oversampling example you gave I would agree but if you use a 10 BIT ADC and calculate the noise you need to make that oversampling then I can tell you by experience that getting 2 BIT's more is very easy. Simply test the code on your Launchpad and put a DMM beside it.

 

If you want to have more details, please have a look.

 

http://www.atmel.com/dyn/resources/prod ... oc8003.pdf

 

Bernd

Link to post
Share on other sites

Let's start off with oversampling. I will continue to insist that it is good but only for a specific applications. Oversampling is based on assumption that if first measurement was A and the second measurement was B, the value must be exactly (A+B)/2 or for two bit, (A+B+C+D)/4. You cannot get detail from nothing. It's like in those movies where they "enhance" a blurry photo and are able to reproduce the entire page of text from 4x4 pixel area.

 

So the ranges are 0-1, 1-2, 2-3, 3-4, that's 4 ranges that you can have with 4bit.

Now, how do you display 0-1, 0 or 1? 1-2, 1 or 2? 2-3, 2 or 3? 3-4, 3 or 4?

If you decide to go lower, you will have 0-3, if higher then 1-4.

You would need 5 values to display a full range 0-4.

0.0-0.4, 0.5-1.4, 1.5-2.4, 2.5-3.4, 3.5-4.0

 

If you divide ref by 3, you can cover the entire range with 4 values

0-0.6, 0.7-2.0, 2.1-3.4, 3.5-4.0

Link to post
Share on other sites

The lowest and highest codes returned by the ADC are 1/2 LSB wide as Rob has explained. This is necessary to ensure that those codes represent VrefLow and VrefHigh +/- 1/2 LSB.

 

Averaging will give you an average reading - nothing more. It does not provide more ENOB or "filter out the noise."

 

One huge flaw in the Atmel app note is the lack of attention to quantization error. You can't just filter it out.

 

If you want 10 ENOB use a SAR ADC with 12 bits. The ENOB will always be less than the physical bit count.

 

Using a SAR ADC for a DMM is a poor choice. It should be dual slope or quad slope. A good sigma delta would be OK, but not great.

post-2341-135135501627_thumb.png

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...