Page 1 of 1

Pico ADC misbehavior

Posted: Thu Jan 20, 2022 3:01 am
by fmr300
If you don't give the ADC a 'rest', it misbehaves ! Try this code:

Code: Select all

import machine, time
adc = machine.ADC(27)

while True:
    t1 = adc.read_u16() >> 4
    print (t1)
What you'll see, and I've tested 4 Pico's to see that it's consistent, is that whatever the ADC conversion value is at startup, is approximately what you will always get, no matter how you change the voltage on pin-27. I say 'approximately' because the value does actually change, but by only a couple counts up and down.... ie, it's not some latched value....

Now put a 'time.sleep_ms(10)' statement after the 'print' and re-run. Now the conversion value varies with the voltage, consistently.

I've been playing with Pico's for a couple weeks now, and have found numerous odd issues like this, although most of the others had to do with multi-threading on Pico. It's enough to drive a person to 'C' or the ESP32 !!

If anybody has idea what's going on here, love to hear your thoughts.

Re: Pico ADC misbehavior

Posted: Fri Jan 28, 2022 5:25 pm
by Shards
What you are seeing is pretty much what I'd expect. ADC conversions aren't instantaneous and what is probably happening is that you are asking for a new conversion before the current one has completed so the register holding the current ADC value is never updated.

If you really need very fast conversions you'll need to see how low you can take that time delay. At the processor level you can almost certainly generate an interrupt when ADC conversion is complete but you'd need C or assembly code to access that. And dedicate one pico core to the task if you need to do anything else.

Re: Pico ADC misbehavior

Posted: Fri Jan 28, 2022 6:36 pm
by davef
What happens if you:

Code: Select all

import machine, utime
adc = machine.ADC(27)

while True:
    t1 = adc.read_u16() >> 4
    utime.sleep(1)
    print (t1)
If this still doesn't work it would suggest to me that is a print "problem". I would be surprised that their isn't a "conversion is complete" flag in the driver. There was a recent thread about a similar issue.

Re: Pico ADC misbehavior

Posted: Sat Feb 05, 2022 11:42 am
by fivdi
When read_u16 is called from MicroPython on a Pico, MicroPython internally calls adc_read in the Pico SDK.

adc_read in the Pico SDK performs the following steps:
  • It immediately starts a new conversion
  • It waits for the conversion to complete
  • It returns the 12-bit conversion result
I would imagine that the problem described above is occurring because the circuit is designed in a way that results in the capacitive ADC input requiring a long time to charge. Adding the 10ms delay is giving the capacitor the time it needs to charge.

Re: Pico ADC misbehavior

Posted: Sat Feb 05, 2022 6:31 pm
by davef
If you measuring a DC voltage or slowly varying DC voltage try a 100nF or 1uF on the ADC input to ground.

Re: Pico ADC misbehavior

Posted: Sat Feb 12, 2022 4:45 pm
by dakotadev
davef wrote:
Sat Feb 05, 2022 6:31 pm
If you measuring a DC voltage or slowly varying DC voltage try a 100nF or 1uF on the ADC input to ground.
I wasn't exactly having OP's problem - I was seeing crazy jumps in analog readings on my pico. I thought the only solution was getting a precision voltage-reference input into ADC_VREF, but the coupling the analog input to ground with 1 uF made a huge improvement. Thanks!