What is Input-Referred Noise?

For an ADC, input-referred noise is the noise that is generated by the ADC itself when connected to a noiseless input.

Or stated differently, it’s the output we would see if we fed it with a perfectly flat input.

How do we measure it?

Measuring Input-Referred Noise is relatively straightforward. All you need to do is connect the ADC input to a noiseless voltage source and measure the noise in the output.

However, as you might imagine, there are some nuances. In reality, nothing is noiseless, so we need to identify what noise level is acceptable to not affect your measurment.

In order to add noises you take the RMS of the values, so we can caculate the total noise of the output as:

\[\text{Noise}_\text{Measured} = \sqrt{\text{Noise}_\text{ADC}^2 + \text{Noise}_\text{Source}^2}\]

Because of the RMS adding of noise, if the voltage source has a third of the ADC’s noise, it will only add a 5% error; to get a 1% error, you only need to have a noise voltage of 15% of the ADCs.

The RP2040 has a 12 bit ADC, operating around 3.3V, so that means every LSB has a voltage of $\frac{3.3V}{2^{12}} = 806\mu V$. If our ADC has an input-referred noise of around 1 LSB RMS (spoiler alert: it does!), we need our voltage source to have a noise of less than $269 \mu V$ to get a 5% error.

How can we cheat?

Shorting the ADC to ground is a straightforward way to create a low noise input for converters.

Note: If the ADC has significant DNL or INL issues, this can over or under represent the expected noise, see MT-004 for more discussion.

Test Methodology

The testing was completed with the input shorted to ground. I collected one million data points.

I used the following Micropython code:

import machine

ain0 = machine.ADC(0)

cnt = 0
val_hist = dict()

smps_mode = machine.Pin(23, machine.Pin.OUT)
smps_mode.value(0) # 0 for PSM, 1 for PWM

while True:
    # Convert 16 bit result to native 12 bit result
    raw = ain0.read_u16() >> 4
    # Save ADC value
    val_hist[raw] = val_hist.get(raw, 0) + 1
    # Print results every 100k readings
    cnt += 1
    if cnt == 100000:
        cnt = 0


Power Save Mode

PWM (“Low-Noise”) Mode


Input-Referred Noise

The input-referred noise is (from the data above) 0.974 LSB in Power Save Mode and 1.36 LSB in PWM (“Low-Noise”) Mode. Here we can see that the Low Noise mode has higher noise than the PWM mode. We can use this measurement to calculate several different quantities.

Power Save Mode Input-Referred Noise 0.974 LSB RMS
PWM Mode Input-Referred Noise 1.36 LSB RMS

Noise-Free Resolution

The noise-free (or flicker-free) resolution is the number of bits of the ADC that will be stable when a constant input is applied. Imagine you plotted the output of the ADC on 12 LEDs. The noise-free resolution is the number of LEDs that would appear steady (not flickering or flashing)

We can calculate the number of noise-free bits with the below formula. $\mathrm{N}$ is the number of bits that our ADC has, in our case 12. The 6.6 term converts RMS values to 99.9th percentile Peak-Peak values.

\[\text { Noise Free Code Resolution }=\log _{2}\left(\frac{2^{\mathrm{N}}}{\text { RMS Input Noise (LSBs) } \times 6.6}\right)\]

We can then calculate:

Power Save Mode Noise-Free Resolution 9.3 Bits
PWM Mode Noise-Free Resolution 8.8 Bits

Effective Resolution

The effective resolution is the ratio of the ADC noise in DC conditions. It is similar but not the same as the Effective Number of Bits (ENOB). It is calculated similarly to noise-free resolution. (Removing the 6.6 factor is equivalent to adding $log_2(6.6) \approx 2.7$ bits). ENOB includes errors from many more components, like INL/DNL error, distortion, etc. It is not a very usefull specification.

\[\text { Noise Free Code Resolution }=\log _{2}\left(\frac{2^{\mathrm{N}}}{\text { RMS Input Noise (LSBs) }}\right)\]

We can then calculate:

Power Save Mode Effective Resolution 12.0 Bits
PWM Mode Effective Resolution 11.6 Bits