Skip to main content

Working with ESP-IDF

This chapter includes the following sections:

ESP-IDF Getting Started

New to ESP32 ESP-IDF development and looking to get started quickly? We have prepared a general Getting Started Tutorial for you.

Please Note: This tutorial uses the ESP32-S3-Zero as a teaching example, and all hardware code is based on its pinout. Before you start, it is recommended that you check the pinout of your development board to ensure the pin configuration is correct.

Setting Up Development Environment

note

The following guide uses Windows as an example, demonstrating development using VS Code + the ESP-IDF extension. macOS and Linux users should refer to the official documentation.

Install the ESP-IDF Development Environment

  1. Download the installation manager from the ESP-IDF Installation Manager page. This is Espressif's latest cross-platform installer. The following steps demonstrate how to use its offline installation feature.

    Click the Offline Installer tab on the page, then select Windows as the operating system and choose your desired version from the filter bar.

    Download EIM and offline package

    After confirming your selection, click the download button. The browser will automatically download two files: the ESP-IDF Offline Package (.zst) and the ESP-IDF Installer (.exe).

    Download EIM and offline package 2

    Please wait for both files to finish downloading.

  2. Once the download is complete, double-click to run the ESP-IDF Installer (eim-gui-windows-x64.exe).

    The installer will automatically detect if the offline package exists in the same directory. Click Install from archive.

    Auto-detect offline package

    Next, select the installation path. We recommend using the default path. If you need to customize it, ensure the path does not contain Chinese characters or spaces. Click Start installation to proceed.

    Select installation path
  3. When you see the following screen, the ESP-IDF installation is successful.

    Installation successful
  4. We recommend installing the drivers as well. Click Finish installation, then select Install driver.

    Install drivers via ESP-IDF Installation Manager

Install Visual Studio Code and the ESP-IDF Extension

  1. Download and install Visual Studio Code.

  2. During installation, it is recommended to check Add "Open with Code" action to Windows Explorer file context menu to facilitate opening project folders quickly.

  3. In VS Code, click the Extensions icon Extensions Icon in the Activity Bar on the side (or use the shortcut Ctrl + Shift + X) to open the Extensions view.

  4. Enter ESP-IDF in the search box, locate the ESP-IDF extension, and click Install.

    Search and install ESP-IDF extension in VS Code

  5. For ESP-IDF extension versions ≥ 2.0, the extension will automatically detect and recognize the ESP-IDF environment installed in the previous steps, requiring no manual configuration.

Performance Optimization Configuration (Menuconfig)

To achieve the best screen refresh rate and LVGL performance under ESP-IDF (for example, reaching an interface frame rate of 41Hz under ESP-IDF v5.3), it is recommended to configure the following options via idf.py menuconfig before compilation:

  • FreeRTOS Tick Rate:
    • CONFIG_FREERTOS_HZ=1000
  • CPU Frequency:
    • CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
  • Flash and PSRAM Optimization:
    • CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
    • CONFIG_ESPTOOLPY_FLASHFREQ_120M=y (Must be consistent with PSRAM)
    • CONFIG_SPIRAM_MODE_OCT=y
    • CONFIG_SPIRAM_SPEED_120M=y (Requires enabling CONFIG_IDF_EXPERIMENTAL_FEATURES)
    • CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
    • CONFIG_SPIRAM_RODATA=y
  • Cache Line Size:
    • CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
  • Compiler Optimization:
    • CONFIG_COMPILER_OPTIMIZATION_PERF=y
  • LVGL Optimization (v8.3+):
    • CONFIG_LV_MEM_CUSTOM=y
    • CONFIG_LV_MEMCPY_MEMSET_STD=y
    • CONFIG_LV_ATTRIBUTE_FAST_MEM=y
warning

If installation fails or a reinstall is needed, try deleting C:\Users\%Username%\esp and C:\Users\%Username%\.espressif before retrying.

Flashing Demo

  1. After installing the ESP-IDF development environment, select the folder to open the example.

    Open folder in VS Code

  2. In the pop-up window, select the example under the ESP-IDF directory within the extracted example package, and click to select a file (here, the 01_I2C_Test folder is used as an example).

    Open file in VS Code

  3. To upload the corresponding code to the ESP32-S3, connect the USB port of the ESP32-S3-Touch-LCD-4.3 to a USB port on your computer using a Type-C to Type-A cable.

  4. If this is the first time flashing a new project, you need to select the detected COM port. For example, here it is detected as COM36.

    Select COM port

  5. Select the download method: UART.

    Select download method

  6. Next, select the main chip as ESP32S3.

    Select main chip

    Select the path for openocd. This does not affect our process, so we can choose any option. Here, select the first one.

    Select openocd path

  7. Click the following "little flame" (Build Flash Monitor) one-click button to execute Build --> Flash --> Monitor sequentially.

    Select the one-click button

  8. The board has a built-in automatic download circuit, so no manual operation is required for automatic downloading. Then wait for the compilation and flashing to complete. The first compilation may take a while.

    Compilation and download complete

Demo

The Arduino demos are located in the demo package.

Below are the purpose, key points, and operational effects for each example (for quick start).

DemoBasic DescriptionDependency Library
01_I2C_TestTests the I2C header-
02_RS485_TestTests the RS485 header-
03_SD_TestTests the TF card slot-
04_Sensor_ADTests the ADC header-
05_UART_TestTests UART-
06_TWAItransmitTests the CAN header-
07_TWAIreceiveTests the CAN header-
08_lvgl_PortingTests LVGL portingv8.4.0

01_I2C_Test

This example tests the I2C header: it starts a console command line and provides I2C scan/read/write tools (e.g., i2cdetect/i2cget/i2cset).

Hardware Connection

  • Connect the board to the computer using a USB cable.

Code Analysis

  • app_main():
    • First, defines constants and variables related to I2C, such as log tags, I2C SDA and SCL pins, and port numbers.
    • Next, installs the console REPL environment based on different configuration options for user interaction. Then configures the I2C bus, including clock source, port, pins, enabling internal pull-up resistors, etc., and initializes the I2C master bus.
    • After that, registers a series of I2C tool commands, such as device detection, register read/write operations. Also prints usage instructions on how to use these commands.
    • Finally, starts the console REPL, allowing users to interact with the application via the command line to perform various I2C operations, providing a convenient way to operate the I2C bus via the command line.

Operation Result

  • After successful flashing, open the serial terminal, enter the command, and press Enter to run.

    ESP32_IDF_01

The steps are as follows:

  • Use help to check all supported commands
  • Use i2cconfig to configure your I2C bus
  • Use i2cdetect to scan for devices on the bus
  • Use i2cget to read the contents of a specific register
  • Use i2cset to set the value of a specific register
  • Use i2cdump to dump all registers (experimental)

02_RS485_Test

This example tests the RS485 header: it performs a UART loopback, echoing back whatever is received.

Hardware Connection

  • Connect the board to the computer using a USB cable

    ESP32-Arduino-43

  • Connect the board to your computer using a USB cable.

Code Analysis

  • echo_task():
    • First, configures UART parameters including baud rate, data bits, parity, stop bits, and hardware flow control.
    • Then, installs the UART driver, sets UART pins, and allocates a temporary buffer for receiving data.
    • In an infinite loop, reads data from UART, writes the read data back to UART, and logs information when data is received.

Operation Result

  • Open the serial debugging assistant and send a message to the ESP32-S3-Touch-LCD-4.3; the device will return the received message to the serial debugging assistant.

    ESP32-Arduino-06

03_SD_Test

This example tests the TF card slot: initializes the TF card and performs basic read/write and directory traversal tests.

Hardware Connection

  • Connect the board to the computer using a USB cable

Code Analysis

  • waveshare_sd_card_init():

    • This function mainly initializes the TF card. First, it initializes I2C, then pulls the TF card's CS pin low via the I2C control chip.
    • Next, it configures TF card mount options, including whether to format on mount failure, maximum file count, and allocation unit size.
    • After that, it initializes the SPI bus and mounts the TF card filesystem using the configured SPI bus and mount options.
    • If mounting is successful, it returns ESP_OK, indicating that TF card initialization is complete.
  • waveshare_sd_card_test():

    • This function tests the TF card functionality. First, it prints information about the initialized TF card.
    • Then, it creates a file and writes data, renames the file, and reads the content of the renamed file.
    • Next, it formats the filesystem and checks if the file is deleted after formatting.
    • Finally, it creates a new file and reads its content, unmounts the TF card after the test, and releases SPI bus resources.

Operation Result

  • After successful flashing, the serial port prints information about the storage card, such as name, type, capacity, and maximum supported frequency.

  • Subsequently, it creates a file, writes data, renames the file, and reads the renamed file.

    ESP32_IDF_02

04_Sensor_AD

This example tests the ADC connector: reads the raw ADC value and performs voltage calibration conversion.

Hardware Connection

  • Connect the board to the computer using a USB cable
  • Connect the PH2.0 to 2.54mm male connector to the Sensor AD interface of the board

Code Analysis

  • app_main():
    • First, it defines variables for storing the current ADC value and declares a calibration function.
    • Next, it initializes the ADC, sets the ADC resolution and attenuation, and then creates the ADC.
    • In an infinite loop, it reads the current ADC value and prints it, with a 1-second delay in the loop.

Operation Result

  • The development board will set the ADC resolution, read the current AD value, and print it to the serial terminal.

    ESP32_IDF_03

05_UART_Test

This example tests UART: received data is echoed back (loopback).

Hardware Connection

  • Connect the UART port of the board to the computer using a USB cable

Code Analysis

  • echo_task():
    • First, configures UART parameters including baud rate, data bits, parity, stop bits, and hardware flow control.
    • Then, installs the UART driver, sets UART pins, and allocates a temporary buffer for receiving data.
    • In an infinite loop, reads data from UART, writes the read data back to UART, and logs information when data is received.

Operation Result

  • Open the serial debugging assistant and send a message to the ESP32-S3-Touch-LCD-4.3; the device will return the received message to the serial debugging assistant.

    ESP32-Arduino-06

06_TWAItransmit

This example tests the CAN header: initializes TWAI and cyclically sends CAN frames.

Hardware Connection

ESP32-Arduino-13

  • Connect the board to the computer using a USB cable;

  • Connect CANH/CANL to the CAN bus and ensure the bus termination resistor is configured correctly.

  • Connect the development board to a USB-CAN-A interface.

Code Analysis

  • waveshare_twai_transmit():
    • If the driver is not installed, wait for a period and then return a failure status.
    • Read triggered alerts and obtain TWAI status information.
    • Print corresponding log information based on different alert types, including error passive alerts, bus error alerts, transmission failure alerts, and transmission success alerts, and print related status information.
    • Determine if it is time to send a message; if so, send the message and update the last send time.

Operation Result

  • The serial port prints successful CAN message sends. After configuring the USB-CAN-A_TOOL and starting it, you can see the CAN messages sent by the ESP32-S3-Touch-LCD-4.3.

    ESP32-Arduino-CN-01

    ESP32_IDF_05

07_TWAIreceive

This example tests the CAN header: initializes TWAI and cyclically receives CAN frames.

Hardware Connection

ESP32-Arduino-13

  • Connect the board to the computer using a USB cable;

  • Connect CANH/CANL to the CAN bus and ensure the bus termination resistor is configured correctly.

  • Connect the development board to a USB-CAN-A interface.

Code Analysis

  • waveshare_twai_receive():
    • If the driver is not installed, wait for a period and then return a failure status.
    • Read triggered alerts and obtain TWAI status information.
    • Print corresponding log information based on different triggered alert types, including error passive alerts, bus error alerts, and receive queue full alerts, and print related status information.
    • If a receive data alert is triggered, it loops to receive messages and calls the handle_rx_message function to process each received message. Finally, it returns a success status.

Operation Result

  • The ESP32-S3-Touch-LCD-4.3 waits for messages sent by the USB-CAN-A_TOOL. If received successfully, it prints them to the serial port.

    ESP32-Arduino-CN-02

    ESP32-Arduino-23

    ESP32_IDF_06

08_lvgl_Porting

This example tests LVGL porting: initializes the LCD/LVGL port and runs lv_demo_widgets().

Hardware Connection

  • Connect the board to the computer using a USB cable;

Code Analysis

  • app_main():
    • Initializes the Waveshare ESP32-S3 RGB LCD, then optionally turns the screen backlight on or off.
    • Next, it prints a message indicating that LVGL demo content will be displayed. Since LVGL APIs are not thread-safe, it first locks a mutex.
    • Then, it optionally runs different LVGL demo programs, such as lv_demo_stress, lv_demo_benchmark, lv_demo_music, lv_demo_widgets, or example_lvgl_demo_ui, etc.
    • Finally, it releases the mutex.

Code Modification

In waveshare_rgb_lcd_port.h, there is a macro definition to choose whether to enable touch functionality. A value of 0 corresponds to touch disabled, a value of 1 corresponds to touch enabled. Choose based on the purchased model.

#define CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 0 // 1 initiates the touch, 0 closes the touch.

Operation Result

  • After successful flashing, press the Reset button to run the demo

    lv_image