Computing stuff tied to the physical world

Measuring voltage without ADC

The LPC81x series microcontrollers does not include an analog-to-digital converter, just an analog comparator, which is obviously much more limited since it only tells you whether an input voltage is above or below another voltage level.

Nevertheless, this is sufficient to implement an N-bit ADC with just two resistors and one capacitor, using a very useful and clever technique called delta-sigma modulation.

To understand how a “delta-sigma ADC” works is going to require taking a small detour.

First, suppose we had a perfect infinite-precision A/D converter and D/A converter, and that we connect them together with a “differ” and “summer” – as follows:

Sdadc

The “differ” takes two voltages and outputs their difference (hence the name “delta”).

The “summer” takes an input voltage and adds it to its previous value, i.e. it accumulates over time (hence “sigma”). If you feed it zero volts, it stays the same, otherwise its output will gradually increase or decrease over time, depending on the sign of its input.

The digital output of the A/D converter (ADC) is fed to the D/A converter (DAC), and its output in turn is subtracted from our input voltage.

The essence of this circuit, is that the error between the input and the DAC’s output is used to adjust the voltage fed into the ADC. With an infinitely accurate ADC and DAC, the difference will move towards zero, and cause the “summer” (which is officially called an “integrator”) to track the input voltage.

When the input voltage rises, a positive error value is fed into the integrator, causing its output to rise, leading to a larger ADC result, driving the DAC output higher, making the error go back to zero. And likewise for falling inputs.

Neat, although so far we really haven’t achieved anything useful!

But now let’s assume that the ADC and DAC are both only 8 bits. They won’t be able to precisely track the input voltage. There will always be a small but non-zero error voltage going into the integrator. If the DAC is slightly too low, that small error will be positive, causing the integrator to slowly rise. Until the ADC sees a value which is one step higher than before, causing the DAC to generate an excessive output voltage. Now the error term will be negative, and the integrator output will start dropping again.

As you can imagine, the ADC results will start to alternate between slightly-too-high and slightly-too-low results. But there is more: if the input is very close to that lowest value, then most of the time the ADC ouput will be the low value, with only brief excursions into that high value. The average ADC result will in fact be a lot closer to the exact input!

So what we have to do, is to not take each ADC result at face value, but to collect a bunch of them and report their average. We’ve turned an 8-bit ADC into a (slower) 8+ bit ADC!

Taking N samples together and using them for a single result is called “over-sampling”. It’s very common in audio equipment – because good 20- or 24-bit ADCs are quite expensive.

Let’s return to our ADC-deprived LPC810.

The big trick we can apply is to use a “1-bit ADC + DAC”. If you think about it for a moment, these are very simple to construct: 1 bit analog-to-digital conversion just means “too high” or “too low”, so all we need to implement it is an analog comparator (aha, check!), using a fixed comparison voltage. Likewise, a 1-bit DAC is nothing but an output pin which is either high or low – a digital output pin!

Each result from the ADC will be only 0 or 1, so let’s simply add 1024 results together, i.e. count the 1’s. What we end up with, is a 10-bit integer from 0 to 1024 (inclusive), which indicates the proportion of the samples which were too low.

Keep in mind that we still need the entire mechanism, i.e. the 1-bit DAC to generate the output, which then feeds the “differ” and “summer” stages.

The one remaining question is how to translate these concepts into an electric circuit.

  1. To build an electronic “differ”: flip the sign of the output, and use an “adder”.

  2. To build an electronic adder: use two resistors to convert voltage to current, and connect their output pins. The output current will be the sum of the inputs.

  3. Lastly, we need a “summer” (i.e. integrator), and again, we’re in luck: that’s what a capacitor does. It collects (sums/aggregates/integrates) currents to build up a voltage.

So in the end, the entire delta-sigma modulation circuit is nothing more than this:

Sdimpl

The digital out is either low (0V) or high (3.3V), and will either feed a current into the capacitor or draw current out of it. The same for our unknown input voltage. When the ratio of on-off times for the output matches the relative input voltage compared to the comparator threshold, the capacitor voltage will fluctuate slightly around that threshold.

The cleverness comes from merging concepts from the analog voltage world and the analog time domain in such a way that the digital world of 1’s and 0’s can actually quantify it all.

Here’s is an example of high-low output bits, taken from the above page on Wikipedia:

Pulse density modulation 1 period

Keeping in mind the sign-reversal involved in the delta-sigma mechanism, you can see:

  • high input: most of the output cycles will need to be low to compensate
  • low input: most of the output cycles will need to be high to compensate

To put it another way: what the algorithm does, is to continuously adjust the digital output to get the capacitor’s voltage as close as it can to the analog comparator’s threshold.

This could be implemented in software, but the LPC81x actually has hardware which can perform this whole process – faster than the ┬ÁC and without consuming any CPU cycles.

So there you have it – when you see a “delta-sigma ADC” mentioned (which is sometimes erroneously called a “sigma-delta ADC”), you’ll know what it is – and how it works!

[Back to article index]