Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Potentiometer with Raspberry Pi Pico W — MicroPython ADC read_u16

Read a 10 kΩ potentiometer on Pico W ADC0 (GP26) with MicroPython’s read_u16, convert it to volts and percent, and dim an LED with PWM.

MicroPythonVerified — micropython (mpy-cross v1.29.0), 3 Nov 2026Compile-only

Community draft — report a mistake

A potentiometer is the simplest way to learn the Pico W’s ADC. The two outer legs go to 3V3 and AGND, the wiper to GP26 (ADC0), and MicroPython reads it with ADC(26).read_u16().

The script prints the raw value, the voltage and a percentage four times a second. Add an LED on GP15 and it follows the knob through hardware PWM.

Wiring

Raspberry Pi Pico WOnly the pins used are shown · 3.3 V logicRotary potentiometer (10 kΩ, B10K)3V3AGNDGP26Pin 1WiperPin 3
Also needed: Optional: LED + 220 Ω resistor from GP15 (pin 20) to GND.
Every connection
Raspberry Pi Pico WRotary potentiometer (10 kΩ, B10K)WireNotes
AGNDPin 1blackAGND (pin 33) is the analog ground next to the ADC pins — quieter than a digital GND. Any GND also works.
GP26WipergreenGP26 = ADC0, physical pin 31.
3V3Pin 3red3V3 is pin 36. Never use VBUS or VSYS here — the wiper would reach 5 V.

Passive — across the board’s 3.3 V or 5 V part, 3.3 V board. Connect the outer legs to the same voltage your ADC uses: 3.3 V and GND on ESP32 and Pico, 5 V and GND on Uno. The wiper can then never exceed the pin limit.

Board quirks

  • Only GP26, GP27 and GP28 are analog on the header (ADC0–ADC2). GP29 is used inside the Pico W by the wireless chip.
  • read_u16() always returns 0–65535: the RP2040’s 12-bit result scaled up, so code moves unchanged between boards.
  • The ends of the range are not perfect: expect a few hundred counts at 0 V and a little below 65535 at full scale. Averaging 16 reads steadies the number.
  • The Pico W’s own LED is switched by the wireless chip and cannot be dimmed — that is why the PWM demo uses an external LED.

Code

main.pyMicroPython
# Potentiometer on a Raspberry Pi Pico W ADC (MicroPython).
# Wiring: Pin 1 -> AGND (pin 33), Wiper -> GP26 / ADC0 (pin 31), Pin 3 -> 3V3 (pin 36).
# Optional: an LED + 220 Ohm on GP15 (pin 20) follows the knob. The Pico W's own LED sits on the
# wireless chip and can only switch on/off, so PWM dimming needs an external LED.
from machine import ADC, Pin, PWM
import time

pot = ADC(26)               # GP26 = ADC0. Only GP26, GP27 and GP28 are analog on the header.
led = PWM(Pin(15))          # optional LED + 220 Ohm on GP15 (pin 20)
led.freq(1000)


def read_avg(n=16):
    # read_u16() always returns 0-65535 (the 12-bit result scaled up); average away the noise
    return sum(pot.read_u16() for _ in range(n)) // n


while True:
    raw = read_avg()
    volts = raw * 3.3 / 65535
    pct = raw * 100 // 65535
    led.duty_u16(raw)
    print("raw {:5d}  {:.2f} V  {:3d} %".format(raw, volts, pct))
    time.sleep_ms(250)

Expected serial output

REPL / Thonny shellOutput
raw   412  0.02 V    0 %
raw 21876  1.10 V   33 %
raw 43305  2.18 V   66 %
raw 65231  3.28 V   99 %

Common errors

ValueError: invalid Pin for ADC

Only GP26, GP27 and GP28 work with ADC(). Move the wiper to one of them.

Value jumps by hundreds while the knob is still

Normal ADC noise on a breadboard. Use AGND for the pot, keep wires short, and average more readings.

↑↓ to move · Enter to open