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
|
GPIO Extension Board x1
|
||
Breadboard x1
|
|||
LED x1
|
Resistor 220Ω x1
|
Jumper M/M x5
|
Rotary potentiometer x1
|
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.
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.
Rotary potentiometer
Rotary potentiometer and linear potentiometer have similar function; their only difference is: the resistance is adjusted by rotating the potentiometer.
Circuit
Schematic diagram |
|
Hardware connection |
If you need any support, please contact us via: support@freenove.com
|
Sketch
Sketch_09.1_ADC_DAC
Download the code to ESP32-WROVER, open the serial monitor, and set the baud rate to 115200. As shown in the following figure,
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.








