Channels ▼

Al Williams

Dr. Dobb's Bloggers

Roll Your Own Analog Input

April 09, 2013

The right software appears below (or download here):

// Simple SAR ADC
// Williams -- DDJ
// Requires an Arduino
// that has an analog comparator on
// Arduino pins D6 and D7

#define LINEAR 1  // 0=binary search, 1=linear

int pwmout=9;  // pwm output pin
int settle=50;  // milliseconds to wait for settling
// The settle time will be more for higher RC
// Smaller RC can go faster but will have more
// PWM noise and thus will be less accurate

// Basic setup for serial and analog comparator
void setup()
{
  Serial.begin(115200);
  ADCSRB=0;  // use the comparator  but with no interrupts
  ACSR=0;
}

// read an analog sample ; returns 0 to 255
int convert()
{
#if LINEAR==1
  int guess=0;
  do {
    analogWrite(pwmout,guess);  // generate voltage
    delay(settle);  // let cap charge
    if (ACSR & _BV(ACO)) break;  // test comparator
    analogWrite(pwmout,0);
  } while (++guess<=255);  // not equal so keep guessing until max
  return guess;
#else
  int guess,hi=255,lo=0;
  do {
    guess=(hi+lo)/2;  // split search space
    analogWrite(pwmout,guess);  // generate voltage
    delay(settle);   // let cap charge
// set hi or lo based on comparator
    if (ACSR & _BV(ACO)) hi=guess; else lo=guess;
    digitalWrite(pwmout,false);  // discharge cap
  } while (lo+1

void loop()
{
  int g;
  float v;
  g=convert();  // get sample
  v=g*5.0/255;  // convert to volts
  Serial.print(g);
  Serial.print(" ");
  Serial.println(v);
  delay(2000);
}

The convert subroutine does all the work. Notice that there are two methods you can try. If you set LINEAR to 1, the algorithm just starts at zero and counts up until the comparator notes the voltages match. This is easy to visualize on an oscilloscope (see Figure 4 below). You can see the yellow voltage from the potentiometer and the blue voltage rising until they touch, then returning to zero.

If you set LINEAR to 0, the algorithm does a binary search for the voltage. That is, it starts at 2.5V and notes if it is low or high. If it is high, for example, it will try 1.25V next. Eventually it will zero in on the actual voltage. You can see the resulting scope traces in Figure 5 (below). Here, the blue line is the guess voltage, which overshoots, then undershoots, then bounces around a few times until it matches the target voltage.

This is one way an analog to digital converter can work (called a successive approximation converter). There are other ways, too. In some cases, you want another method to make some trade-off. For example, the parallel comparator method I mentioned first is very fast, but uses a lot of bits. The successive approximation is much slower but doesn't require many pins. There are other designs possible, some of which take advantage of special properties of integrated circuits, for example. I'll talk about some other analog input methods next time.

Why roll your own analog I/O? You probably don't want to do it in practice. But understanding why hardware works can often lead to practical insights when you do wind up using a black box supplied by your silicon manufacturer.

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.
 


Video