MCP3008 ADC (SPI)
The MCP3008 is an 8-channel, 10-bit analog-to-digital converter in a DIP-16 package. It costs $4 and is the classic way to give a Raspberry Pi analog inputs: the Pi has no ADC of its own, so a potentiometer, an LDR or a soil probe is read through this chip over four SPI wires, turning a voltage into a number from 0 to 1023. The analog inputs primer explains why that is needed in the first place.
Pins
| Pin | What it is | Type |
|---|---|---|
| CH0 | Analog input 0 (pin 1) | io |
| CH1 | Analog input 1 (pin 2) | io |
| CH2 | Analog input 2 (pin 3) | io |
| CH3 | Analog input 3 (pin 4) | io |
| CH4 | Analog input 4 (pin 5) | io |
| CH5 | Analog input 5 (pin 6) | io |
| CH6 | Analog input 6 (pin 7) | io |
| CH7 | Analog input 7 (pin 8) | io |
| DGND | Digital ground (pin 9) | ground |
| CS | Chip select, active low (pin 10) | io |
| DIN | Serial data in, from MOSI (pin 11) | io |
| DOUT | Serial data out, to MISO (pin 12) | io |
| CLK | Serial clock, from SCLK (pin 13) | io |
| AGND | Analog ground (pin 14) | ground |
| VREF | Reference voltage (pin 15) | io |
| VDD | Supply 2.7–5.5 V (pin 16) | power |
CH0–CH7 are the analog inputs; the wiper of a pot or the middle of a divider goes to one of them. VDD and VREF both go to 3V3 — VREF sets the conversion range and VDD powers the logic — and AGND and DGND join at the Pi's ground. CLK, DIN, DOUT and CS are the SPI side: the Pi's SCLK, MOSI, MISO and CE0.
Wiring it in circuit.py
A potentiometer on channel 0, using the Pi's hardware SPI pins:
from wiring import *
pi = Pi()
pot = Potentiometer(10000)
adc = MCP3008()
pi.V3_3 >> pot.pin3
pot.pin1 >> pi.GND
pot.wiper >> adc.ch0
pi.V3_3 >> adc.vdd
adc.vdd >> adc.vref
adc.agnd >> pi.GND
adc.dgnd >> pi.GND
pi.SCLK >> adc.clk
pi.MISO >> adc.dout
pi.MOSI >> adc.din
pi.CE0 >> adc.csThe knob + ADC kit is this circuit pre-wired: it exposes vdd, gnd, clk, dout, din and cs, and the pot sits on channel 0.
Driving it in main.py
from gpiozero import MCP3008
from time import sleep
knob = MCP3008(channel=0)
while True:
print(f"{knob.value:.3f} {knob.voltage:.2f} V raw {knob.raw_value}")
sleep(0.5)value is the reading divided by VREF (0.0–1.0), voltage is the input in volts and raw_value is the code from 0 to 1023. Pass differential=True to read a channel against its neighbour instead of ground.
Electrical notes
- Supply is 2.7–5.5 V, but power it from 3V3. At 5 V the chip's digital output swings to 5 V, which the SPI pins must not see; VREF may still be 3.3 V, since it only sets the conversion range.
- 10 bits over VREF:
code = 1024 × Vin ÷ VREF. With VREF on 3V3 that is one step of about 3.2 mV. - The model adds the datasheet's errors: a smooth bow of up to 1 LSB across the range (integral non-linearity) plus Gaussian noise of 0.5 LSB σ by default. Both are datafeed knobs; offset and gain errors are not modelled.
- It converts up to about 200 kSPS at 5 V (75 kSPS at 2.7 V), draws 425 µA, and answers in SPI mode 0. The datasheet's other mode, 3, is not modelled: a driver that asks for it gets a warning and a reply shifted by one bit.
- Leave unused channels grounded: a floating input reads whatever its neighbour last held.
- VREF at or below 0.25 V reads 0, which is a handy test — an unwired reference gives all-zero codes.
Simulator vs real hardware
- SPI is decoded at bit level: after CS goes low the chip waits for a start bit, the single-ended/differential bit and three channel bits, samples, then shifts out a null bit, the 10-bit result MSB first and the same bits LSB first — exactly as the datasheet's timing diagram, so gpiozero, spidev and hand-rolled drivers all work.
- The eight channels are also differential pairs (CH0–CH1, CH2–CH3, …), so
MCP3008(channel=0, differential=True)reads CH0 minus CH1 like the real chip. - Conversions are instant: no sample rate, no minimum clock, no droop. On hardware, reading faster than the sample rate starts overlapping conversions.
- gpiozero's
MCP3008uses spidev (port 0, device 0 → CE0) in the simulator. For a different chip select, wire it and drive the transfer yourself.
Going deeper
- Primer: analog inputs and ADCs compares this chip with the ADS1115.
- Analog sources: potentiometer, light sensor, soil moisture.
- Pre-wired modules: knob + ADC, light sensor + ADC, soil sensor + ADC.
- Libraries: gpiozero's
MCP3008and spidev. - Recipe: the night light reads an LDR through channel 0.
Further reading
- MCP3004/3008 datasheet (Microchip DS21295) — conversions, SPI framing and the channel map.
- gpiozero: SPI devices —
MCP3008(channel=0),differentialandraw_value. - Adafruit: MCP3008 SPI ADC — the chip and the pot-to-ADC circuit on a bench.