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.

ADC value to millivolt no floats

Status
Not open for further replies.

yankee96

Newbie
Newbie level 1
Joined
Sep 29, 2021
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
0
Activity points
11
Hey so I have a 5.0V signal let's say and I get an ADC value of 65535 so then I get 5V and the ADC value of 0 is 0V. How do I write in C to convert my ADC value back to millivolts using a 16-bit ADC without using floats or division?
 

Hi,

mV = ADCValue × 5000 / 65536
Or
mV = (ADCValue × 5000) >> 16

Klaus

Added:
But using a 16bit ADC at VCC as reference makes not much sense.
Vcc is neither accureate nor stable.

Vcc may drift with input voltage, load current, time, temperature, age...
So if your measurement shows 4,123mV it may show 4,034 next time.
Not much of an improvement against an 8 bit ADC.

Klaus
 
Last edited:

Put your scope on infinite persistence and look at Vdd rail. Typically you will see
100+mV or more of noise, and if thats Vref thats 100 mV in 5 volts (if using 5V
as Vref) or roughly 5 bits in accuracy.

Integer math -





Regards, Dana.
 

Hello!

What is said above about noise is certainly true, but we don't know how he measures. Maybe he uses a 2.5V
reference which is internal to some chips, and a divider bridge (by 2) in which case what he says is right: 65535
can effectively correspond to 5V.
By the way, another way of calculating, without shifting:
Since a 32 bit value is used internally when calculating the adcval * 5000, he can also do like this:

Code:
uint16 AdcToMV(uint16 adcval) {
    uint16 retval;
    uint32 accu = adcval;
    uint16 * vals = (uint16 *)(&accu);  // At this point, vals[0] = adcval, assuming little endian
    accu *= 5000;
    retval = vals[1];
    return retval;
};

NB: the redundant variables are on purpose, in order to test because the debugger might not give
easy access to vals which is only a pointer.

Dora.
 

For the common, that is simple, analog to digital converters in use today the values reported are a ratio from zero to the maximum integer count the converter is designed to provide. For this topic that is 16-bits, so a maximum of 65535.

To represent this ADC value in terms of voltage applied to the ADC input is only possible when the reverence voltage the ADC uses is known.

In the data sheet that describes the ADC this parameter is usually called VREF.

So to convert ADC counts to VOLTS I use this formula:
VOLTS = (ADC_COUNT * VREF) / (2 ^ ADC_NUMBER_OF_BITS).

Example:

Output to be a 16-bit unsigned integer number of millivolts present at the ADC input.

ADC reference is 5000 millivolts.
ADC resolution is 16 bits.

C:
unsigned short ADC_in_to_millivolts(unsigned short ADC_counts)
{

#define VREF_mV (5000UL)

    unsigned long ADC_temp;

    ADC_temp = ADC_counts;
    ADC_temp = ADC_temp * VREF_mV;
    
    return (unsigned short)(ADC_temp >> 16);
}

There are a lot of long and tedious explanations of how the number you get from the ADC is related to the voltage present on the ADC input at the time of the conversion from the analog domain to the digital domain. This is an issue outside the scope of this reply.
 

A hardware hack to avoid even the multiplication and ">>" is to use a potentiometer to divide input voltage and adjust it to get 5000 as direct adc value when we set input as 5V.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top