What

Install ESP-IDF (Espressif IoT Development Framework) on Ubuntu and run a hello world example on ESP32.

Why

  • Official SDK: ESP-IDF is Espressif’s native framework with full hardware support.
  • No Arduino overhead: Direct hardware access, smaller binaries, complete control.
  • Production-ready: Same toolchain used in commercial ESP32 development.

How

System Requirements

  • Ubuntu/Debian-based Linux
  • Python 3.6 or newer
  • At least 4GB free disk space
  • USB port for ESP32

Video Tutorial

ESP32 Setup on Linux: https://www.youtube.com/watch?v=Jt6ZDct4bZk

Complete visual walkthrough of ESP-IDF installation and troubleshooting.

Step 1 — Update system and install dependencies

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip git wget flex bison gperf python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util

What these packages do:

  • git - Clone ESP-IDF repository
  • flex, bison, gperf - Parser generators for build tools
  • cmake, ninja-build - Build system
  • ccache - Compiler cache for faster rebuilds
  • libffi-dev, libssl-dev - Development libraries
  • dfu-util - Device firmware upgrade utility

Step 2 — Create ESP directory

mkdir -p ~/esp
cd ~/esp

Keeps all ESP32 tools and projects in one place.

Step 3 — Clone ESP-IDF

git clone --recursive https://github.com/espressif/esp-idf.git

Downloads ESP-IDF framework with submodules. Large download (around 1GB).

Step 4 — Run installer

cd esp-idf
./install.sh

Installs:

  • Xtensa toolchain for ESP32
  • Python dependencies
  • Build tools

Takes 5-10 minutes depending on connection speed.

Step 5 — Optional pip upgrade

pip install --upgrade pip

Ensures latest pip version for dependency management.

Step 6 — Set up environment variables

For current session:

. ./export.sh

To make permanent (recommended):

Edit profile:

nano ~/.profile

Add this line at the end:

. $HOME/esp/esp-idf/export.sh

Save (Ctrl+X, Y, Enter) and reload:

source ~/.profile

Environment activates automatically on new terminal sessions.

Step 7 — Add user to serial port groups

ESP32 connects via USB serial (usually /dev/ttyUSB0). Grant access without sudo:

sudo usermod -a -G dialout,tty $USER

Important: Reboot for group changes to apply.

sudo reboot

Virtual machine users: shut down completely and restart.

Step 8 — Verify serial port

After reboot, connect ESP32 via USB and check:

ls /dev/ttyUSB*

Expected: /dev/ttyUSB0 or /dev/ttyACM0

If nothing appears:

  • Check USB cable (must support data, not charge-only)
  • Try different USB port
  • On VM: ensure USB passthrough is enabled

Step 9 — Copy hello world example

cd ~/esp
cp -r esp-idf/examples/get-started/hello_world ./hello_world
cd hello_world

ESP-IDF examples are tested templates. Copy to avoid modifying originals.

Step 10 — Build the project

idf.py build

Build process:

  • CMake generates build files
  • Compiles source code
  • Creates binary images
  • Generates partition tables

First build takes 2-5 minutes. Subsequent builds use cache (faster).

Step 11 — Flash to ESP32

idf.py -p /dev/ttyUSB0 flash

Replace /dev/ttyUSB0 if your device path differs.

Flash writes:

  • Bootloader
  • Partition table
  • Application binary

Some boards require holding BOOT button during flash.

Step 12 — Monitor output

idf.py -p /dev/ttyUSB0 monitor

Opens serial console at 115200 baud. Expected output:

Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE
Minimum free heap size: 298892 bytes
Restarting in 10 seconds...

Exit monitor: Ctrl+]

Step 13 — Combined flash and monitor

idf.py -p /dev/ttyUSB0 flash monitor

Flashes then immediately monitors. Saves a step during development.

Troubleshooting

Permission denied on /dev/ttyUSB0

Cause: Didn’t reboot after adding user to dialout group.

Temporary fix:

sudo chmod 666 /dev/ttyUSB0

Permanent fix: Reboot system.

Brownout detector triggered

Error: BOD: Brownout detector was triggered

Causes:

  • Insufficient power from USB
  • Weak USB cable
  • USB hub without external power

Solutions:

  • Connect directly to computer USB port (not hub)
  • Use USB 3.0 port (blue inside) - provides more current
  • Try shorter/thicker USB cable
  • Use powered USB hub
  • Use external 5V power supply

idf.py command not found

Cause: Environment variables not set.

Fix:

. $HOME/esp/esp-idf/export.sh

Or add to ~/.profile for persistence.

Build errors

Clean and rebuild:

idf.py fullclean
idf.py build

Update ESP-IDF:

cd ~/esp/esp-idf
git pull
git submodule update --init --recursive
./install.sh

Serial port not detected

Check device connection:

dmesg | grep tty
lsusb

If using VM: Ensure USB passthrough connects ESP32 to VM, not host.

Useful Commands

# Build project
idf.py build

# Flash to device
idf.py -p /dev/ttyUSB0 flash

# Monitor serial output
idf.py -p /dev/ttyUSB0 monitor

# Flash and monitor
idf.py -p /dev/ttyUSB0 flash monitor

# Clean build
idf.py clean

# Full clean (all build artifacts)
idf.py fullclean

# Configure project (interactive menu)
idf.py menuconfig

# Erase flash completely
idf.py -p /dev/ttyUSB0 erase-flash

# Show project size
idf.py size

# List USB devices
ls /dev/ttyUSB*

# Check device connection
dmesg | grep tty

# List USB hardware
lsusb

# Check user groups
groups

# Monitor USB events (real-time)
sudo dmesg -w

Notes

  • ESP-IDF creates its own Python virtual environment. Don’t activate other venvs.
  • Hold BOOT button on ESP32 during flash if auto-detection fails.
  • First build is slow. Subsequent builds use cmake cache.
  • USB cable quality matters. Data cables work, charge-only cables don’t.
  • VM users need proper USB passthrough configuration.

Next Steps

  • Explore ESP-IDF examples: ~/esp/esp-idf/examples/
  • Try blink example: ~/esp/esp-idf/examples/get-started/blink/
  • Read ESP-IDF Programming Guide
  • Configure WiFi: idf.py menuconfig
  • Check WiFi examples: ~/esp/esp-idf/examples/wifi/
  • HTTP server examples: ~/esp/esp-idf/examples/protocols/http_server/