Learn

Reading a Potentiometer on a Raspberry Pi 4B with an MCP3008 ADC

The Raspberry Pi has no analog input — read a real potentiometer's position using an MCP3008 ADC over SPI, with full wiring and Python code.

Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.

What you’ll need

Step by step

  1. Drag Raspberry Pi 4B onto the Canvas.
  2. Drag the MCP3008 ADC onto the Canvas — a real DIP-16 chip, connects via drawn wires.
  3. Drag the 10kΩ Potentiometer onto the Canvas.
  4. Hover over every MCP3008 pin and note the exact labels shown (standard datasheet pins are CH0-CH7, VDD, VREF, AGND, CLK, DOUT, DIN, CS/SHDN, DGND — confirm against the actual on-screen labels).
  5. Wire the MCP3008 to the Pi's fixed SPI pins (physical/BOARD numbering):
MCP3008 pinPi pin
VDD3.3V
VREF3.3V
AGNDGND
DGNDGND
CLKPhysical pin 23 (SCLK)
DOUTPhysical pin 21 (MISO)
DINPhysical pin 19 (MOSI)
CS/SHDNPhysical pin 24 (CE0)
  1. Wire the Potentiometer: GND → GND. VCC → 3.3V. SIG → MCP3008's CH0 (or whichever channel — note which one you used).
import spidev
import asyncio
 
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000
 
def read_channel(channel):
adc = spi.xfer2([1, (8 + channel) << 4, 0])
return ((adc[1] & 3) << 8) + adc[2] # returns 0-1023
 
while True:
value = read_channel(0) # change to match whichever CH pin you wired
print(f"Potentiometer value: {value}")
await asyncio.sleep(0.5)

What “working correctly” looks like

More component tutorials are in Learn.