RobotLabs
  • Welcome
  • ESP32
    • PlatformIO
      • 1.1 Arduino Basics
      • 1.2 Install PlatformIO
      • 2.1 GPIO - LED Blink
      • 2.2 GPIO - LED Multi
      • 2.3 GPIO - LED Button
      • 3.1 PWM - LED Fade
      • 3.2 ADC - Analog Input
      • 4.1 IIC - OLED
    • MicroPython
    • ESP32 Projects
  • ROS
    • ROS2 Jazzy
      • 1.1 Install ROS 2 Jazzy
      • 1.2 Install VS Code
      • 1.3 Save ROS code on GitHub
      • 2.1 Create a Mobile Robot with URDF and Visualize it
      • 2.3 Create Launch Files to Display the URDF in RViz
      • 2.4 Simulation with Gazebo
      • 2.5 Gazebo sensors
      • 2.6 Sensor fusion and SLAM
    • MoveIt2
      • Moveit 2 joint position control with keyboard
      • Moveit2 joint velocity control for Panda robot arm
    • Perception
      • PCL-ROS
  • FOC
    • SimpleFOC
      • Install simpleFOC Lib
  • Template
    • Markdown
    • Interactive blocks
    • OpenAPI
    • Integrations
Powered by GitBook
On this page
  • Introduction
  • Hardware Circuit
  • 1. Parts Required
  • 2. Wiring
  • Coding and Testing
  • 1. Functions for ESP32 ADC
  • 2. Read Analog value using ESP32
  • 3. Change LED brightness
  • 4. Using ADC analog channel input
  • Summary
  1. ESP32
  2. PlatformIO

3.2 ADC - Analog Input

Previous3.1 PWM - LED FadeNext4.1 IIC - OLED

Last updated 3 months ago

Earlier, we introduced the PWM to output different voltage values like analog signal output. What if ESP32 needs to detect external analog input signals? This is the ADC that we will learn in this lesson. The ADC converts the analog signal into a digital signal for ESP32 to process.

Introduction

Analog signals are continuous in time and amplitude, while digital signals are discrete in time and amplitude. Analog circuits are circuits that use and process analog signals; digital circuits are circuits that use and process digital signals.

  • Many sensors' output is analog. To interface it with MCU, we need to convert it into a digital signal.

  • ADC (Analog to Digital converter) is used to converts an analog signal into digital, so it can be processed by the microcontroller.

  • ADC is used in many IoT applications like Biometric applications, Sensor monitoring, Gas leakage detection, etc.

ADC (Analog to Digital Converter) is an analog-to-digital converter that can convert analog signals into digital signals. Since the microcontroller can only recognize binary numbers, external analog signals are often converted into digital signals through ADC first. A common way is to convert changing voltage into digital signals.

ESP32-S3 integrates two 12-bit SAR ADCs and supports measurements on 20 channels (analog-enabled pins), which can be used to read analog signals in the range 0-3.3V. It has a 12-bit ADC means it will give digital values in the range of 0 – 4096 (2^12). This is called resolution which indicates the number of discrete values it can produce over the range of analog values.

Hardware Circuit

1. Parts Required

Here’s a list of the parts to you need to build the circuit:

  • ESP32-S3-N16R8

  • LED

  • 330 - 1k Ohm resistor

  • Potentiometer

  • Breadboard

  • Jumper wires

2. Wiring

Wire a potentiometer to your ESP32. The potentiometer middle pin should be connected to GPIO 9 and LED is connected to GPIO 13. You can use the following schematic diagram as a reference.

Coding and Testing

1. Functions for ESP32 ADC

  • analogRead (pin)

This function is used to read analog values from a specified analog pin.

pin - number of the analog pin which we want to read

returns - digital value 0 – 4095

  • analogReference (type)

This function is used for configuring the reference voltage used for analog input.

2. Read Analog value using ESP32

Let’s write a program to read varying analog values generated by a potentiometer that is connected to the pin_9 analog channel ADC2_8. Display the digital value on the Serial monitor which we got from the ESP32 ADC.

#include <Arduino.h>
// Potentiometer is connected to GPIO 9 (Analog ADC1_CH8) 
const int potPin = 9;

// variable for storing the potentiometer value
int potValue = 0;

void setup() {
  Serial.begin(115200);
  //pinMode(POT, INPUT);
  delay(1000);
}

void loop() {
  // Reading potentiometer value
  potValue = analogRead(potPin);
  Serial.println(potValue);
  delay(500);
}

3. Change LED brightness

We can use analogRead() to read the analog value passed in by the potentiometer, the range is 0 ~ 4023, and the parameter range we want to input to analogWrite() is 0 ~ 255, so we also need to convert the analog value range read into the output range, the code is as follows:

#include <Arduino.h>
#define POT 26
#define LED 13
 
// variable for storing the potentiometer value
int pot_value;
int led_value;
 
void setup() {
    Serial.begin(9600);
    pinMode(POT, INPUT);
    pinMode(LED, OUTPUT);
}
 
void loop() {
    // read potentiometer input value
    pot_value = analogRead(POT);
    // convert analog input value to LED output
    led_value = pot_value / 16;
    analogWrite(LED, led_value);
    delay(50);
}

4. Using ADC analog channel input

There are other more advanced functions to use with the ADC pins that can be useful in other projects After opening the esp32_hal_adc.h file, we can see all the control functions of ADC:

  • analogReadResolution(resolution): set the sample bits and resolution. It can be a value between 9 (0 – 511) and 12 bits (0 – 4095). Default is 12-bit resolution.

  • analogSetWidth(width): set the sample bits and resolution. It can be a value between 9 (0 – 511) and 12 bits (0 – 4095). Default is 12-bit resolution.

  • analogSetCycles(cycles): set the number of cycles per sample. Default is 8. Range: 1 to 255.

  • analogSetSamples(samples): set the number of samples in the range. Default is 1 sample. It has an effect of increasing sensitivity.

  • analogSetClockDiv(attenuation): set the divider for the ADC clock. Default is 1. Range: 1 to 255.

  • analogSetAttenuation(attenuation): sets the input attenuation for all ADC pins. Default is ADC_11db. Accepted values:

    • ADC_0db: sets no attenuation. ADC can measure up to approximately 800 mV (1V input = ADC reading of 1088).

    • ADC_2_5db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. (1V input = ADC reading of 3722).

    • ADC_6db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1350 mV. (1V input = ADC reading of 3033).

    • ADC_11db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 2600 mV. (1V input = ADC reading of 1575).

  • analogSetPinAttenuation(pin, attenuation): sets the input attenuation for the specified pin. The default is ADC_11db. Attenuation values are the same from previous function.

  • adcAttachPin(pin): Attach a pin to ADC (also clears any other analog mode that could be on). Returns TRUE or FALSE result.

  • adcStart(pin), adcBusy(pin) and resultadcEnd(pin): starts an ADC convertion on attached pin’s bus. Check if conversion on the pin’s ADC bus is currently running (returns TRUE or FALSE). Get the result of the conversion: returns 16-bit integer.

Summary

In this example you’ve learned how to read analog inputs using the ESP32-S3 with the PlatformIO IDE.

  • The ESP32-S3 has 20 ADC pins you can use to read analog inputs.

  • These pins have a resolution of 12 bits, which means you can get values from 0 to 4095.

  • To read a value, you simply use the analogRead() function.

  • The ESP32 ADC pins don’t have a linear behavior. You’ll probably won’t be able to distinguish between 0 and 0.1V, or between 3.2 and 3.3V. You need to keep that in mind when using the ADC pins.

Finally, if you want to learn more about other controllers, take a look at our Youtube channel:

RobotLabsYouTube
Logo