Making voltmeter accepting bipolar input voltage, using a microcontroller
As FakeMoustache explained, the diode idea isn't really a good one. The easiest way to achieve this is to adjust the input range (which includes both positive and negative voltages of high amplitude) to something useable by the ADC (a voltage between GND and VREF). For this, you need to reduce the input voltage amplitude and add a fixed offset. The aim is that when you have an input at 0V, you obtain a VREF/2 voltage to feed the ADC with.

We can build this stage with an operational amplifier. But this can be more effectively done if you accept to invert the input voltage sign and fix that later from the MCU firmware. For example, the adjusting stage will output a +VREF voltage when the input is -20V and a GND voltage when the input is +20V. Basically, the transfer function is reversed. This way, you can do this without needing negative voltage biases, and with a single opamp.

Here is the basic circuit:







simulate this circuit &ndash; Schematic created using CircuitLab

Now, how to compute the values of R1, R2, R3, R4 and R5 so that you get the range you need and the correct offset? Well, basically, everything can be deduced from the following formula:

\$\dfrac{\frac{V_{OUT}}{R1}+\frac{V_{IN}}{R2}}{\frac{1}{R1}+\frac{1}{R2}+\frac{1}{R3}}=\dfrac{\frac{V_{REF}}{R4}}{\frac{1}{R4}+\frac{1}{R5}}\$

You must find the appropriate values so that when VIN is 20V, VOUT is 0V and when VIN is -20V, VOUT is VREF. You must also ensure that the total input impedance is high enough to leave your input signal unaltered (values in the 100kΩ range will probably be fine).

But I'm a bit too lazy to solve this myself...

Last thing: choose an opamp with rail-to-rail inputs and output. Otherwise, you'll get incorrect results in the far end of the input range.



Edit: It seems I'm not that lazy after all. Let's say the input range is +VMAX → -VMAX and you want to translate this to 0 → +VREF, the above formula gives the following relationships between the resistance values:

\$\frac{R1}{R2}=\frac{V_{REF}}{2V_{MAX}}\$ and \$\frac{R4}{R5}=1+2\frac{R1}{R3}+\frac{V_{REF}}{V_{MAX}}\$

So, a possible solution for VMAX=20V and VREF=5V would be:


R1 = R3 = 12.5k
R2 = 100k
R5 = 10k
R4 = 32.5k


I checked with the circuitlab simulator, it seems consistent. Here is the transfer function: