---
title: "Raspberry Pi Pico ADC Explained: Hardware, Modes, Registers & Common Pitfalls"
url: "https://maker.wiznet.io/ruilixin6/projects/raspberry-pi-pico-adc-explained-hardware-modes-registers-common-pitfalls/"
markdown_url: "https://maker.wiznet.io/ruilixin6/projects/raspberry-pi-pico-adc-explained-hardware-modes-registers-common-pitfalls/md"
type: "UCC: User Created Content"
author: "FreakStudio"
author_url: "https://maker.wiznet.io/ruilixin6/"
original_author: "Freakstudio"
original_url: "https://f1829ryac0m.feishu.cn/drive/folder/Fh5Eftd3WlbEIIdHGdtcSsIgn7c?from=fyt"
published: "2026-08-24"
language: "en"
tags: ["ADC", "Pitfalls", "RP2040"]
likes: 0
views: 85
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# Raspberry Pi Pico ADC Explained: Hardware, Modes, Registers & Common Pitfalls

> In‑depth analysis of RP2040 on‑chip ADC covering hardware architecture, one‑shot /free‑running modes, register description

Original author: Freakstudio (source: https://f1829ryac0m.feishu.cn/drive/folder/Fh5Eftd3WlbEIIdHGdtcSsIgn7c?from=fyt)

## Article

【Preliminary Note】The original hardware example in this article was written based on the RP2040. The actual hardware used in this hands-on demonstration features the W55RP20 as the main controller chip. The circuit logic and UF2 flashing operation principles are universally applicable, with only the main controller model differing. The original chip model mentioned in the circuit descriptions below is provided for reference purposes only.

![](https://maker.wiznet.io/upload/ckeditor5/383111824%5F1787572726%2Epng)

1. ADC Peripheral Introduction

The RP2040 integrates a Successive‑Approximation Register (SAR) ADC. This ADC uses an independent 48 MHz clock and supports a maximum sampling rate of 500 ksps (500 000 samples per second), suitable for medium‑speed signal acquisition. It features 12‑bit resolution, which means it can convert analog input signals into 4096 (2^12) distinct digital values. Its Effective Number Of Bits (ENOB) is 8.7, representing its real‑world practical precision.

![1.png](http://openwrite.cn/uploads/21597/64045/7bf5afa8-5124-4f67-a074-a749b268b2ca.png)

Connection between the on‑chip RP2040 ADC peripheral and GPIO pins:

![2.png](http://openwrite.cn/uploads/21597/64045/5bbe82df-4df7-4ed5-b2d7-2098249de356.png)

A digital controller is dedicated to managing ADC operations and provides additional functions:

One‑shot sampling mode or free‑running sampling mode The ADC can be configured to perform a single conversion (one‑shot mode) or run continuous sampling (free‑running capture mode).

Sampling FIFO with DMA interface ADC sampled data is stored inside a FIFO buffer. Data can be transferred to system memory via DMA (Direct Memory Access) to reduce CPU workload.

Ticking timer This timer features 16‑bit integer plus 8‑bit fractional resolution for setting sampling rates under free‑running mode. It allows precise control over sampling time intervals.

Polled multi‑channel sampling Under free‑running mode, the ADC can sample multiple input channels in round‑robin sequence, which is useful when multiple signals need to be acquired simultaneously.

Optional 8‑bit right‑shift output In free‑running mode, sampling results can be optionally right‑shifted to 8‑bit width. Sampled data can then be transferred as bytes via DMA into system‑memory buffers, which helps reduce memory footprint and simplifies byte‑oriented data processing.

When using the ADC peripheral, make sure digital functions of the target pins are disabled. This is accomplished by setting the IE (input enable) bit low (IE = 0) and OD (open‑drain drive) bit high (OD = 1) inside the Pad Control register for that pin.

![3.png](http://openwrite.cn/uploads/21597/64045/4c140c35-6d7b-4318-8302-89e43fca623a.png)

In addition, the maximum allowable ADC input voltage is determined by the digital I/O supply voltage (IOVDD), not the ADC analog supply (ADC_AVDD). For example, if IOVDD equals 1.8 V, ADC input voltage must not exceed 1.8 V even when ADC_AVDD is 3.3 V. Voltages exceeding IOVDD create leakage current through ESD protection diodes and may permanently damage the chip.

![4.png](http://openwrite.cn/uploads/21597/64045/20adb8cb-97e1-4f17-abb2-8db8effd6c10.png)

ADC input impedance on Raspberry Pi Pico is approximately 100 kΩ. This impedance value works well for most applications. If the signal‑source impedance is higher than the ADC input impedance, signal attenuation will occur and measurement accuracy will degrade.

As mentioned above, RP2040 integrates a SAR‑type ADC. Its block diagram is shown below:

![5.png](http://openwrite.cn/uploads/21597/64045/ed97c1f6-5dcf-4497-876e-98a99d375131.png)

The internal DAC unit inside the SAR ADC is one of its key components. It converts digital values back into analog voltages for comparison against the incoming analog input signal.

The operating sequence of a SAR ADC can be summarised as follows:

1. Bit‑by‑bit successive approximation The SAR ADC performs analog‑to‑digital conversion using a successive‑approximation algorithm. It starts from the Most Significant Bit (MSB), sets this bit to logic‑1, then converts this digital setting to an analog voltage via its internal DAC.

2. Comparator comparison The generated analog voltage is compared with the incoming analog input signal. If the DAC‑generated voltage is higher than the input signal, the SAR clears this bit; if lower, the bit remains set to 1.

3. Continue successive‑approximation process This procedure repeats for every bit position, determining each bit value sequentially until all bits are resolved.

4. Final output After completing bit‑by‑bit successive approximation, the resulting digital value represents the digitised version of the original analog‑input signal.

The DAC unit continuously generates different reference voltages and compares them against the input signal to resolve the digital representation of the input. Therefore, DAC precision and linearity are critical metrics for overall SAR‑ADC performance. Inside the RP2040 ADC, this DAC is fully integrated on‑chip; no external DAC chip is required for analog‑to‑digital conversion.

The SAR ADC (Successive‑Approximation Register Analog‑to‑Digital Converter) combines digital‑controller logic and analog circuitry. It requires a 48 MHz clock (`clk_adc`), which can be sourced from the USB PLL (Phase‑Locked Loop). One sample conversion takes 96 clock cycles: (96 × 1/48 MHz) = 2 µs, corresponding to the 500 ksps maximum sampling rate. The clock must be properly configured before enabling the ADC.

![6.png](http://openwrite.cn/uploads/21597/64045/6fe1d45a-8ab7-48e9-8385-9e617b911654.png)

Once the ADC module receives its clock and its reset state is released, setting the EN bit inside the CS control register to 1 triggers a brief internal power‑on sequence for the ADC analog hardware. After several clock cycles, the READY bit inside the CS control register goes high to signal that the ADC is ready for its first conversion.

![7.png](http://openwrite.cn/uploads/21597/64045/87f4da80-b5ee-47fb-81c7-d03516c475b9.png)

The ADC can be disabled at any time by clearing the EN bit in the CS control register to save power. Note that ADC inputs are capacitive with an on‑chip 1 pF capacitor. At 500 ksps sampling rate its effective input impedance exceeds 100 kΩ. Buffers are generally not required for DC‑voltage measurements.

1. ADC Operating Modes

RP2040 ADC supports two operating modes:

One‑shot sampling mode Suitable for on‑demand one‑time analog‑to‑digital conversion events. After triggering a conversion, the ADC completes sampling within 96 clock cycles and returns the result.

Free‑running sampling mode Designed for continuous sampling scenarios such as real‑time data acquisition. After finishing one conversion, the ADC automatically starts the next conversion unless explicit delays are configured.

2.1 One‑shot sampling mode

Under one‑shot mode, writing bit `CS.START_ONCE` to 1 immediately launches a new analog‑to‑digital conversion. When conversion starts, bit `CS.READY` goes low to indicate conversion‑in‑progress. After 96 `clk_adc` clock cycles, `CS.READY` returns high signalling conversion completion.

![8.png](http://openwrite.cn/uploads/21597/64045/d8a0ae8c-79aa-4ad5-aa46-a49ca2ab3925.png)

After conversion completes, the 12‑bit conversion result is stored inside the `RESULT` register.

Prior to starting conversion, select the target ADC input channel by writing to `CS.AINSEL`. Values 0‑3 select ADC input channels mapped to GPIO 26‑29 respectively; value 4 selects the internal on‑chip temperature sensor.

![10.png](http://openwrite.cn/uploads/21597/64045/ef46a2e2-663d-4078-9fea-27a3d6445dfe.png)

Note: No settling‑time wait is required when switching the `AINSEL` value. Input channels can be arbitrarily switched just before conversion starts without adversely affecting conversion results.

2.2 Free‑running sampling mode

In free‑running sampling mode, setting bit `CS.START_MANY` causes the ADC to automatically initiate new conversions at fixed intervals. The most recent conversion result is always held inside the `RESULT` register. However, when sampled data will be transported using interrupts (IRQ) or DMA, the ADC FIFO must be enabled.

Sampling rate is controlled by configuring the `DIV.INT` and `DIV.FRAC` fields within the DIV divider register.

With default setting (`DIV = 0`), a new conversion begins immediately after the previous conversion finishes, generating one sample every 96 clock cycles. With a 48 MHz clock this yields a sampling rate of 500 ksps.

When `DIV.INT` is set to a positive integer n, new conversions are triggered every n + 1 clock cycles. Triggers are ignored if a conversion is already running, so n should normally be greater‑or‑equal to 96. As an example, setting `DIV.INT` = 47999 with a 48 MHz clock results in a 1 ksps sampling rate.

The timer supports fractional‑value frequency division. When `DIV.FRAC` is non‑zero, new conversions start on average every `1 + INT + FRAC/256` clock cycles. This is achieved by alternating sampling intervals between `INT+1` and `INT+2` clock cycles.

1. Multi‑input sampling

Multi‑input sampling mode is activated by configuring the `RROBIN` bit‑field inside the CS register. This allows the ADC to automatically switch between different input channels and perform round‑robin sampling under free‑running mode without manual intervention.

Setting a particular bit within `CS.RROBIN` to 1 enables automatic sampling for the corresponding input channel. Multiple bits set to 1 will make the ADC sample those channels in sequence. If all bits inside `CS.RROBIN` are zero, round‑robin sampling is disabled and the ADC continuously samples only the channel selected by `CS.AINSEL`.

Even if the initial `AINSEL` value is not among channels enabled inside `RROBIN`, the ADC starts from that current channel and then cycles through channels specified in `RROBIN`. For instance: initial `AINSEL` = 0 and `RROBIN` = 0x06 (bits 1 and 2 set). The sampling‑channel sequence becomes:

1. Channel 0

2. Channel 1

3. Channel 2

4. Channel 1

5. Channel 2

6. Channel 1 …

This round‑robin sequence repeats continuously until `CS.RROBIN` is disabled.

1. Sample‑receive FIFO

Inside the RP2040 ADC module, conversion results can either be read directly from the `RESULT` register or written into a local receive FIFO buffer, which is read out via the `FIFO` register.

FIFO behaviour is controlled through the `FCS` FIFO‑control register.

Definitions for each flag bit:

4.1 FIFO enable and readout

When bit `FCS.EN` is set to 1, every ADC conversion result gets written into the FIFO. Two consumption methods are available:

‑ Software polls status bits inside the FCS register and reads samples once new data becomes available. ‑ Use interrupts or DMA: read samples from FIFO upon receiving ADC IRQ interrupt or DREQ DMA‑request signals.

4.2 FIFO overflow

When the FIFO is full and another new conversion result arrives, the `FCS.OVER` error flag bit is asserted. Existing FIFO data is not overwritten; however the newly‑arrived conversion sample is discarded.

4.3 FIFO data‑write formatting

Two bit‑fields inside the FCS register govern data format written to the FIFO:

`FCS.SHIFT` bit: when set to 1, FIFO data is right‑shifted by 4 bits (bits 7:0 of FIFO correspond to bits 11:4 of conversion result). This facilitates 8‑bit DMA transfers into byte‑wide memory buffers for larger capture buffers at the cost of reduced measurement precision.

`FCS.ERR` bit: when set to 1, the ERR flag bit for each FIFO entry is asserted, signalling a conversion error. In such cases software should either use the next sample or increase conversion time duration.

Important note: Even when FIFO data is bit‑shifted, the `FIFO.ERR` flag retains its original bit‑position and correctly indicates conversion‑error status for each individual sample regardless of shifting operations.

These errors indicate that bit‑comparison operations could not complete within the allowed conversion window. This is commonly caused by comparator metastability, which occurs when the analog‑input signal voltage lies very close to comparator threshold levels and requires longer conversion time.

4.4 FIFO combined with DMA usage

The RP2040 DMA controller fetches ADC samples by reading the ADC sample FIFO register, controlled by the `ADC_DREQ` system data‑request signal. Key points for DMA‑driven ADC data transfers:

1. Enable FIFO (`FCS.EN`): The FIFO must be enabled so ADC conversion results are written into it. By default the FIFO stays disabled to prevent unintended FIFO filling during one‑shot conversions.

2. Enable ADC DMA request (`FCS.DREQ_EN`): The ADC DREQ signal must be enabled so DMA can perform FIFO reads triggered by ADC data‑request events.

3. Select `DREQ_ADC` as the DMA‑channel data‑request source: The used DMA channel must select `DREQ_ADC` as its trigger source for proper synchronisation with ADC events.

4. Set DREQ assertion threshold (`FCS.THRESH`): Set threshold value to 1 so DMA starts transferring as soon as one sample is present inside FIFO. Note that this value also controls IRQ assertion threshold; higher threshold values may be preferred for non‑DMA use‑cases to reduce interrupt frequency.

5. Configuration for 8‑bit DMA transfers: If DMA transfer width is configured for 8‑bit (transferring into byte arrays in memory), `FCS.SHIFT` must be enabled to pre‑right‑shift samples into byte‑sized values.

6. Multi‑channel sampling setup: When sampling multiple input channels, configure the 5‑bit mask inside `CS.RROBIN` (covering four external input channels plus temperature‑sensor channel). Also set `CS.AINSEL` to select the very first channel for sampling sequence.

7. Configure ADC sampling rate: Complete ADC sampling‑rate configuration before starting ADC conversions.

After finishing ADC configuration, start the DMA channel first, then trigger ADC conversions by setting the `CS.START_MANY` bit. Once DMA completes, you may stop the ADC or immediately launch a new DMA transfer. After clearing `CS.START_MANY` bit to halt the ADC, software must poll `CS.READY` bit to confirm completion of the final conversion and flush any leftover samples held within FIFO.

4.5 FIFO combined with interrupt usage

Interrupts can be generated whenever sample count stored inside FIFO reaches configurable threshold value `FCS.THRESH`. Interrupt generation must first be enabled via the `FIFO` bit‑field within the `INTE` register.

Interrupt status can be read from the `INTS` register. Interrupt condition clears when FIFO sample count drops below threshold value defined by `FCS.THRESH`.

![18.png](http://openwrite.cn/uploads/21597/64045/df260ac5-3ed7-48d9-914e-9a8eb2afff1d.png)

![19.png](http://openwrite.cn/uploads/21597/64045/e0f5c76d-5cff-48fe-99ed-d5716957abf3.png)

ADC interrupts can be manually forced by writing corresponding bits inside `INTF` register to 1, without waiting for FIFO sample‑count threshold conditions.

![20.png](http://openwrite.cn/uploads/21597/64045/ec001ce1-f784-42c2-8b3c-3ccf0f20ffd9.png)

Interrupt masking status and forced‑interrupt events can be inspected through the `INTS` register.

![21.png](http://openwrite.cn/uploads/21597/64045/521f534e-5d8b-41f0-b55f-9ce882777cf3.png)

1. ADC effective precision

The RP2040 datasheet documents ADC‑precision characterisation tests, measuring parameters including ENOB (Effective Number of Bits), INL (Integral Non‑Linearity) and DNL (Differential Non‑Linearity). Detailed interpretation is omitted here; readers may refer to official documentation for full details.

1. On‑chip temperature sensor

The RP2040 on‑chip temperature sensor measures temperature by reading base‑emitter voltage Vbe of a biased bipolar diode. This sensor is connected to ADC channel 5 (`AINSEL` = 4). Typically Vbe equals approximately 0.706 V at 27 °C. Temperature‑to‑voltage relationship formula: `T = 27 - (ADC_voltage - 0.706) / 0.001721`

Where ADC_voltage is the measured base‑emitter voltage. Vbe decreases by roughly 1.721 mV for every 1 °C temperature increase.

Note: The temperature‑sensor reading is highly sensitive to reference‑voltage errors. For example, a 1 % drop in reference voltage (3.3 V → 3.267 V) shifts the temperature reading corresponding to ADC value 891 down to 24.3 °C. Merely 1 % reference‑voltage deviation yields more than 4 °C measurement error. Therefore for improved temperature‑sensor accuracy usage of an external precision voltage reference is recommended.

Before using the temperature sensor, enable its bias‑power supply by setting bit `CS.TS_EN`. This adds roughly 40 µA current draw on the `ADC_AVDD` power rail.

RP2040 built‑in temperature sensor is suitable for basic temperature monitoring applications. For high‑precision scenarios reference‑voltage stability must be guaranteed and calibration may be required to compensate for Vbe offset and Vbe temperature‑slope variations.

---

Source: https://maker.wiznet.io/ruilixin6/projects/raspberry-pi-pico-adc-explained-hardware-modes-registers-common-pitfalls/
