Channels ▼

Al Williams

Dr. Dobb's Bloggers

More Conversions

April 15, 2013

Last time I built a simple A/D converter using an Arduino and its built-in comparator. I mentioned the algorithm was SAR or successive approximation, and that's true of the code that did the "binary search" — that is, it guessed about half of the voltage and then kept making adjustments depending on whether the guess was high or low. However, the program that simply ramped the voltage until it hit the target voltage is actually a "ramp compare" converter. A small point, since both use the same principle: Guess a voltage and see if it is the same. The only difference is the algorithm used to drive the guesses.

In general, however, all converters use the same sort of principle. As I mentioned last time, take what you know and use it to get what you don't know. In this case, what you know is a voltage the converter (in this case, the Arduino) generates. That only works, though, because the computer has enough external circuitry to generate a voltage.

The other thing that computers are pretty good at knowing is time. Granted, it is sometimes hard to know exactly what time it is (which leads to GPS, IRIG-B signals, and rubidium clocks). But it is pretty easy to know relative times, and that is another way you can make a digital circuit measure a voltage.

For example, you can charge a capacitor to an input voltage and then determine how quickly it discharges to a known point (for example, 0 volts). There are several variations on this theme. You can let the capacitor discharge naturally and do some math, or you can arrange for a constant current discharge of the capacitor so you get a linear relationship between time and voltage.

In fact, many sensors look like resistors (some joysticks, volume controls, and thermistors, for example) or capacitors (level sensors, proximity sensors, some humidity sensors, among others). In these cases, it is easy to measure the charge or discharge time with a known capacitor (for resistive sensors) or a known resistance (for capacitive sensors).

This is so useful, the popular Basic Stamp and many of its imitators include a command just for this purpose called RCTime. The Arduino even has an analog of that command.

Here's a slightly modified excerpt of the function from the Arduino tutorial:

long RCtime(int sensPin){
   long result = 0;
   pinMode(sensPin, OUTPUT);       // make pin OUTPUT
   digitalWrite(sensPin, HIGH);    // make pin HIGH to discharge capacitor  
   delay(1);                       // wait a  ms to make sure cap is discharged

   pinMode(sensPin, INPUT);        // turn pin into an input and 
   digitalWrite(sensPin, LOW);     // turn pullups off - or it won't work
   while(digitalRead(sensPin)){    // wait for pin to go low (and time in result)

   return result;                   // report results   

There are several ways you could wire up a circuit for this type of service, but the code above assumes you have a capacitor from the 5V rail to one side of a resistor. Then the other side of the resistor goes to ground. A small resistor (say, 220 ohms) goes from the center of the resistor/capacitor network to the Arduino pin. Either the resistor or the capacitor can be the unknown value. You can see the schematic below.

By bringing the pin to a high output, the capacitor has the same voltage across it and discharges. The function then makes the pin an input (with no pull-ups), which is effectively an open circuit. This allows the capacitor to charge. While it is charging, the capacitor will start out as nearly a short circuit. The voltage across it will get greater and greater until it looks like an open circuit (nearly). The Arduino will read the input as a low before that happens. The function counts up until the pin reads low. This is another example of using what you know (time, in this case — the time it takes to go through the loop) to get what you don't know (the unknown resistance or capacitance).

Of course, this doesn't give you an absolute value. It gives you a relative one. Without calibrating, all you can say is that the resistance now is more or less by some amount than it was before. To make things worse, the capacitor charges with an exponential curve so the result is not linear. That is, the actual measurement difference between 10 and 12 won't be the same as the difference between 100 and 102. To get a constant slope on a charging capacitor you have to use a constant current source, not a constant voltage as is the case here.

On the other hand, for some purposes this relative non-linear measurement is fine. One last interesting tidbit: In the macro world, resistors are inexpensive and of high quality and capacitors tend to be lower quality for the cost. High-precision designs often rely on resistors. However, on an IC die, resistors are sometimes difficult to fabricate precisely. Capacitors, on the other hand, can be made from very exact sized conductor plates with very thin insulating layers that are part of the standard IC process. That means IC designers often use designs that utilize highly precise capacitors instead of resistors.

Many processors now have built in analog I/O and that certainly makes things easier. But it is still worthwhile to understand how at least some of these devices work.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.