Analog inputs and ADCs
A digital input answers yes or no: is the pin high or low? Many of the most useful sensors answer with a value instead — a potentiometer gives a voltage that depends on the knob's angle, an LDR one that depends on the light, a soil probe one that depends on moisture. The Pi has no pin that can measure a voltage, so every such sensor needs an analog-to-digital converter (ADC) between it and the Pi.
Why an ADC is needed
The 40-pin header is digital only: a GPIO reads high or low, with nothing in between. An ADC measures a voltage and reports a number, and it talks to the Pi over a digital bus — usually SPI or I²C. Two chips cover almost every case: the MCP3008 (cheap, 10-bit, eight channels, SPI) and the ADS1115 (precise, 16-bit, four channels, I²C).
MCP3008 — 10 bits, 8 channels, SPI
The classic Raspberry Pi ADC. It has eight single-ended inputs, converts one at a time, and returns a number from 0 to 1023 — 10 bits — proportional to the input voltage relative to its reference:
code = 1024 × Vin ÷ VREF
Wire VREF to 3V3 and the range is 0–3.3 V, with each step worth 3.3 V ÷ 1024 ≈ 3.2 mV. Power VDD from 3V3 as well: at 5 V the chip's data output swings to 5 V, which a GPIO must not see. It costs $4.
| 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 |
A potentiometer read through channel 0:
from wiring import *
pi = Pi()
adc = MCP3008()
pot = Potentiometer()
pi.V3_3 >> adc.VDD >> adc.VREF
pi.GND >> adc.AGND >> adc.DGND
pi.SCLK >> adc.CLK
pi.MOSI >> adc.DIN
pi.MISO >> adc.DOUT
pi.CE0 >> adc.CS
pi.V3_3 >> pot.pin1
pot.pin3 >> pi.GND
pot.wiper >> adc.CH0
from gpiozero import MCP3008
from time import sleep
knob = MCP3008(channel=0)
while True:
print(f"{knob.value:.3f} ({knob.voltage:.2f} V)")
sleep(0.5)
gpiozero.MCP3008 gives you value (0.0–1.0), voltage (0–3.3 V) and raw_value (0–1023). The MCP3008 page has the full pinout, and the potentiometer page explains the three terminals.
ADS1115 — 16 bits, 4 channels, I²C
The ADS1115 is the precise option: four inputs, 16-bit conversions, an internal reference and a programmable gain that picks the full-scale range (±4.096 V down to ±0.256 V), at 8–860 samples per second. It costs $6 and needs only the I²C pins:
- VDD and GND from the Pi.
- SDA and SCL to GPIO2 and GPIO3, alongside any other I²C devices — its part page has the pull-ups covered.
- ADDR picks the address: GND = 0x48, VDD = 0x49, SDA = 0x4A, SCL = 0x4B, so four can share one bus.
Its registers are 16-bit and big-endian: write a pointer byte, then read two bytes — which smbus2 can drive directly, or use the vendored Adafruit ADS1x15 driver.
Reading real sensors
- Potentiometer — ends to 3V3 and GND, wiper to the ADC. The wiper voltage is the knob's position across the full range.
- LDR — an LDR needs a partner: put the LDR from 3V3 to the ADC input and a 10 kΩ resistor from the input to GND. More light lowers the LDR's resistance and raises the voltage. The light sensor module is exactly this, pre-wired to an MCP3008.
- Soil moisture — the capacitive probe outputs a voltage that falls as the soil gets wetter. It drifts part to part, so calibrate: note the reading in dry air and in a glass of water, then scale between them. The soil module includes the ADC.
10 bits or 16?
- MCP3008: 1024 steps over the reference, 3.2 mV at 3V3. Plenty for a knob, an LDR or a soil probe — which are not that precise themselves — and its eight channels are handy.
- ADS1115: 32768 steps, about 125 µV at its 4.096 V range, but the noise floor is around a step, so treat the lowest bits as noise. Worth it for small signals (a thermocouple, a strain gauge), not for a doorbell light sensor.
- The reference matters more than the bits. On the MCP3008 the counts mean nothing if VREF is not the voltage you assumed; tie it to the same 3V3 the sensor uses, and keep inputs between 0 V and VREF.
Going deeper
- The MCP3008 is modelled at bit level. After CS goes low it waits for a start bit, a single-ended/differential bit and three channel bits; it samples, then shifts out a null bit, the 10-bit result MSB first, and the same bits LSB first, as the datasheet describes. VREF at or below 0.25 V reads 0. The simulated chip answers in SPI mode 0; another mode rotates the reply and warns. Missing MISO wiring or an unwired CS reads zeros.
- The ADS1115's model implements the register map: conversion (0), config (1) and threshold registers; 16-bit big-endian; single-shot mode sets the OS bit and takes 1/sample-rate of simulated time, clearing OS when done; the PGA picks the range. Noise is roughly one LSB, as the datasheet says.
- gpiozero's MCP3008 uses spidev in the simulator (port 0, device 0 — CE0) and falls back to bit-banging four GPIOs on real hardware if spidev is missing.
channel,differentialand the normalized reading all work as documented. - Unused inputs should be grounded; a channel with nothing wired to it has no defined voltage, and its readings wander.
- Divider maths for an LDR (LDR on top, 10 kΩ below): Vout = 3.3 V × 10 kΩ ÷ (LDR resistance + 10 kΩ). At 10 lux the GL5528 sits around 10–20 kΩ, so the reading lands near mid-scale; swap the resistor if your light range sits at one end.
- Never power the MCP3008 at 5 V. VREF may be 3.3 V while VDD is 5 V — the reference only sets the conversion range — but the digital output levels follow VDD, so at 5 V the chip puts 5 V on MISO.
- Datasheets: MCP3004/3008 (Microchip) and ADS111x (TI); gpiozero's SPI device docs cover
MCP3008and friends.