ESP32 — ESP-IDF v6
Your First ESP-IDF Project
Now that your ESP-IDF environment is set up, let's build your first real project: a Hello World that prints to the serial monitor and blinks an LED using a FreeRTOS task.
Prerequisites
Before continuing, make sure you have completed the setup guide for your OS:
And that idf.py --version returns ESP-IDF v6.x.x in your terminal.
Step 1 — Activate the ESP-IDF Environment
Every time you open a new terminal, activate the environment first.
Windows (PowerShell):
. $env:USERPROFILE\.espressif\esp-idf-v6.0\export.ps1
Ubuntu / macOS:
get_idf # If you set up the alias
# OR
. $HOME/.espressif/esp-idf-v6.0/export.sh
Step 2 — Create a New Project
# Create a new minimal project
idf.py create-project hello_world
cd hello_world
This creates the following structure:
hello_world/
├── CMakeLists.txt # Top-level build file
├── main/
│ ├── CMakeLists.txt # Component build file
│ └── hello_world_main.c # Your application code
└── sdkconfig # (created after first build)
Step 3 — Write the Application
Open main/hello_world_main.c in VS Code and replace its contents with:
1#include <stdio.h>2#include "freertos/FreeRTOS.h"3#include "freertos/task.h"4#include "esp_log.h"5#include "driver/gpio.h"67static const char *TAG = "hello_world";89// Change this to your board's LED pin10// ESP32 DevKit v1: GPIO 211// ESP32-S3 DevKitC: GPIO 4812#define BLINK_GPIO 21314void app_main(void)15{16 // Configure LED GPIO as output17 gpio_reset_pin(BLINK_GPIO);18 gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);1920 ESP_LOGI(TAG, "Hello from Analog Data!");21 ESP_LOGI(TAG, "ESP-IDF version: %s", esp_get_idf_version());2223 int count = 0;24 while (1) {25 ESP_LOGI(TAG, "Blink count: %d", count++);2627 // LED ON28 gpio_set_level(BLINK_GPIO, 1);29 vTaskDelay(pdMS_TO_TICKS(500));3031 // LED OFF32 gpio_set_level(BLINK_GPIO, 0);33 vTaskDelay(pdMS_TO_TICKS(500));34 }35}Step 4 — Set the Target Chip
# For standard ESP32 DevKit
idf.py set-target esp32
# For ESP32-S3
idf.py set-target esp32s3
# For ESP32-C6
idf.py set-target esp32c6
This creates or updates the sdkconfig file with chip-specific settings.
Step 5 — (Optional) Configure the Project
idf.py menuconfig
This opens a terminal-based configuration menu. For now, you can leave everything at defaults and press Q then Y to save and exit.
Useful settings to explore later:
- Component config → ESP System Settings — CPU frequency, logging level
- Partition Table — Flash partitioning
- Serial flasher config — Default flash size and port
Step 6 — Build the Project
idf.py build
The first build takes 3–10 minutes as it compiles all ESP-IDF libraries. Subsequent builds are incremental and much faster.
A successful build ends with:
[100%] Linking CXX executable hello_world.elf
esptool.py v4.x.x
...
Project build complete. To flash, run:
idf.py flash
or
idf.py -p PORT flash
Step 7 — Flash and Monitor
Connect your ESP32 via USB and identify the port:
| OS | Find port with |
|---|---|
| Windows | Device Manager → COM ports |
| Ubuntu | ls /dev/ttyUSB* |
| macOS | ls /dev/cu.* |
Flash and open the serial monitor:
# Windows
idf.py -p COM3 flash monitor
# Ubuntu / macOS
idf.py -p /dev/ttyUSB0 flash monitor
You should see the LED on your board blinking and the serial output:
I (342) hello_world: Hello from Analog Data!
I (342) hello_world: ESP-IDF version: v6.0.0
I (352) hello_world: Blink count: 0
I (852) hello_world: Blink count: 1
I (1352) hello_world: Blink count: 2
...
Exit the monitor: Press Ctrl + ]
Understanding the Project Structure
CMakeLists.txt (root)
1cmake_minimum_required(VERSION 3.24)2include($ENV{IDF_PATH}/tools/cmake/project.cmake)3project(hello_world)This tells CMake where to find ESP-IDF and sets your project name.
main/CMakeLists.txt
1idf_component_register(SRCS "hello_world_main.c"2 INCLUDE_DIRS ".")This registers your source files as a component in the build system.
app_main() — The Entry Point
Unlike Arduino's setup() and loop(), ESP-IDF uses app_main() as the entry point. It runs in a FreeRTOS task with a configurable stack size.
1void app_main(void) {2 // Your code here3 // This function can create FreeRTOS tasks and return4}Next Steps
- VS Code Integration → — Set up IntelliSense, build, and debug from VS Code

