# Scale and shift small positive analog voltage range for ADC input

I want to measure a small positive analog voltage, 3v +/- 200mv with the ADC of a microcontroller.
The ADC measures voltages between 0 and 3.3V, so ideally I would like the voltage I am measuring to be mapped to that range.

I was able to find this post, which basically contains the same question as mine, but the math in the accepted answer is badly formatted and I was not able to deduce what to calculate to work out the resistor values I need:

How do I scale and offset an input to an ADC?

So my question is basically: How do I calculate the R1, R2 and R3 values in the linked post?

• Let's say it's a 10k potentiometer between 2.8v and 3.2v with a human hand turning the knob. Jan 20 at 3:53
• I could just measure that voltage with my ADC, but then I would only get 9ish bits of resolution out of the 12 bits it it has. Jan 20 at 3:59
• Make sure you do a sensitivity analysis of your circuit. In particular, any variations in the components used to offset the input (resistors, reference voltage) will have a roughly 10x larger effect on the ADC reading than others, including the ADC reference itself. Jan 20 at 7:41
• the math in the accepted answer is badly formatted and I was not able to deduce what to calculate to work out the resistor values I need I have fixed the math formatting in that answer to hopefully make things clear. Please let me know if there's anything else that is still unclear in the answer you mention. Making existing answers better is one of the goals here. Jan 20 at 17:28
• @Busti Do you actually need more bits of resolution? If the input is an actual single-turn potentiometer, then 9 bits of resolution gives an LSB smaller than one degree of mechanical rotation. If an actual human were to tweak that potentiometer and was expected to "hit" a position range that small, it'd be a bit annoying from user experience point of view. If the input is something else, then perhaps that voltage range is not inherent in its operation, just in how it was set up. Please edit the question to add the sensor type and its surrounding circuit. It's easy to get mired in an XY problem Jan 20 at 17:52

In this answer, bold text is used to indicate that a given section is general. The sections of bold text can be read independently of any particular concrete problem. Text which is not bold is specific to the problem given in the original question.

There are a number of circuits that are used to level shift and scale a signal. The specific circuit topologies that may provide solutions depend upon the specifics of the problem.

This answer assumes that the magnitude of amplification required is greater than 1, and the amplification is positive. Thus, in all cases, the input signal is connected directly or indirectly to the non-inverting input of an op-amp. It is also assumed that the level shifting is negative.

To find a topology that might provide an appropriate solution:

First find

$$\mathbf{A = \frac{\Delta V_{out}}{\Delta V_{in}}}$$

$$A = \frac{3.3-0}{3.2-2.8} = 8.25$$

Next find the value $$\\mathbf{V_0}\$$ of $$\\mathbf{V_{in}}\$$ that gives an output $$\\mathbf{V_{out}=0}\$$.

$$\mathbf{V_0 = V_{in}|_{V_{out}=0}}$$

In your case, we are told that an input of 2.8V gives an output of 0.

$$V_0 = 2.8$$

We can now write the equation relating $$\\mathbf{V_{in}}\$$ to $$\\mathbf{V_{out}}\$$ as

$$\mathbf{V_{out} = A(V_{in}-V_0)}$$

$$V_{out} = 8.5(V_{in}-2.8)$$

The circuit topology we use will depend upon what reference voltages we are able to use. To choose which topology, we will define another voltage $$\\mathbf{V_x}\$$.

$$\\mathbf{V_x}\$$ is the input voltage at which the output voltage is equal to the input voltage. That is $$\\mathbf{V_x}\$$ satisfies this equation

$$\mathbf{V_x = A(V_x - V_0)}$$

or

$$\mathbf{V_x = \frac{A}{A-1}V_0}$$

$$V_x = \frac{8.25}{7.25}2.8 = 3.1862 \text{V}$$

## $$\\mathbf{V_x}\$$ is available as a reference voltage

The simplest topology occurs when $$\\mathbf{V_x}\$$ is available as a reference voltage

The ratio between R1 and R2 must be $$\\mathbf{A-1}\$$.

$$\mathbf{R1:R2 = (A-1):1}$$

In your case, the ratio of R1 and R2 must be

$$R1:R2 = (A-1):1 = 7.25:1$$

Now if you happened to have a 3.1862 voltage reference, and two resistors with the ratio 7.25 between them, you would be done.

Here is the circuit.

simulate this circuit – Schematic created using CircuitLab

Unfortunately, there are no resistors in the E48 series that have a ratio of 7.25. You could however, use resistors in parallel or series to create such a ratio. But more importantly, you probably don't have a 3.1862 V voltage reference. So, we will look at some other solutions.

## A voltage greater than $$\\mathbf{V_x}\$$ is available as a reference voltage

If a voltage greater than $$\\mathbf{V_x}\$$ is available as a reference voltage, we can use the following topology.

With this new topology, we have the following relationships.

To get the proper gain, the resistors must have the ratio

$$\mathbf{\frac{R1}{R2 || R3} = A-1 }$$

and to get the proper voltage shift,

$$\mathbf{\frac{R2}{R1 || R3} = \frac{V_{ref}}{V_0} - 1}$$

Define

$$\mathbf{B = \frac{V_{ref}}{V_0} - 1}$$

Using a little algebra, we discover that we must have

$$\mathbf{\frac{R1}{R2} = \frac{A}{B+1}}$$

and

$$\mathbf{\frac{R1}{R3} = \frac{(A-1)B-1}{B+1}}$$

which gives the following ratio equation:

$$\mathbf{\text{R1:R2:R3} = \frac{1}{B+1}:\frac{1}{A}:\frac{1}{(A-1)B-1}}$$

Let's assume we have an accurate 3.3V reference voltage that we can use. (Remember that $$\V_{ref}\$$ must be greater than $$\V_x\$$ or 3.1862 V in your case to use this topology.

Then

$$B = \frac{3.3}{2.8}-1 = \frac{5}{28} = 0.1786$$

$$(A-1)B = \frac{2.9}{.4}\frac{5}{28} = \frac{145}{112}$$

$$(A-1)B-1 = \frac{33}{112}$$

$$\text{R1:R2:R3} = \frac{28}{33}:\frac{4}{33}:\frac{112}{33} = 7:1:28$$

It is more or less serendipity that there are nice standard values that match these ratios. If we plug values in these ratios into our circuit, we get the completed circuit.

simulate this circuit

## A voltage less than $$\\mathbf{V_x}\$$ is available as a reference voltage

If a voltage less than $$\\mathbf{V_x}\$$ is available as a reference voltage, we can use the following topology.

In this case, the resistor ratios are given by

$$\mathbf{R3:R4 = V_{ref}:AV_0}$$

$$\mathbf{R1:R2 = (k-A):A}$$

where

$$\mathbf{k = 1 + \frac{R4}{R3}}$$

Some ADC's provide a reference voltage at their midrange voltage. For a 3.3 V ADC, 1.65 volts may be available as a reference. We will choose that value to work an example.

The resistor ratios are calculated as follows:

$$R3:R4 = 1.65:(8.25\times 2.8) = 1.65:23.1 = 1:14$$

$$k = 14+1 = 15$$

$$R1:R2 = (15-8.25):8.25 = 6.75:8.25 = 27:33$$

Note that in the previous topologies, $$\\mathbf{V_{in}}\$$ was connected directly to the non-inverting input of the op-amp. This made the input impedance of the circuit very high. However, in this topology, the $$\\mathbf{V_{in}}\$$ is connected to the op-amp through a voltage divider. This brings the input impedance to approximately R1 || R2. Loading effects on the source may become an issue. There are at least two ways of dealing with the lowered input impedance of this topology. One solution is to use an extra op-amp as a voltage follower / unity gain buffer. Alternatively, one could simply use very high resistances for R1 and R2. This may lead to some inaccuracies, especially if the op-amp's input bias current is not very small.

In this example, we will use high valued resistors for R1 and R2 to mitigate loading issues, knowing that the best solution depends upon circumstances.

Here is a completed circuit.

simulate this circuit

• Math Keeps Me Busy - Hi, You've added blockquotes to several sections, and the quoted material is typically from someone else, as explained here. But in your answer, it's not clear to me who you are quoting in those blockquotes. Can you add a citation or link to who/what you are quoting? Otherwise people may (like me) spend time trying to find what you're quoting. TY Jan 20 at 17:04
• @SamGibson A quick google later my guess is that no quoting was intended, it was just a formatting choice. I may be wrong though. Jan 20 at 17:30
• @SamGibson I wanted to highlight those sections that were general, rather than specific to given values. The ">" seemed the best way to do it. Maybe I can use html markup to gray the background. In any event, I wasn't quoting anyone. Jan 20 at 17:36
• @Math - "The ">" seemed the best way to do it." Not really :( That syntax already has an established meaning and can be confusing when used for other things. || I see you have edited your answer & attempted to explain this non-standard usage. Note that we have had flags on previous non-standard blockquote usage (by others) because it causes readability problems. || I won't change things here now, unless flagged, but unfortunately I think what you want to do isn't possible within the (deliberate) syntax limitations allowed by SE :( Jan 20 at 17:51
• @MathKeepsMeBusy Use italics instead of ">". Screen readers will provide a bit confusing output when block quotes are used. Jan 20 at 17:53

Let's assume that the input voltage scales with the supply voltage, i.e. that the source of the input voltage is powered by the same 3.3V supply as the MCU is.

Since the useful input voltage range is close to the top rail, just amplify it with reference to that rail. The op-amp needs to have input common mode that includes the top rail, and "soft" rail-to-rail output range - within about 0.1V of either supply, so as not to split hairs. Most any "rail-to-rail output" op-amp will fit the bill here.

simulate this circuit – Schematic created using CircuitLab

Vin is the +/-200mV signal on top of the 3V DC baseline.

The Vin-to-out transfer function is:

While the output doesn't occupy the whole 0..3.3V ADC range, in most cases it'd be unrealistic anyway since you're not using 0% tolerance resistors, the op-amp doesn't have zero offset voltage, and the sensor/input source isn't perfect either, the ADC may have poor linearity very close to the rails, and all of these nonidealities are temperature-dependent to varying extent.

So, if I was asked to design such a mapping circuit, I'd do it as above. If the slightly larger output range is needed to get sufficient resolution from the ADC, it's the wrong ADC for the job anyway. Note that sufficient resolution doesn't imply full span of the ADC.

You start with a resolution and accuracy specification driven by the application needs. That spec has nothing to do with implementation details. Only then you start looking at "what parts would fit the bill", and nowhere is there an implication that every last bit of the ADCs range has to be utilized.

Note that mediocre textbooks have a tendency to oversimplify things without making it clear that nobody designs practical circuits the way the textbook implies. In this case, bothering with an "exact" mapping is not worth it, since the result you get is not practical and won't work exactly as the simplified textbook analysis would indicate. So, if your demand for "exact mapping" is textbook-driven, that textbook has failed at its job.

• Sigh. I like how you used the "sub" markup. I moved my general text to bold, and left the specific text plain. But looking at your "sub", I now think it might have been nicer to leave my general text plain, and make my specific text "sub". Jan 20 at 19:41