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.
Note: the Potentiometer (MCP3008 ADC) is a Premium-tier component in the simulator — you’ll need a Premium or VIP plan to use it there.
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)- Click Start. The Console prints "Potentiometer value: N" every half second. While it runs, drag the round knob on the potentiometer to change the value.
What “working correctly” looks like
- With the knob at its default middle position, the value is about 512. This is the first thing to check.
- 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.
If something’s wrong
- The value is always 0 → check the chip's power first. VDD must reach a Pi power pin and DGND or AGND must reach a Pi GND pin. An unpowered MCP3008 returns zeros.
- The value is still 0 with power wired → CS/SHDN must go to physical pin 24 (CE0) to match spi.open(0, 0), or to pin 26 (CE1) to match spi.open(0, 1). The simulator finds the chip by the chip-select pin.
- The value does not follow the knob → your script reads one channel, and the potentiometer's SIG wire must go to that same channel. The example reads channel 0, so use CH0.
- The value sticks at 1023 and the Console warns about the voltage → the potentiometer's VCC is on a higher voltage than the chip's VREF. Wire the potentiometer VCC to 3.3V, the same as VREF.
- This chip reads single-ended values only, using the request [1, (8 + channel) << 4, 0]. Differential reads are not supported.