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 repositoryflex,bison,gperf- Parser generators for build toolscmake,ninja-build- Build systemccache- Compiler cache for faster rebuildslibffi-dev,libssl-dev- Development librariesdfu-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/