MicroPython unstable ADC readings +/- 5% between reads



  • Using Arduino, readings were stable, but with Micropython & UIFlow, the ADC is unaccurate with variations up to +/- 5% between each adc0.read()

    Also, when M5Stack is alone, not a single pin connected, I see occasional jumps to raw 150 or more (max 4095) instead of expected steady 0.

    Did you experience similar behaviour ?
    How can we fix this ?

    Context
    M5Stack Core1 + uiflow
    Reading voltage drop by a water pressure sensor with 4-20mA through a 147 Ohms resistance. Power is 24V switching power supply, I added a 4700µF capacitor on the PSU. Reading every 1s.

    Code slice (uiflow)

    adc0 = machine.ADC(35)
    # Maximum attenuation for 0.17 to 3.10V Range
    adc0.atten(machine.ADC.ATTN_11DB)
    
    while True:
      adc_raw = adc0.read()
      label_adcraw.setText(str(adc_raw))
      # Just for info
      # Converts the raw value to the range of the sensor (0-300cm water column pressure)
      # Values adjusted after some testing.
      height = int((((adc_raw - 530) / (3600 - 530)) * 300))
      label_height.setText(str(height))
      wait_ms(1000)
    

    Probably irrelevant details

    • TL-136 Liquid Level Sensor Detector Liquid Level Transmitter 24VDC 4-20mA Signal Output
    • Using independant PSU for the sensor and the M5Stack Core1
    • Using pin 35 for ADC


  • Replying to myself.

    The solution is to read many times, and take the mean.

    8000 reads takes about 31.7s with the default 2ms pause at the end of the UIFlow script, which is good enough for me. (Water level sensor). So I have a value published on mqtt twice/minute.
    From 1000 reads, I get a good accuracy / measures stability.
    Over 4000 reads, there's no visible improvement. I do not have more than 0.25% between 2 measures.

    Some tips & links for other people interested in this kind of sensor reading or ADC :

    François



  • There are lots of ways to filter this type of data. The mean is one but you can also use median or an FIR filter. Take a look 🤗

    Fábio Dias