Measuring floating pin voltage (ADC from just the built-in comparator)
evanh
Posts: 16,039
I've recently explored a soft start for audio output that doesn't "pop" on first use - https://forums.parallax.com/discussion/comment/1535297/#Comment_1535297
One thing that came out of this was that I found a useful reason to, using the internal comparator hardware, implement a SAR mode ADC - https://en.wikipedia.org/wiki/Successive-approximation_ADC - rather than using the dedicated sigma-delta ADC. The dedicated ADC hardware isn't suited to measuring a floating pin since the frontend hardware will always pull the pin voltage to VIO/2.
It's far from a performance ADC - doesn't have the sample and hold circuit and the comparator's R2R DAC is quite slow - but works perfectly for a low-res static level check like I needed.
pub sar_reading( pinnum ) : level | mask ' This routine makes use of the comparator's unloaded inputs ' to measure the floating voltage of the pin. ' Returns an unsigned 8-bit value in "level", GIO to VIO volts ' mask := 128 level := 0 pinf( pinnum ) repeat wrpin( pinnum, P_LEVEL_A | ((level | mask) << 8) ) ' set comparator DAC level waitus(2) ' DAC settle time about 1.0 us if pinr( pinnum ) ' pin voltage higher than comparator's DAC level |= mask mask >>= 1 while mask wrpin( pinnum, 0 )
Comments
Another way to write the same procedure: