 ### Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

• I'm trying to measure the voltage of a 16v DC supply by applying it to an analog pin via a 100k/4k7 voltage divider. My multimeter shows the pin sitting at exactly 721mV. But when I run

``````import time, machine
for i in range(9): val=adc.channel(pin='P20'); v=val.voltage(); print(v, ' ', end='')
``````

I'm seeing 10mV of variation

``````693  691  701  692  702  701  691  700  701  >
``````

Averaging

``````import time, machine
for i in range(10):
Vav=0
for i in range(10): val=adc.channel(pin='P20'); v=val.voltage(); Vav+=v
print(Vav/10, ' ', end='')
``````

helps

``````694.1  696.2  695.7  694.6  693.5  695.4  695.5  692.6  694.6  694.4  >
``````

but still 3.5mV (0.5%) variation. I really need 3 significant figures for this, what am I missing?

• @kjm So you are averaging over 1000 values. You can also use a low pass filter, which is a little bit simpler
https://github.com/bboser/IoT49
and especially
https://github.com/bboser/IoT49/blob/master/doc/analog_io.md
which shows a noise of about 25 LSB. So your averaging of 1024 values (25*25=625) matches that. B.t.w: good ADCs have a noise <= 1 LSB.

• I couldn't get any improvement with a 100nF ceramic across the 4k7 but did better with brutish code

``````import time, machine
for i in range(8):
Vav2=0
for i in range(128):
Vav1=0
for i in range(128): val=adc.channel(pin='P20'); v=val.value(); Vav1+=v
av=Vav1/128#; print(av, ' ', end='')
Vav2+=av
x=Vav2/128; print('%.0f' % x, '  ', end='')
``````
``````
2687   2687   2687   2687   2687   2688   2687   2687   >
``````

• @kjm You miss nothing. The ADC of the ESP32 is bad. It helps a little bit, if you add a low impedance capacitor (e.g. 10 nF Ceramic) with short leads as close as possible to the ADC input you are using.
Besides that: If you need low noise, good precision and linearity, use an external ADC.

Note: You do not have to re-init the channel in the loop all the time.