Skip to content

sluebbert/esp32-adc-calibrate

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This repository consists of code for generating a lookup table (LUT) to be used for correcting ADC non-linearity issue. An example is also given on how to apply the LUT in your program.

The code is based on original work from Helmut Weber that he first described at ESP32 discussion forum, but modified with bug-fixed by me.

ESP32 Linearity issue

To address the ESP32 ADC non-linear issue, a lookup table is used to correct the non-linearity. You may need to generate your own lookup table as it varies from device to device due to the variation of ESP32 internal reference voltage.

ESP32 ADC linearity

Things need to know before using LUT

It is recommended to read the ESP32 Analog to Digital Converter before using the LUT approach for solving the ESP32 linearity issue. According to documentation, ESP32 chips(ESP32-D0WD and ESP32-D0WDQ6) that manufactured after 1st week of 2018 have been individual measurement and burned with the eFuse Vref value on to the chip. The eFuse Vref can be read using the function call read_efuse_vref(void) which you can find the source code at esp_adc_cal.c.

There is a function calculate_voltage_linear() in the same library which uses a polynomial formula to correct the linearity.

It is your choice on whether you want to implement the polynomial fitting method or LUT method to address your ESP32 ADC linearity problem. The LUT take up a lot of memory (which is not a big issue for ESP32) but it is faster and more accurate than the polynomial fitting approach.

How to generate the LUT?

This program use the ESP32 DAC to generate a value as the reference and feed it into the ADC for calibration. Remember to use a short jumper wire to connect DAC output(GPIO 25) to ADC Channel 1 ADC7(GPIO 35) on your ESP32.

By default, the program will generate a float ADC_LUT which take up much more memory but with better precision, if you want to have an int ADC_LUT table, comment out the line #define FLOAT_LUT to get the integer table.

  1. Connect a jumper wire between GPIO 25 and GPIO 35 (i.e. A7);
  2. decide on what table (float or integer) you'd want to generate;
  3. Start the main.cpp sketch from PlatformIO or Arduino IDE;
  4. When the program stops, copy and paste the entire table from Serial Monitor to your sketch to use it.

How to use the LUT?

Refer to the sketch in example directory on how to apply the LUT in your program. Run the sketch and see the result on Serial Plotter.

Here is the results between raw reading from ESP32 ADC against the calibrated reading with LUT.

rawReading versus calbratedReading

and here is the DAC output against calibrated ADC reading.

DAC output versus ADC calbratedReading

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 100.0%