How to use ADC of ESP32 – Measuring voltage example

How to use analog to digital converter module of ESP32 development board and How to measure analog voltage with ESP32 ADC channels. ESP32 board has two 12 bit analog to digital converters.  The type of ADCs used in this development board is SAR based which is also known as successive approximation registers. To know more about types of ADC’s, check this analog to digital converter tutorial.  Both these ADCs supports up to 18 analog channels which means we can connect eighteen analog sensors at a time with this board. But ADC2 is shared between other resources of this development board.  So we have two ADCs in ESP32 ADC1 and ADC2.  Pin mapping of ADC channels for both ADCs is shown below.

pin mapping of ESP32 ADC1

Following is a pin mapping of with ESP32 devkit DOIT board. Although ESP32 chip ADC1 has eight channels, Devkit DOIT board supports only 6 channels. But still, we have enough analog channels for analog sensor interfacing.

  • ADC1_CH0 >>>GPIO36
  • ADC1_CH1 >>>Not available on this board Devkit DoIT ( 30 pins version )
  • ADC1_CH2 >>> NA
  • ADC1_CH3 >>>GPIO39
  • ADC1_CH6 >>>GPIO34
  • ADC1_CH7 >>> GPIO35
  • ADC1_CH4 >>> GPIO32
  • ADC1_CH5 >>> GPIO33

pin mapping of ESP32 ADC2

Pin mapping for ADC2 channel is given below. Devkit DOIT board ADC2 supports 10 analog channels and all these analog channels are available on Devkit do it board.

  • ADC2_CH0 >>>GPIO0
  • ADC2_CH1 >>> This channel is not available on Devkit DOIT board
  • ADC2_CH2 >>>GPIO2
  • ADC2_CH3 >>> GPIO15
  • ADC2_CH4 >>> GPIO13
  • ADC2_CH5 >>> GPIO12
  • ADC2_CH6 >>>GPIO14
  • ADC2_CH7 >>> GPIO27
  • ADC2_CH8 >>> GPIO25
  • ADC2_CH9 >>> GPIO26

Although we have 10 analog channels available in ADC2, all these channels are shared among other resources. For example, ADC2 is shared with WiFi drivers, therefore you can only use it after WiFi drivers are not started. You have to make your program smart enough to switch between two resources. The easy way is to turn off the WiFi driver when you want to use ADC2 and read the analog value and after that turn on the WiFi driver when you want to update value to the server etc. I will explain more about it in later parts of this series of tutorials. The figure below shows the pins of analog channels on Devkit DOIT:

ESP32 ADC channels pinout

How to use Analog to digital converter channels of ESP32

So now let’s see how to write code or program for reading ADC values of with any of these 15 channels available on this board. After that, we will see an example, where we connect a variable resistor with the analog channel and measure voltage and display it on serial monitor of Arduino IDE. ESP32 analog channels are of 12 bit which means the minimum step of each voltage level is between 0 and 4095. Analog channel produces a digital value between 0 and 4095 according to the voltage at the input of the analog channel. For example

  • If the voltage is 0 at the input of the analog channel, the digital value will be zero.
  • If the voltage is 3.3 volt at the input, the digital value will be 4095. So the maximum voltage limit is 3.3 volt.
  • But we can measure higher voltage else by using voltage step down methods like voltage divider method, step down transformer method in case of ac voltage measurement.

You may like to check our previous project on high voltage measurement with other microcontrollers. Although a different microcontroller is used in these projects, you can apply the same concepts to ESP32 ADC for measurement of current, voltage, power factor and ac power.

One main disadvantage of ESP32 ADC is that it has a non linear behavior. Graph below shows its non-linear curve. you can find more information about it on this link.

ESP32 adc curve non linear

Program for ESP32 Analog to digital converter

So we are using Arduino IDE in these tutorials.  Arduino IDE provides built in function to read analog values that is analogRead function.

  • analogRead(analog_pin_number) : We will use this function to read analog value. This analogRead function has only one argument which is a pin number of the analog channel you want to use. I have already provided pin mapping of all analog channels with GPIO pins above. So you will only pass the name of GPIO pin to this function like analogRead(36), it will read the value from ADC1 channel zero. Figure above also shows the pin number and respective analog channels.
  • You just need to store the output of this function in any variable other than character types. Because character type variable can store values between 0 and 255 only.

If you are just getting start with ESP32 programming, check these earlier tutorials:

Now make this circuit diagram on your bread board and after that, we will write a code to measure voltage using a variable resistor.

measure analog voltage ESP32

In the above circuit diagram, a variable resistor is used. one terminal of the variable resistor is connected with ground and other terminal with 3.3 volt. Center terminal of the variable resistor is connected with GPIO15 which is ADC2 channel three or ADC2_CH3.

Code for analog voltage measurement using ESP32 ADC

Code for analog voltage measurement is shown below. All the functions used in this code have already explained in the previous tutorial and in this tutorial except serial.begin() and serial.println() functions.

const int Analog_channel_pin= 15;
int ADC_VALUE = 0;
int voltage_value = 0; 
void setup() 
{
Serial.begin(115200);
}
void loop() 
{
ADC_VALUE = analogRead(Analog_channel_pin);
Serial.print("ADC VALUE = ");
Serial.println(ADC_VALUE);
delay(1000);
voltage_value = (ADC_VALUE * 3.3 ) / (4095);
Serial.print("Voltage = ");
Serial.print(voltage_value);
Serial.print("volts");
delay(1000);
}

Now  I will explain the working of code line by line.  In these lines, first we give a name to ADC2_CH3 as Analog_channel_pin and after that, we initialized two integer variables to zero. One variable is used to store digital value and other variable is used to store voltage.

const int Analog_channel_pin= 15;
int ADC_VALUE = 0;
int voltage_value = 0;

In the setup() function, we have serial.begin function is used to initialize serial communication of esp32 and serial communication rate is defined by baud rate. So we have initialized the baud rate of 115200.  Serial communication will be used to send data from ESP32 board to serial monitor of Arduino IDE.

Serial.begin(115200);

Now the main function of this code is a loop part where we are taking an analog input and displaying it on serial monitor of Arduino IDE with the help of these lines.  serial.print function is used to transmit data without a new line at the end and serial.println() function is also used to transmit data but it also includes new line character at the end of the string. After that delay function is used to add a delay of one second. It is not necessary to add delay but we did it check to receive value after every one second.

ADC_VALUE = analogRead(Analog_channel_pin);
Serial.print("ADC VALUE = ");
Serial.println(ADC_VALUE);
delay(1000);

Now in the last part, the first line will convert the digital value of ADC_VALUE into voltage.  ADC_VALUE is multiplied with a resolution of ESP32 ADC which is 3.3 / 4095. Resolution is also know as a minimum step of adc for each corresponding value of voltage. For example, if ADC_VALUE counts 10, its mean it has taken 10 steps or value at the input pin is 10 times the resolution of adc.  So to convert ADC_VALUE back into voltage we simply multiply it with resolution as we done in the first line.  After that Serial.print function sends a string of “voltage = ” and then voltage value and after that unit of voltage is transmitted to the serial monitor.

voltage_value = (ADC_VALUE * 3.3 ) / (4095);
Serial.print("Voltage = ");
Serial.print(voltage_value);
Serial.print("volts");
delay(1000);

So when you run this code on ESP32 board, you will get the value of adc and voltage value after every one second on serial monitor of Arduino IDE. you can also check ESP32 Webserver tutorial.

Leave a Comment

shares