Author Topic: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?  (Read 1907 times)

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18219
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« on: April 25, 2025, 07:38:58 am »
I'm struggling to wrap my head around this. I expect it applies to any ADC with result accumulation.

Do I take it that given the ADC is 12 bit and that I can accumulate up to 16 of those results into the 16 bit result register before overflowing is the total range 16 * 4095 = 65520 or 16 * 4096 - 1 = 65535 ?

using 4095 sounds right to me in terms or basic math but some in my head says that as this has taken me out of round binary numbers it can't be right.
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 15541
  • Country: de
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #1 on: April 25, 2025, 08:25:09 am »
The largest number possible with 12 bits is 4095 = 2^12 - 1. So the sum of 16 such values can not be larger then 16*4095.
 
The following users thanked this post: thm_w

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 5122
  • Country: nl
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #2 on: April 25, 2025, 09:08:10 am »
Another way to look at it is in hexadecimal.

Max number in 12 bit is 0x0FFF. Shift this 4 bits to the left, which is the same as multiplying by 16, you get 0xFFF0, which is 65520.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18219
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #3 on: April 28, 2025, 01:51:58 pm »
Yes of course, thank you for proving I am semi sane
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9771
  • Country: fi
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #4 on: April 28, 2025, 02:21:10 pm »
Range is 2^n, but largest possible number is 2^n - 1, because smallest possible number is 0.

Therefore, if you do stuff like divide by range (to get percentage), you need to divide by 2^n, not 2^n -1.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 892
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #5 on: April 28, 2025, 02:51:27 pm »
Quote
Therefore, if you do stuff like divide by range (to get percentage), you need to divide by 2^n, not 2^n -1.
How is this handled in practice? My adc gives me a value of 4095, which I would consider 100%, but now when I convert to percent- 4095*100/4096 I get 99%. Using 4095 will get me the 100% and make little difference for anything in between, but of course my underpowered mcu would rather divide by 4096. What is normally done with this type of thing?
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3468
  • Country: gb
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #6 on: April 28, 2025, 03:38:29 pm »
It's easy to handle because the ADC will hit full scale (4095 in this case) with an input 1 LSB below Vref* i.e. dividing by 4096 gives the correct result.  This is the same with most DACs, the maximum code doesn't give you Vref on the output, but 1 LSB below Vref.

*Ideally an ADC transitions at the 1/2 LSB point, so it should hot full scale 1.5 LSBs below Vref.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16365
  • Country: fr
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #7 on: April 28, 2025, 03:53:16 pm »
Quote
Therefore, if you do stuff like divide by range (to get percentage), you need to divide by 2^n, not 2^n -1.
How is this handled in practice? My adc gives me a value of 4095, which I would consider 100%, but now when I convert to percent- 4095*100/4096 I get 99%. Using 4095 will get me the 100% and make little difference for anything in between, but of course my underpowered mcu would rather divide by 4096. What is normally done with this type of thing?

I'm assuming you meant "99%" here as a figure of speech. For 12-bit samples, it's actually ~99.98%.
So yes, this is 1 LSB below Vref. Something to know, although for it to begin to even matter, you'd need to consider ADCs with better than 1 LSB accuracy, which is not something that usual.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18219
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #8 on: April 28, 2025, 05:03:39 pm »
err, if I were treating my result as a percentage or range it would be 4095 as the top, for the same reason that my top value is 4095*16 when oversampling.

There are 4096 Values a 0-100% range has 101 values, we don't use 101 in calculations, so why use 4096 instead of 4095?
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9771
  • Country: fi
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #9 on: April 28, 2025, 05:37:13 pm »
There are 4096 Values a 0-100% range has 101 values, we don't use 101 in calculations, so why use 4096 instead of 4095?

Because there isn't. If you look how a typical SAR ADC operates, measurement range does not include a separate code for Vcc.

The small error is hidden in noise, gain errors, inaccuracies and nonlinearities, but using wrong multiplier adds even more error, so don't do that.

Assume imaginary highly accurate 4-bit SAR ADC in a microcontroller powered from 1.6V supply voltage. Code 0 corresponds to 0 to 0.1V, code 1 to 0.1 to 0.2V, and so on, until code 15 corresponds to 1.5V to 1.6V. Therefore, when you convert to percentages or voltages, you divide by 16:
Code 1: 1/16 * 1.6V = 0.1V
Code 15: 15/16 * 1.6V =  1.5V
In both cases that would be the start of the bin.

If you divide by 15, you will get the ends wrong by different amount:
Code 1: 1/15 * 1.6V = 0.10666V
Code 15: 15/15 * 1.6V = 1.6000V

Now if you redefine the meaning to be the "upper side of the bin", then code 15 appears "correct", but code 1 is then incorrect to that definition. You added gain error.

You get bonus points of using the correct divider in that it can be implemented as a simple bit shift way more efficiently than a division, which most simple microcontollers lack.
« Last Edit: April 28, 2025, 05:38:56 pm by Siwastaja »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16365
  • Country: fr
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #10 on: April 28, 2025, 05:49:44 pm »
Yes, by defining 1/(2^N - 1) as the LSB, you're getting it wrong and will introduce a gain error.

The fact that the full scale of an ADC doesn't fully reach Vref is something that tickles many people for no good reason apart from a misunderstanding of how most ADCs work. Then they divide by (2^N - 1), which is not just wrong in terms of gain, but also expensive (instead of dividing by 2^N, which is cheap and correct), and they feel better. Maybe. And since as we said, it's often drown in noise and various errors, they don't even notice.

When you're most likely to really notice (unless of course you design precision equipment) is when using a very low-resolution ADC, like 4 bits. Then that becomes very obvious. Note that some of these, often made for high-speed stuff, may not have the typical 1/2^N scale and may not even be linear (specialty stuff). So, as always, read the F.. uh, the datasheet. :-+
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9771
  • Country: fi
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #11 on: April 28, 2025, 06:02:32 pm »
The thinking error there is fundamental, not limited to ADCs by any means. Discretized data represented as single numbers is confusing. Think about 0-100% Simon mentioned. We think about it as a continuous range with infinite resolution, which is why we think 0% is the minimum, "nothing", and 100% is the maximum, "all of it".

Yet, if you discretize that to 1% wide bins, then the first bin is 0% to 1% and the last bin must be 99% to 100% and so there are 100 of them, not 101. Now what happens if you name the bins with a single number? Do you use the beginning of the bin as the name? Then your 100 bins are labelled from 0% to 99%. Or maybe you use the end of the bin as label? Then you have 100 bins labelled from 1% to 100%. But you never ever will have 0% to 100%, unless you suddenly change the rounding rules (how the bin is labelled) somewhere in the middle of the range. Which is exactly the gain error.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18219
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #12 on: April 28, 2025, 07:44:37 pm »
Yes I suppose to think of the numbers as representing a ranges of Vref/2^n is more realistic. So if any value is so +/-0.5 bits does this mean that 0 is 0 +/-0.5 and that the for 12 bits 4095 = Vref / 4096 * 4095 +/- 0.5 bit
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 892
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #13 on: April 28, 2025, 10:26:00 pm »
Quote
I'm assuming you meant "99%" here as a figure of speech. For 12-bit samples, it's actually ~99.98%.
You are truncating the value to two decimal places (and also indicating this is not the actual value with ~), and I'm truncating to an integer, neither one is the actual value but we both made a choice about how much resolution we wanted. A percentage is not a scale designed for maximum precision, so a decimal place or two is probably the most precision one will see when viewing some information given as a percentage.

I understand the adc value of 4095 is not technically 100% of vref, and there is no adc value that will represent it, but as a practical matter where this adc value is presented to the outside as a percentage (of something) it would seem to me a consumer of this percentage information would like to see when max is reached so 0-100% and not 0-99%. Indicating 99% (or 99.9755...) seems to imply to the viewer the max has not been reached although it has (and maybe exceeded). So my question was about how to deal with getting to that 100% which can never be reached if following the /N^2 'rule'. It appears simply using /4095 is the answer, which will get the 100% and make no difference to any introduced error which was already lost in the conversion to a lower resolution.


 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16365
  • Country: fr
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #14 on: April 28, 2025, 11:02:17 pm »
Quote
I'm assuming you meant "99%" here as a figure of speech. For 12-bit samples, it's actually ~99.98%.
You are truncating the value to two decimal places (and also indicating this is not the actual value with ~), and I'm truncating to an integer,

No, I actually rounded it. You truncated it. If you had rounded it like I did, you would have found 100%.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 892
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #15 on: April 29, 2025, 12:13:29 am »
Quote
No, I actually rounded it. You truncated it. If you had rounded it like I did, you would have found 100%.
True.

So a better alternative to /4095 would be to use extra precision to get a rounding value, and apply it?
res=4095*1000/4096; //res=999
if( (res % 10) >= 5 ) res += 10; //res= 1009
res /= 10; //res = 100

I realize in this case discarding so much precision means it makes little difference which method is used, but maybe it becomes more important when there is a conversion where less precision is lost. A method that always works would be preferable to one that happens to work ok in a specific instance.

I have an LDR in use at the moment where I was using the adc value to show a display output value as 0-100%, and of course was using /4096 which prevented me from seeing 100%.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3468
  • Country: gb
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #16 on: April 29, 2025, 09:16:24 am »
Yes I suppose to think of the numbers as representing a ranges of Vref/2^n is more realistic. So if any value is so +/-0.5 bits does this mean that 0 is 0 +/-0.5 and that the for 12 bits 4095 = Vref / 4096 * 4095 +/- 0.5 bit

The transition between codes occurs with the input 0.5 LSB below/above a nominal code value.  Zero and full scale are special cases since there is no code below zero and no code above full scale to transition to or from. This is assuming single ended unipolar ADC, obviously you can go below zero with bipolar or differential input, but the reduced range still applies to the full scale codes.

 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4437
  • Country: Earth
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #17 on: May 03, 2025, 01:52:21 am »
Do I take it that given the ADC is 12 bit and that I can accumulate up to 16 of those results into the 16 bit result register before overflowing is the total range 16 * 4095 = 65520 or 16 * 4096 - 1 = 65535 ?

Yes, you can.

A 12-bit ADC produces values from 0 to 4095, which is a total of 4096 distinct values. So:

Maximum sum of 16 samples = 16 * 4095 = 65520
Maximum possible value in 16 bits = 2^16 - 1 = 65535


This means you can safely accumulate up to 16 full-scale 12-bit samples in a 16-bit unsigned register without overflow.

using 4095 sounds right to me in terms or basic math but some in my head says that as this has taken me out of round binary numbers it can't be right.

The confusion between 4095 and 4096 arises because:
- 4095 is the maximum value of a 12-bit ADC.
- 4096 is the number of possible values, from 0 to 4095.

When calculating LSB weight, the full scale is divided by 4096, not 4095, because 0 is a valid value.


Also, note that if you're summing signed 12-bit values (from a differential ADC or after offset correction), keep in mind that the negative range goes from -2048 to +2047. This asymmetry means the maximum absolute value is smaller on the positive side, and special care must be taken when scaling or accumulating such values to avoid overflow or bias. So, with signed integers things is a little bit more complicated.
« Last Edit: May 03, 2025, 02:28:40 am by radiolistener »
 
The following users thanked this post: Siwastaja

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18219
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #18 on: May 04, 2025, 06:51:28 am »
err yea, now you come to mention it, I am using +/- output. But an error of 1 bit in 4095/6 or 65535/6 is really neither here nor there as my numbers are actually being used as -100/+100.

Now I'm not sure about the 4096 thing. I have a potentiometer on the 3.3V supply that acts as the reference for one of the ADC's, the oversampled result on full travel to the 3.3V side is exactly 65520 rather than 65535.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16365
  • Country: fr
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #19 on: May 04, 2025, 04:27:25 pm »
err yea, now you come to mention it, I am using +/- output. But an error of 1 bit in 4095/6 or 65535/6 is really neither here nor there as my numbers are actually being used as -100/+100.

Now I'm not sure about the 4096 thing. I have a potentiometer on the 3.3V supply that acts as the reference for one of the ADC's, the oversampled result on full travel to the 3.3V side is exactly 65520 rather than 65535.

That's mixing a different set of problems. Potentiometers rarely fully reach a state of "zero" resistance at each end of their travel.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 892
Re: [SAMC] ADC 12 bit result accumulation of 4095 or 4096?
« Reply #20 on: May 04, 2025, 10:59:31 pm »
Quote
the oversampled result on full travel to the 3.3V side is exactly 65520 rather than 65535
The hardware is doing what you would otherwise do in software (but in software you would not place a 16bit restriction on the accumulated value)-

uint32_t adcAcc = 0; for( unsigned i = 0; i<16; i++ ) adcAcc += adcRead();

which leaves you with a max accumulated value of 16*4095 which is 65520. The hardware uses the 16bit RESULT register for its accumulation so has to deal with preventing overflow while accumulating values so it will do shifting as needed which the datasheet describes (and for 16 samples, no shifting required).

Your +/- output is a scaling issue separate from your use of a single ended adc input (according to your accumulated value you must be doing, otherwise that unsigned 65520 would be a signed -16).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf