MCP3008 8-Channel 10-Bit A/D Converter

The Raspberry Pi has no built in analog to digital converters (ADC), which can limit the types of sensors it can interface to directly; digital only. A simple and inexpensive option for adding several channels of analog inputs is with Micochip’s MCP3008. It features a SPI serial interface, can operate between 2.7-5.5 VDC, has 10 bit resolution, and can run in a single-ended or differential input configuration. A datasheet is included at the end of this article.

MCP3008-PDIP-16

Connecting the Hardware:

Four pins are required for SPI communications, data in, data out, clock and chip select (CS). A great interactive Raspberry Pi Pinout is posted at Gadgetoid. Here are the connections needed:

MCP3008 PIN PI (MODEL B2) PIN DESCRIPTION NOTES
1-8 CH0-CH7 NA Analog input
9 DGND 6, 9, 14, 20 or 25 Ground USE ONE PIN ONLY!
10 CS 24 (GPIO 8) CE0 or 26 (GPIO 7) CE1 SPI Channel Select USE ONE PIN ONLY!
11 DIN 19 (GPIO 10) MOSI Data out from Pi to MCP3008
12 DOUT 21 (GPIO 9) MISO Data into Pi from MCP3008 SEE NOTE #1!
13 CLK 23 (GPIO 11) SCKL Clock
14 AGND NA Common ground for analog input SEE NOTE #2
15 VREF NA Reference voltage for analog input SEE NOTE #2
16 VDD 1 or 17 (3.3V) Operating voltage SEE NOTE #1!

NOTE #1:  If the supply voltage for the MCP3008 is greater than 3.3VDC, the digital output line on the SPI interface can exceed the Raspberry Pi’s input voltage limit of 3.3V!

NOTE #2: The reference input (VREF) determines the analog input voltage range and is used to calculate the digital output code.

The formula to convert analog to digital is: 1024 (10 bit) * analog voltage in (VIN) / reference voltage (VREF).
Example: 2.5VDC analog in @ 5VDC VREF = (1024*2.5)/5 = 512.
Example: 2.5VDC analog in @ 3.3VDC VREF = (1024*2.5)/3.3 = 775.

Putting it together:

mcp3008_interconnect

Enabling Device Drivers Under Raspbian “wheezy”:

On some Raspberry Pi software distributions, SPI and I2C kernel modules are explicitly set not to be loaded (blacklisted). We will need to edit the ‘/etc/modprobe.d/raspi-blacklist.conf’ file to remove these restrictions. Place a comment (#)  at the front of the lines containing spi-bcm2708 and i2c-bcm2708. A reboot is needed.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

#blacklist spi and i2c by default (many users don’t need them)
#blacklist spi-bcm2708
#blacklist i2c-bcm2708

sudo reboot

Setting Up the Software:

This program requires Wiring Pi: GPIO Interface library for the Raspberry Pi to make it easier for setting up and using the Pi SPI interface. After you have installed WiringPi. you can test it with the following command.

gpio -v && gpio readall

Once WiringPi is successfully installed, copy the following source code into a file named mcp3008.c and compile.

mkdir source
cd source
nano readMcp3008.c

Double click the source code to get the full listing. Copy and paste into nano and save.

gcc -Wall -o readMcp3008 readMcp3008.c -lwiringPi

And now we can test the program. On my setup I have the first channel attached to 3.3VDC. The second channel is tied to a LED on my prototype board. The rest of the channels were left floating.

capture_mcp3008

Usage: readMcp3008 all|channel[1-8] [-l] [-ce1] [-d]
Options
-l = load SPI driver, default: do not load SPI drivers, drivers already loaded
-ce1 = spi channel 1, default: 0
-d = differential channel input, default: single-ended

External Resources:

Wiring Pi: GPIO Interface library for the Raspberry Pi

References:

MCP3008 Datasheet

Shaun Bennett has written 6 articles

6 thoughts on “MCP3008 8-Channel 10-Bit A/D Converter

    1. David says:

      My guess: you hit the same problem I did… your input impedance is too high for the MCP3008 to charge the “sample&hold” capacitor properly during one clock cycle. (e.g. with the supplied LDR and a 10k voltage divider.)

      Solutions: (a) add a relevantly sized capacitor.
      (b)give the chip longer to do the sample: (wiringPiSPISetup call) I found that all went much better at an SPI clock frequency of 500kHz rather than 1MHz.

  1. craig says:

    Thanks, very helpful. was a bit confused for a while as running the “gpio load spi” command would return “unable to load/unload modules as this Pi has the device tree enabled” . In the end, I just tried the program code anyway, and once I got the reference voltage right it was fine, even with the odd error message when using the command. Thanks!!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">