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
- Raspberry Pi 4B
- MCP3008 ADC
- 10kΩ Potentiometer
Step by step
- Drag Raspberry Pi 4B onto the Canvas.
- Drag the MCP3008 ADC onto the Canvas — a real DIP-16 chip, connects via drawn wires.
- Drag the 10kΩ Potentiometer onto the Canvas.
- 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).
- Wire the MCP3008 to the Pi's fixed SPI pins (physical/BOARD numbering):
| MCP3008 pin | Pi pin |
|---|---|
| VDD | 3.3V |
| VREF | 3.3V |
| AGND | GND |
| DGND | GND |
| CLK | Physical pin 23 (SCLK) |
| DOUT | Physical pin 21 (MISO) |
| DIN | Physical pin 19 (MOSI) |
| CS/SHDN | Physical pin 24 (CE0) |
- Wire the Potentiometer: GND → GND. VCC → 3.3V. SIG → MCP3008's CH0 (or whichever channel — note which one you used).
import spidevimport 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
- Turning the knob fully counter-clockwise reads near 0, fully clockwise reads near 1023, with a smooth, proportional value in between.
- The knob should physically stop at both ends of its travel.
More component tutorials are in Learn.