ABC of Electronics cosycom.com
RASPBERRY PI 12 · Sensors

Reading Analog Sensors with an MCP3008 ADC

The Raspberry Pi has no built-in ADC at all — here's the small external chip that gives it one, and how to read it over SPI.

You'll need: an MCP3008 (an 8-channel, 10-bit ADC chip), a potentiometer or LDR-divider from Lesson cb-12, jumper wires, a breadboard, and your Pi.

Lesson 29 covered ADCs, and the Arduino Uno has one built in, ready to use with a single analogRead() call. The Raspberry Pi's GPIO pins are purely digital — there's no equivalent built-in ADC at all. To read any analog voltage on a Pi, you need an external ADC chip like the MCP3008, connected over the SPI protocol from Lesson 34.

Wire the MCP3008 to the Pi's SPI pins (covered fully in Lesson rpi-14), connect your analog source (a potentiometer's wiper, or an LDR divider's junction) to one of the MCP3008's 8 analog input channels, and read it in Python using the spidev library:

read_adc.py
import spidev

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000

def read_channel(channel):
    cmd = [1, (8 + channel) << 4, 0]
    reply = spi.xfer2(cmd)
    value = ((reply[1] & 3) << 8) + reply[2]
    return value

print(read_channel(0))  # 0-1023, same range as Arduino's analogRead()

The MCP3008 communicates over SPI using a specific 3-byte command format, which is what the slightly cryptic cmd list encodes — you don't need to fully understand SPI's byte-level protocol to use this function, just to know that read_channel(0) through read_channel(7) reads each of the chip's 8 input channels, returning the same familiar 0–1023 range as the Uno's analogRead().

Pi (SPI) MCP30088ch ADC Potentiometer/LDRabcofelectronics
The Pi talks to the MCP3008 over SPI; the MCP3008 does the actual analog-to-digital conversion the Pi's own pins can't.
TRY THIS
Any analog sensor on a Raspberry Pi needs an external ADC chip like the MCP3008 — unlike the Uno, there's no built-in analogRead() equivalent at all.