All data converters have noise from the quantization of the signal: that’s the fact that every input is mapped to the closest single output level (no matter how fine), and the difference between that and the true value of the input is considered noise (this is the Error trace in the graph below).
This noise is (approximately) uniformly distributed over -1/2 to +1/2 LSB, and this noise is (approximately) uniformly distributed over the bandwidth of the ADC. The RMS value of this noise for an ideal ADC is $\frac{1}{\sqrt{12}}$ LSBs.
So, what is the Effective Number of Bits of an ADC? It is the bit width of a ideal ADC whose quantization noise alone has the same RMS value as the total noise of your real ADC.
For example, if you had a 12 bit ADC with an ENOB of 6 bits, that means that your ADC has the same noise level as an ideal 6 bit ADC.
Note, however, that this is only about noise. Having an ENOB of 6 bits does not mean your ADC is equivalent to an ideal 6 bit ADC - linearity errors in particular are not considered by the ENOB.
How do we measure it?
Measuring the ENOB is deceptively simple. We measure a perfect full-scale sine wave with our ADC, subtract the sine wave, and measure the RMS value of the resulting noise. Then we determine the bit width of an ideal ADC with the same RMS noise: this is our ENOB.
Note: This is the same as Total Harmonic Distortion and Noise (THD+N). However, THD+N is usually specified over a smaller frequency range than the full bandwidth of the ADC.
How perfect does perfect need to be?
We want the noise contribution of our sine wave to be a small fraction of our ADC’s quantization noise. We can calculate the ideal quantization noise of the Raspberry Pi Pico ADC as $\frac{1/ \sqrt{12}}{2^{12}} = 0.007\%$. And the sum of two (uncorrelated) noise sources is
which means we need to feed in a sine wave that has $1/3$ the noise to get less than a 5% contribution. However, this is a tall order, requiring a THD of better than -90dBc. But that can be relaxed - the specified ENOB of the Pico is only 9.5 Bits (9 Bits minimum), that means we only need to keep our source’s noise below $\left(\frac{1}{3}\right)\frac{1/ \sqrt{12}}{2^9} = 0.02\%$ (-75dBc THD+N) to accurately measure the Pico’s ADC.
Test Methodology
A 1kHz sine wave was generated with a SG505 function generator. It has a THD+N of -102 dB more than enough.
The following code was used to sample the ADC at it’s full rate then dump the samples out the USB serial interface:
Note: This code uses DMA to sample the ADC at the full 500 kSps, then print out the sample buffer over the serial port; it’s based on the ADC Console and ADC DMA samples from the Pico SDK.
Analysis
The data was captured to a file, then a sine wave was fitted to the data, and subtracted from the data, and finally the RMS value of the difference was calculated.