Microcontroller Interfacing Part 13

Using the A/D Converter Peripheral

  

Goals

The I/O lines discussed in the previous sections were binary – they can have only two states, high or low.  The real world is not so simple.  Real world signals can have an infinite number of values.  The Analog to Digital (A/D) converter is a bridge between the real analog world and our digital microcontroller. This section will be in introduction to using the A/D converter, also referred to as an ADC.

A/D Basics

The easiest way to think of an A/D converter is as a digital volt meter (DVM).  You hook up your DVM up to a battery and it shows something like 8.65 Volts.  The ADC measures the voltage, but does not directly provide the absolute voltage.  Instead it provides a numerical value, or code, that gives the sampled voltage with respect to a voltage reference.

The A/D converter can be used for a lot of purposes.  Probably the main use is to measure the voltage outputs of sensors.  Most electronic sensors produce a voltage that corresponds to temperature, pressure, acceleration or other phenomenon.  Music, speech, or other signals can be converted to digital form by A/D converters for storage or additional processing.  Finally, A/D converters can be used in some slick user interface applications, some of which will be covered in future segments.

The first thing to consider on an ADC is the resolution.  The A/D converters found on microcontrollers typically are 8 bit or 10 bit.  An 8 bit number can range between 0-255, or have 256 different values.  A 10 bit number can have a value between 0 and 1023, or 1024 discrete values. 

Assuming a 5 volt reference voltage, an 8 bit ADC  will return a value of 0 if the input voltage is zero volts.  If 5 volts is put on the A/D pin, the value returned will be the maximum value for 8 bits, or 255. Similarly, if the A/D converter is a 10 bit version, the returned value will be 0 for 0 volts applied, and 1023 with 5 volts applies.

The resolution of the A/D converter is the voltage change that will result in the returned value changing by 1.  Essentially it is the range of voltages divided by the number of possible values for the number of bits. Mathematically the resolution for an A/D is

Resolution = Ref/2^n

Where Ref is the A/D reference voltage and n= # of bits

  

For an 8 bit A/D covering 0-5V:  Vr es = 5/2^8 = 5/ 256 = 0.0196 V

For a 10 bit A/D covering 0-5V:    Vr es = 5/2^10 = 5/1024 = 0.00488 V

 

This means that with an 8 bit A/D the returned value will change by 1 when the voltage changes by about 20 mv.  With a 10 bit A/D, a change of only about 5 mV will change the count by 1. Clearly an A/D with more bits will give better accuracy.  Note that if the micro is running at a lower voltage, say 3.3V, the range covered by the A/D converter will be less.

Figure 13-1 shows a simplified 3 bit ADC that covers 0-1V.  The X-axis is the input voltage and the Y-axis shows the output code. Since it has only 3 bits, there are only 8 possible output codes, 0-7.  With this ADC, an input voltage of 0.0 - .125 V will produce an output code of 0.  Between .125 and .250 V the output code is 1, and so on.

There will be an uncertainty of the actual value. In the example of the battery and DVM we have the same situation. Assuming our DVM is perfectly accurate, the 8.65 V reading is an approximation. The battery could have an actual voltage anywhere between 8.645V and 8.654 V.  The last digit is rounded off.  The same thing happens with the A/D converter.  Adding more bits to the A/D  is like adding more digits on our DVM.  The more bit or digits you have, the finer the resolution.

Figure 13-1.  The graph shows the relationship between a voltage applied to the analog input pin for a theoretical 3 bit A/D converter with a 1V reference.

So why don’t we just use A/Ds with 20 or more bits and get really good resolutions? Well, there are draw backs. First is that the technology used for making fast, inexpensive digital microcontrollers is not conducive to making high resolution A/D converters.  If you need more resolution you will probably have to connect an external A/D to your microcontroller.  The price will increase as you add more digits. There are a number of additional problems that become harder to solve. We will cover some of these here.

  

Resolution, Accuracy and Precision

A common misconception is that resolution equates with accuracy. Suppose you have a voltmeter that goes to 3 decimal places.  Suppose it reads 8.653 volts.  Does it mean that the voltage is really 8.653 volts, +/-  .001 V? Not necessarily.  There could be any number of reasons the meter was not reading correctly unless you had it properly calibrated recently.   

How close the reading is to the actual voltage is the accuracy. How much the signal has to change to make a change in the reading is the resolution.  Resolution is sometimes referred to as the step size.

  

Suppose we had a DVM that displayed two digits after the decimal point. It would have a resolution of .01 volts.  If we needed to take readings within .1V, the meter would have plenty of resolution.  If we needed to measure within .001 V, it would not have enough resolution.

Suppose we dropped the meter and something happened to it. Now the meter reads .3 volts high. A 1.00 V source would read 1.3V. This is not very accurate. Yet, the resolution would not change. If the voltage being measured went up .01 volts (1.01V), the DVM reading would show 1.31V.

After discovering this we have the meter calibrated and the accuracy is back to spec.   Now suppose we measure a batch of batteries known to be exactly 1.25V.  We find some read high or low.  How much the readings vary from 1.25 is the precision, or repeatability. 

ADC Accuracy

There are a number of things that can adversely affect the accuracy of an A/D converter.  The first is the accuracy of the reference voltage.  With a 5V reference and an 8 bit A/D, we have a resolution of 0.0196 V as shown earlier.  If we make a reading, we can calculate the voltage by multiplying our reading by .0196.  A more general form would be

  

Vin = ADreading * (Vref /2^n)   where n is the number of bits.

  

Now suppose our 5V reference was really 4.9V. We would not get accurate results if we used 5V for our calculations.  The accuracy of the ADC reading can be no better than the accuracy of the reference.

There are often options for the reference voltage source for the ADC on a microcontroller.  These are configured under program control.  The most common reference voltage is the microcontroller supply voltage.  A power supply built with a garden variety 7805 voltage regulator may be off by a few percent. This is not very accurate, and depending on  your application, not be accurate enough.

Some microcontrollers have a more accurate internal voltage reference. Usually this will be at some lower voltage than the supply voltage.  A micro with a 5V supply might have an internal reference of 3.8V. This means you can only measure voltages between 0-3.8 volts when using this reference.  Microcontrollers with internal A/D converters often have a pin that an external voltage reference can be connected to. There are special ICs that are designed to be highly accurate voltage references.

You can perform an interesting experiment with an Arduino by using the program in listing 13-1. It reads an external voltage applied to analog input A0 and displays the result on a Unified Microsystems ATS-1 LCD terminal shield.  Connect a 1.25V battery to the Arduino.  Be sure to connect the battery’s negative terminal to the Arduino GND and the battery’s positive terminal to the Arduino AO pin.   You can damage the Arduino if you connect it backwards!

With the Arduino powered by the USB port note the voltage reading.  Then remove the USB cable and power the Arduino through the external power jack. If you don’t have a power supply, a 9V battery will work. Does the voltage differ with the different power supplies?  Using different power sources I got variations as much as .03V from the same battery.

//***************************************************************************************************************************

// DVM - Simple Arduino DVM

// Gary C. Sutcliffe

// Version 1.00

// March 2012

//

//This program is a simple Digital Volt Meter using an Arduino. It measures the voltage on analog pin A0.

// The results are shown on a Unified Microsystems ATS-1 Terminal Shield.  www.unifiedmicro.com

///DVM  Program by Gary C. Sutcliffe is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

//

// **** IMPORTANT: Don't apply more than 5V to the analog input pin or you may damage the Arduino! ****

//

//Updates:

//***************************************************************************************************************************

int analogPin = 0; //The voltage is connected to Analog pin 0

  

#define CLS  0x01  //Character to send to the ATS-1 to clear the LCD and home the cursor  

#define SCALE_FACTOR .00488    //the voltage difference to change the 10 bit Arduino A/D reading by one  

#define TRUNC_VAL  4  //divisor for truncating lower bits. 2 will truncate LSB, 4 lowest 2 bits, 8 lowest 3 bits

  

void setup()

{

Serial.begin(4800);   // opens serial port, sets data rate to 4800 baud to LCD display 

}

  

void loop()

{

float voltage;

int rawAD;      //raw A/D reading value

rawAD = analogRead(analogPin);

voltage = (float)rawAD * SCALE_FACTOR;  //convert the A/D reading to a type float and multiply by scaling factor

Serial.write(CLS);     //Clear the LCD screen

Serial.print("Voltage: ");

Serial.print(voltage);  //note that Serial.print defaults to two digits after the decimal point.

delay(250);   //put in a short delay between readings

}

  

Listing 13-1  This simple program turns an Arduino into a simple digital volt meter to read voltages up to 5 volts.

IThe USB port directly supplies 5V to the Arduino, and the ADC reference.  An on board voltage regulator supplies 5V when an external voltage source is applied.  The “5V” from the different sources may differ a bit, resulting in different ADC references.  Also try powering the Arduino through the USB port from different computers (try a laptop) and through external USB hubs.  

We have established that a 10 bit A/D has a resolution of about .0049V. Each time we raise the input voltage by .0049V the reading will increase by one.  That is not exactly true.  On the average, across the entire voltage range,  the reading will change by 1 for every .0048V volt change. In reality the relationship between the input voltage and the reading is often not a straight line.  It is often a curve, and it might take a bit more or less voltage change to change the reading in the middle of the range than it does at the ends. The microcontroller’s data sheet should show you what to expect. 

Noise

Noise is the enemy of analog signals, especially if the signal level is very low or we need great accuracy. Noise can come from many sources.  Every component generates noise.  Even the A/D converter itself adds some noise. Improper design or poor component selection can result in enough noise to mask weak signals or affect the accuracy that they can be measured.  

Figure 13-2 Arduino running the DVM program and measuring a NiMH AA battery.  Notice an actual meter reading the same battery. The white box above the Arduino contains a 9V battery, powering the Arduino and LCD shield.

Digital circuits like microcontrollers generate a lot of noise on the power supply lines called switching noise.  If you look at Figure 3.1 back in Part 3 of this series,  you will see the typical output circuit of a microcontroller.  There are two transistors. Only one will be on at a time. If the top transistor is on, the output will be connected to the supply voltage and the output will be high. If the lower transistor is on, the output pin will be connected to ground and the output will be low.  As the output switches from one state to the other there will be a brief instance when both transistors are on, or at least partially on. This causes a brief short circuit between power and ground and will induce a voltage spike on the power lines.  

The supply noise can get into the sensor supplying the voltage to be measured or signal conditioning circuitry before it reaches the A/D input pin. Noise can also be coupled from noisy sources like motors into analog signals. The accuracy of the A/D reading will be reduced depending on the amount of noise present.  

Switching noise can get into the voltage reference as well.  The microcontroller data sheet will usually give instructions for the circuit design to minimize noise on the reference.  This usually involves adding capacitors on a pin.

If a microcontroller is running on 5V and has .1V of noise on the power lines, it will probably not affect the basic operation of the microcontroller.  That same amount of noise on an analog signal will randomly change the reading on a 10 bit A/D by up to 20 counts.  

Proper design and circuit board layout will help minimize noise. Properly bypass the power lines and reference voltages.  Keep the high power switching part of your circuit away from the low level analog section. Provide a ground plane on the circuit board layout.  Follow any other board layout suggestion in the microcontroller data sheet.  

Sampling Time  

Another important parameter of an ADC is the conversion time.  It takes a certain amount of time from when you command the microcontroller to take a measurement and when the result is available.   The amount of time required will limit the applications you can use it for.  

If you are measuring the voltage on a battery or using a temperature sensor to measure the temperature of your swimming pool, the signal does not change very fast, and the speed of conversion is not too important.  If you are using a sensor to control a high speed machine you might need to take readings very frequently for proper operation.  

A common application of A/D conversion is to digitize speech or music.  This is how they got the music into your CD or MP3 file.  Mathematically it is possible to take periodic readings of an analog signal and then later to recreate the analog signal from the samples. This is what happens when you listen to music on your digital devices.  

There is a mathematical law, called the Nyquist Sampling Theorom which states that if you sample the signal at least twice as often as the highest frequency present in your signal, you can recreate the original signal.  A typical land line phone has a bandwidth of about 3 KHz.  To get the same sound quality of a phone line, your microcontroller must be capable of  sampling at least twice that rate, or 6 KHz.  The sampling rate for music on CDs is 44 KHz.  

Summary

Analog to digital conversion is the method used to convert real world signals into the digital world. It is a very powerful technique, but using the ADC on your microcontroller is more complex than using the digital lines.  For best success understand the limitations of your ADC and use proper circuit design and layout techniques to minimize noise. 

Arduino Notes

  • The Uno has 6 10 bit A/D input channels
  • Use the analogRead(pin#) function to read the value
  • The maximum  sample rate is about 10,000 samples/second
  • The 5V (3.3V) supply voltage is the default voltage reference source. It also has a 1.1V internal reference that can be used as well as a pin for an external reference.

© 2009 - 2022 Gary C. Sutcliffe

  

Created with the QTH.com SiteBuilder.