Chapter 9 AD/DA Converter

We have learned how to control the brightness of LED through PWM and understood that PWM is not the real analog before. In this chapter, we will learn how to read analog, convert it into digital and convert the digital into analog output. That is, ADC and DAC.

Project 9.1 Read the Voltage of Potentiometer

In this project, we will use the ADC function of ESP32 to read the voltage value of potentiometer. And then output the voltage value through the DAC to control the brightness of LED.

Component List

ESP32-WROVER x1

Chapter01_00

GPIO Extension Board x1

Chapter01_01

Breadboard x1

Chapter01_02

LED x1

Chapter01_03

Resistor 220Ω x1

Chapter01_04

Jumper M/M x5

Chapter01_05

Rotary potentiometer x1

Chapter09_00

Component knowledge

Potentiometer

A potentiometer is a three-terminal resistor. Unlike the resistors that we have used thus far in our project which have a fixed resistance value, the resistance value of a potentiometer can be adjusted. A potentiometer is often made up by a resistive substance (a wire or carbon element) and movable contact brush. When the brush moves along the resistor element, there will be a change in the resistance of the potentiometer’s output side (3) (or change in the voltage of the circuit that is a part). The illustration below represents a linear sliding potentiometer and its electronic symbol on the right.

../../../_images/Chapter09_04.png

What between potentiometer pin 1 and pin 2 is the resistor body, and pins 3 is connected to brush. When brush moves from pin 1 to pin 2, the resistance between pin 1 and pin 3 will increase up to body resistance linearly, and the resistance between pin 2 and pin 3 will decrease down to 0 linearly.

In the circuit. The both sides of resistance body are often connected to the positive and negative electrode of the power. When you slide the brush pin 3, you can get a certain voltage in the range of the power supply.

../../../_images/Chapter09_05.png

Rotary potentiometer

Rotary potentiometer and linear potentiometer have similar function; their only difference is: the resistance is adjusted by rotating the potentiometer.

../../../_images/Chapter09_06.png

Circuit

Schematic diagram

Chapter09_07

Hardware connection

If you need any support, please contact us via: support@freenove.com

Chapter09_08

Sketch

Sketch_09.1_ADC_DAC

../../../_images/Chapter09_09.png

Download the code to ESP32-WROVER, open the serial monitor, and set the baud rate to 115200. As shown in the following figure,

../../../_images/Chapter09_10.png

The serial monitor prints ADC values, DAC values, and the output voltage of the potentiometer. In the code, we made the voltage output from the DAC pin equal to the voltage input from the ADC pin. Rotate the handle of the potentiometer and the print will change. When the voltage is greater than 1.6V (voltage needed to turn on red LED), LED starts emitting light. If you continue to increase the output voltage, the LED will become more and more brighter. When the voltage is less than 1.6v, the LED will not light up, because it does not reach the voltage to turn on LED, which indirectly proves the difference between DAC and PWM. (if you have an oscilloscope, you can check the waveform of the DAC output through it.)

The following is the code:

 1/**********************************************************************
 2  Filename    : ADC_DAC
 3  Description : Basic usage of ADC and DAC for esp32.
 4  Auther      : www.freenove.com
 5  Modification: 2024/06/18
 6**********************************************************************/
 7#define PIN_ANALOG_IN  4
 8
 9void setup() {
10  Serial.begin(115200);
11}
12
13void loop() {
14  int adcVal = analogRead(PIN_ANALOG_IN);
15  int dacVal = map(adcVal, 0, 4095, 0, 255);
16  double voltage = adcVal / 4095.0 * 3.3;
17  dacWrite(DAC1, dacVal);
18  Serial.printf("ADC Val: %d, \t DAC Val: %d, \t Voltage: %.2fV\n", adcVal, dacVal, voltage);
19  delay(200);
20}

In loop(), the analogRead() function is used to obtain the ADC value, and then the map() function is used to convert the value into an 8-bit precision DAC value. The function dacWrite() is used to output the value. The input and output voltage are calculated according to the previous formula, and the information is finally printed out.

1int adcVal = analogRead(PIN_ANALOG_IN);
2int dacVal = map(adcVal, 0, 4095, 0, 255);
3double voltage = adcVal / 4095.0 * 3.3;
4dacWrite(DAC1, dacVal);
5Serial.printf("ADC Val: %d, \t DAC Val: %d, \t Voltage: %.2fV\n", adcVal, dacVal, voltage);

Reference

uint16_t analogRead(uint8_t pin);

Reads the value from the specified analog pin. Return the analog reading on the pin. (0-4095 for 12 bits).

void dacWrite(uint8_t pin, uint8_t value);

This writes the given value to the supplied analog pin.

long map(long value,long fromLow,long fromHigh,long toLow,long toHigh);

Re-maps a number from one range to another. That is, a value of fromLow would get mapped to toLow, a value of fromHigh to toHigh, values in-between to values in-between, etc.