Fix non-linear ADC

rin67630
Posts: 141
Joined: Sun Mar 11, 2018 5:13 pm

Fix non-linear ADC

Postby rin67630 » Sun Mar 07, 2021 10:08 am

The ADC of the ESP32 has a – fully justified – bad reputation.

- The advertised 12 bits are practically 9 bit +3 bit noise.
- The V/ADC relation is not linear
- The first 0.21V of the input (by 11dB attenuation) are ignored

I am proposing here a solution to get an acceptable result despite of all that drawbacks.

1) usefull settings:

Code: Select all

  // Settings for ADC
  analogSetWidth(11);               // 11Bit resolution
  analogSetAttenuation(ADC_0db);
11 bit or 10 bit is much more realistic
It is the attenuator that is non-linear, the best is to switch it off and to use a resistor divider.

2) oversampling and filtering

Code: Select all

   
   A0Raw = A3Raw = 0;
  for  (byte n = 0; n < 5; n++)
  {
    A0Raw += analogRead(A0);
    delay (2);
  }
  A0Raw = A0Raw / 5;
  A0Raw = constrain( A0Raw,lastA0-3,lastA0+3);  // eliminate spikes
  lastA0 = A0Raw;
  dashboard.Vout +=  (adc2volt(A0Raw) - dashboard.Vout) / 8 ;  // 1rst order low pass filter 
3) input circuitry:

Image

-Use a resistive voltage divider and a decoupling capacitor c2 to stabilize the input to the ADC.
as well as
-Feed a minimal voltage supplement of ~0.07V into the ADC to get rid if the ADC offset:
In my circuit I am sourcing the feed from 5V, (which has for me the best stability) eliminating potential ripple through R4,C1 and injecting a small residual current into the ADC through R3
Shouldn't you have a stable 5V, you might use 3,3V as well, in that case the value of R3 is 390K instead of 560K.
Without any input you should measure ~ 0.07V at the input of the ADC, just enough to pull the input slightly above the offset.

4) final adjustment:

Code: Select all

float adc2volt(unsigned int adc)
{
  float volt = map(adc, ADC_0V, 2047, 0, VOLT_MAX);
  volt = volt / 1000;
  return volt;
}
Whereas "ADC_0V" is the value of the ADC without any input and VOLT_MAX the voltage when the ADC shows 2047-

Using all these methods I could get a precision of 2% over the full range of measurements.

Enjoy!

ESP_Minatel
Posts: 364
Joined: Mon Jan 04, 2021 2:06 pm

Re: Fix non-linear ADC

Postby ESP_Minatel » Tue May 18, 2021 9:19 am

Thank you for sharing!

Have you already tested the ESP32-S2 ADC?

impishbynature
Posts: 4
Joined: Thu May 20, 2021 7:14 am

Re: Fix non-linear ADC

Postby impishbynature » Thu May 20, 2021 7:19 am

return -0.000000000000016 * pow(reading,4) + 0.000000000118171 * pow(reading,3)- 0.000000301211691 * pow(reading,2)+ 0.001109019271794 * reading + 0.034143524634089;

from

https://github.com/G6EJD/ESP32-ADC-Accu ... t-function



better than 1% for the full range

mrburnette
Posts: 22
Joined: Mon Feb 12, 2018 6:50 pm

Re: Fix non-linear ADC

Postby mrburnette » Tue May 25, 2021 5:18 pm

ALL uC's have similar documentation:
https://docs.espressif.com/projects/esp ... s/adc.html

The ADC is essentially "free" and satisfactory for Arduino projects.

Who is online

Users browsing this forum: Google [Bot] and 51 guests