Voltage reading formula

MrChips

Joined Oct 2, 2009
34,818
What is your implication? That operations on fixed point binary values are not entirely integer arithmetic?

If so, I emphatically disagree. The fixed point simply implies a shift, which you do explicitly.
Am I misreading you? Are you saying that fixed point arithmetic and integer arithmetic are not the same?
I don't see any difference.
 

joeyd999

Joined Jun 6, 2011
6,303
Am I misreading you? Are you saying that fixed point arithmetic and integer arithmetic are not the same?
I don't see any difference.
I'm as confused by your posts.

Yes, I am saying they are equivalent -- with the exception that fixed-point implies your explicit shift. And if one works the numbers right (so that the fixed-point lands on byte boundaries), no shifts are necessary.
 

MrChips

Joined Oct 2, 2009
34,818
I'm as confused by your posts.

Yes, I am saying they are equivalent -- with the exception that fixed-point implies your explicit shift. And if one works the numbers right (so that the fixed-point lands on byte boundaries), no shifts are necessary.
Yes. I do fixed point arithmetic often when working with temperatures. My values are scaled by a factor of 40.
This gives me one decimal place plus extra 2 guard bits. For example, 50.0°C would be represented by 2000.
 

joeyd999

Joined Jun 6, 2011
6,303
Yes. I do fixed point arithmetic often when working with temperatures. My values are scaled by a factor of 40.
This gives me one decimal place plus extra 2 guard bits. For example, 50.0°C would be represented by 2000.
If it were me, I'd record temperature in milliC, therefore, 50.0C would be 50000 counts.

Same two bytes, but I'd not need to multiply by 25 later to display the value in human terms.

It's also easier on the eyes when using a debugger.

But, each to his own.
 

MrChips

Joined Oct 2, 2009
34,818
If it were me, I'd record temperature in milliC, therefore, 50.0C would be 50000 counts.

Same two bytes, but I'd not need to multiply by 25 later to display the value in human terms.

It's also easier on the eyes when using a debugger.

But, each to his own.
The problem with that is that it does not accommodate negative values using two bytes.
 

joeyd999

Joined Jun 6, 2011
6,303
The problem with that is that it does not accommodate negative values using two bytes.
Of course, the chosen representation must be defined based on range and resolution.

My point is that I attempt to structure my data to require as little manipulation as possible, while still making sense from a debugging POV.

That said, this discussion has likely gone way over OP's head at this point.
 

MrChips

Joined Oct 2, 2009
34,818
What's the min/max range of temperatures you are interested in representing?
16-bit signed integer scaled by 40 can accommodate temperatures from -800 to +800°F which is about -460 to +425°C.
In most cases, -100 to +200°C covers most applications.
 

WBahn

Joined Mar 31, 2012
32,855
16-bit signed integer scaled by 40 can accommodate temperatures from -800 to +800°F which is about -460 to +425°C.
In most cases, -100 to +200°C covers most applications.
There's no value in being able to represent temperatures that are below absolute zero.

If -100°C to +200°C covers most applications, does that mean that you don't have a need to be able to represent temperatures outside that range.
 

MrChips

Joined Oct 2, 2009
34,818
There's no value in being able to represent temperatures that are below absolute zero.

If -100°C to +200°C covers most applications, does that mean that you don't have a need to be able to represent temperatures outside that range.
With 16-bit integers and a scaling factor of 40, values between -800.0 and +800.0 can be represented with one decimal place.
 

WBahn

Joined Mar 31, 2012
32,855
With 16-bit integers and a scaling factor of 40, values between -800.0 and +800.0 can be represented with one decimal place.
I am not asking what you can do with a particular scaling. I am asking what is the range of temperatures that you NEED to be able to represent!
 

MrChips

Joined Oct 2, 2009
34,818
I am not asking what you can do with a particular scaling. I am asking what is the range of temperatures that you NEED to be able to represent!
What does it matter?

The question is what is a viable strategy to represent a parameter with a range from minimum to maximum value with d decimal places using n-bit integers.
 

WBahn

Joined Mar 31, 2012
32,855
What does it matter?

The question is what is a viable strategy to represent a parameter with a range from minimum to maximum value with d decimal places using n-bit integers.
I wanted to see if I could come up with a scaling that would only involve add/sub/shift while providing acceptable range and resolution. But since it is such a closely held secret, never mind.
 

MrChips

Joined Oct 2, 2009
34,818
I wanted to see if I could come up with a scaling that would only involve add/sub/shift while providing acceptable range and resolution. But since it is such a closely held secret, never mind.
I think that the problem was already solved. 16-bit 2’s complement signed integer scaled by a factor of 40 covers the desired temperature range using only add/sub/shift operations on an 8-bit processor. I don’t know the actual temperature range. I would have to look it up.

Thanks for your offer but the product was developed and shipped 20 years ago.
 

Jon Chandler

Joined Jun 12, 2008
1,597
I'd like to point out that over 30 messages have been posted since the TS has made a comment, and you gentlemen are arguing over minutia that is totally off the topic.
 

MrChips

Joined Oct 2, 2009
34,818
In my opinion, I believe that the discussion is still very much relevant.

Hi there, I need some help understanding how to use a microcontroller's ADC to read voltages from a variable DC supply (0-12V) and display them on a screen. I know I need a voltage divider circuit since the microcontroller can only handle up to 5V. With a 10-bit ADC and a reference voltage of 5V, I'm calculating the voltage using:

Voltage = (ADC sample / Total ADC samples) * reference voltage

For instance, at 6V supply, I'm getting a 512 ADC value, which computes to 2.5V. How can I adjust the formula to display the correct voltage value (6V) on the screen? This is a general question, not specific to any microcontroller, display, or compiler
We are trying to demonstrate how such simple conversions can be performed easily using fixed point integer arithmetic.

The formula assumed by the TS is correct.
Voltage = (ADC sample / Total ADC samples) * reference voltage

What it needs is proper implementation. In this example, all one has to do is use the data as calibration data.
6V input gives 512 ADC counts.

Hence,
Voltage = (ADC sample / 512) * 6

If one wants to show the result with one decimal place, use
Voltage = (ADC sample / 512) * 60

We can avoid a costly division by doing right shifts:
Voltage = (ADC sample * 60 ) >> 9

This can be simplified:
Voltage = (ADC sample * 15 * 4 ) >> 9
Voltage = (ADC sample * 15 ) >> 7

With rounding:
Voltage = (ADC sample * 15 + 64) >> 7
 

BobTPH

Joined Jun 5, 2013
11,521
Ada got this right.

Fixed point data types are defined by;

range low .. high delta d

Low, high and d are real numbers.

So, if i want a variable that can represent a temperature range up to 800C I can defind a type as:

type temp is range -273.15 .. 800.0 delta 0.1

And the compiler can choose the representation based on offsetting and scaling. It may chose, for instance, to add 273.15 to each value to make it positive, then we have a range of 0 .. 1273.15 and use an unsigned value. Or it may leave the negative values, requiring a signed value.

It might decide to scale it by 100, the minimum to get that delta, or by 128 to be able to scale with one shift or scale my 256 in order to require no shifting.
 

atferrari

Joined Jan 6, 2004
5,012
In my opinion, I believe that the discussion is still very much relevant.


We are trying to demonstrate how such simple conversions can be performed easily using fixed point integer arithmetic.

The formula assumed by the TS is correct.
Voltage = (ADC sample / Total ADC samples) * reference voltage

What it needs is proper implementation. In this example, all one has to do is use the data as calibration data.
6V input gives 512 ADC counts.

Hence,
Voltage = (ADC sample / 512) * 6

If one wants to show the result with one decimal place, use
Voltage = (ADC sample / 512) * 60

We can avoid a costly division by doing right shifts:
Voltage = (ADC sample * 60 ) >> 9

This can be simplified:
Voltage = (ADC sample * 15 * 4 ) >> 9
Voltage = (ADC sample * 15 ) >> 7

With rounding:
Voltage = (ADC sample * 15 + 64) >> 7
The first project I designed and fully implemented (temperature data collector for a greenhouse using the PIC 16C57) required me to learn on signal conditioning of the LM35 sensors and to design the fixed point arithmetic routines to cover -10ºC to 45ºC. It took me some time to learn tricks/simplifications like the above.

Interrupts would come much later...
 

Jon Chandler

Joined Jun 12, 2008
1,597
If you look at the original question, @gogo00 asked how to read 12 volts with a 5 volt input ADC. "I know I need to use a voltage divider."

He was satisfied by post #3. The following 36 replies have done nothing to further answer the very BASIC question.

That basic question hasn't really been fully addressed. "Use a voltage divider" is a great toss-off answer, but considering the level of the question, should it be? Is it as simple as grabbing any pair of resistors that produce a 5 volt output from a 12 volt input? How about 180k/130k?

No, it's not that simple, but instead y'all are arguing about the most efficient way to scale (scale, not calibrate) the resulting reading. Key point missed is that the acceptable range of voltage divider resistors depends on the input impedance of the ADC.

Nobody asked about the accuracy needed. This resulted in another key point being missed – any discussion of the voltage reference. If the micro is operating from a regulated supply, using Vdd as the reference is probably fine but perhaps the micro has a built-in fixed voltage reference. Basic questions need basic answers.

There is a tendency here to get lost in the weeds. To go off answering the question you want to answer (and often insisting your way is the only correct way to accomplish a thing), ignoring the gist of the question asked. And these threads go on for dozens if not hundreds of replies after a TS has stopped reading.

Maybe this is something to think about, but I'm afraid the most guilty will continue giving doctorate level "answers" to kindergarten level questions.
 
Top