Bắt đầu với ESP-IDF, cài đặt môi trường và các công cụ của IDF cho dev IoT
Hello các anh em, chắc hẳn ai quan tâm đến blog này đều đã biết về esp32, một MCU tuyệt vời mà giá siêu sinh viên cho anh em phát triển các hệ thống IoT với hiệu năng cao mà chi phí bỏ ra thì vô cùng hợp lý.
Không những thế, esp còn có thể lập trình bằng Arduino core, việc lập trình cho nó còn trở nên cực kỳ dễ dàng, nếu chỉ cần chạy được, demo sản phẩm, cần cho 1 dự án nhanh chóng Esp + Arduino core đã là sự kết hợp hoàn hảo.
Nhưng để trở thành 1 dev IoT chuyên nghiệp, gây ấn tượng với nhà tuyển dụng, anh em sinh viên không nên chỉ dừng ở Arduino, trong blog lần này chúng ta sẽ cùng đi vào những nội dung liên quan đến ESP-IDF, bộ công cụ phát triển phần mềm nhúng mạnh mẽ do chính công ty sản xuất cung cấp cho anh em embedded dev chúng ta, mà đã là hàng chính hãng thì hiệu năng và độ tin cậy sẽ khỏi phải bàn đúng không anh em, oke cùng mình bước những bước chân đầu tiên để tạo ra 1 project IoT chuyên nghiệp bằng IDF nhé.
1. Giới thiệu về ESP-IDF (Espressif IoT Development Framework)
ESP-IDF (Espressif IoT Development Framework) là framework (khung phát triển) gốc do chính Espressif (nhà phát triển chip ESP32) tạo ra để lập trình cho các dòng chip của họ.
Đây là một SDK (Bộ công cụ phát triển phần mềm) cho phép phát triển các ứng dụng trên chip ESP32 bằng ngôn ngữ lập trình C và C++. Điểm mạnh lớn nhất của nó là cho phép truy cập ở cấp độ thấp (low-level access) vào phần cứng, giúp khai thác tối đa sức mạnh của vi điều khiển.
Là phương thức lập trình "chính thức" cho ESP32, ESP-IDF đồng nghĩa với việc bộ SDK này luôn được cập nhật thường xuyên để hỗ trợ các phiên bản chip ESP32 mới nhất vừa được phát hành. Ngược lại, có thể phải mất một thời gian thì các chip mới này mới được hỗ trợ trên môi trường Arduino IDE.
Các dòng ESP32 SoC hiện đang được ESP-IDF hỗ trợ bao gồm :
- ESP32
- ESP32-S2, ESP32-S3
- ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61
- ESP32-H2
- ESP32-P4
Để lập trình cho bo mạch ESP32 bằng ESP-IDF, nên bắt đầu sử dụng VS Code IDE (Visual Studio Code) cùng với tiện ích mở rộng (extension) ESP-IDF. Và đó cũng chính là những gì bạn sẽ cài đặt trong hướng dẫn này.
2. Tiến hành cài đặt và build 1 chương trình "hello world"
Để chạy được bộ công cụ để build 1 chương trình IDF, anh em cần phải cài đặt python trước :
1) Tải python trên Window.
Di chuyển tới trang python.org/downloads và tải bản 3.13.3 hoặc các bản mới hơn.
Mở file đã tải về, cửa sổ này sẽ hiện ra.
Quan trọng : Hãy đảm bảo bạn đã tick (chọn) vào tùy chọn 'Add Python to PATH'. Sau đó, bạn có thể nhấp vào nút 'Install Now'. Bạn cũng có thể cần phải tick (chọn) vào ô “Use admin privileges when installing py.exe”.
Thành công sẽ hiện ra cửa sổ :
Bấm close để hoàn thành cài đặt.
B) Tải Python trên Mac OS X
Mở một cửa sổ Terminal. Bạn có thể mở nó thông qua Spotlight Search. Để khởi chạy Spotlight, hãy nhấp vào biểu tượng kính lúp nhỏ trên thanh menu của bạn (hoặc nhấn tổ hợp phím Cmd+Space).
Sau đó, gõ chữ “terminal” và nhấp vào biểu tượng Terminal để khởi chạy nó.
Dưới đây là bản dịch sang tiếng Việt của đoạn hướng dẫn cài đặt Python bằng Homebrew:
Để cài đặt Python, tôi sẽ sử dụng Homebrew. Nếu bạn chưa có lệnh brew (Homebrew) khả dụng, hãy gõ lệnh sau vào cửa sổ Terminal:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Sau đó, chạy lệnh brew để cài đặt Python 3.13:
brew install python3
Và đây là giao diện trông như thế nào trên cửa sổ Terminal :
C) Tải Python trên Linux Ubuntu
Hãy mở cửa sổ Terminal và kiểm tra xem bạn đã cài đặt Python 3 hay chưa. Chạy lệnh sau:
python3 --version
Nếu có nó sẽ trả về như :
python 3.13.3
Nếu bạn chưa cài đặt Python, hãy chạy lệnh sau để cài đặt nó :
sudo apt install python3
Dù bạn đã cài đặt Python hay chưa, bạn cần chạy lệnh sau để cài đặt các tiện ích Python.
sudo apt install python3.udo apt install python3-distutils.
Sau khi có môi trường python, tiến hành cài vscode + idf extension thôi :
Vscode là công cụ giúp soạn thảo, còn idf extension sẽ giúp chúng ta compile và build code để nạp vào esp32.
Cài VsCode tại đây : https://code.visualstudio.com/download
Sau quá trình cài đặt, vscode và tìm vào mục EXTENSIONS bấm vào search và tìm ESP-IDF.
Sau khi bấm install, IDF extension đã được cài thành công, hãy reload Vscode để extension hoạt động nhé.
Sau khi reload, vscode sẽ tự đông nhảy vào IDF setup cho chúng ta
Chọn express để bắt đầu setup môi trường, vì extension mới chỉ được tải trên vscode, nếu muốn build code và nạp vào chip sẽ phải về toàn bộ công cụ từ nhà sản xuất.
Chọn các cấu hình để tải về như : Server để tải, các đường dẫn chứa tool của IDF( để mặc định hoặc tùy chỉnh đường dẫn).
Bấm install và đợi quá trình hoàn tất tải về, khởi động lại, và quá trình cài đặt đã hoàn tất rồi đó.
Sau khi có môi trường, cùng mình viết thử 1 project hello world với ESP-IDF nhé.
Chuẩn bị phần cứng :
Trên tay mình là board ESP32 của ELAB, mà nhìn sơ qua có thể khiến nhiều người liên tưởng ngay đến Arduino – vừa quen thuộc, vừa dễ làm quen.
Nhỏ gọn, có đầy đủ chân GPIO, ADC, SPI, I2C, hỗ trợ cả WiFi và Bluetooth, board này cho bạn cảm giác “như đang lập trình Arduino nhưng mạnh mẽ hơn gấp nhiều lần”. Điều tuyệt vời là nó tương thích hoàn toàn với ESP-IDF, nên bạn vừa có thể trải nghiệm môi trường lập trình chuyên nghiệp, vừa không bị lúng túng nếu đã quen với Arduino IDE :
Tại cửa sổ welcome to Espressif IDF extension bấm vào new project để idf-tool tạo cho chúng ta 1 dự án mới
Trường đầu tiên là tên dự án, là dự án đầu nên anh em đặt tên thật kêu nhá, tiếp đến là đường dẫn để chứa project này (project sẽ là 1 folder trong máy chúng ta), tiếp đến chọn tên chip mà bạn đang có (esp32 thường, esp32c3, esp32s3, cuối cùng là component( là cách mà idf định nghĩa cho các thư viện bên ngoài) phần này ae chưa cần lưu ý đến, nhấn choose template để chọn.
Đến với cửa sổ tiếp theo, chúng ta có thể chọn mẫu cho dự án của mình, nhấn vào template-app để tạo 1 dự án trống nhé, cuối cùng nhấn vào create project using template app, đợi 1 lúc sẽ có cửa sổ thông báo để chúng ta chuyển vào project đó.
Bấm yes để nhảy vào folder đó, cấu trúc của 1 folder sau khi tạo sẽ như sau :
Để bắt đầu viết code cho chương trình idf đầu tiên, vào folder main và bắt đầu viết những dòng code đầu tiên trong main.c.
Vậy khi viết xong thì biên dịch và nạp chỗ nào ? Để ý phía dưới nào.
Ở bên dưới là các công cụ phục vụ cho chúng ta build và nạp code vào esp32, cụ thể là :
- 🔌 Select Port (Chọn cổng COM):
- Biểu tượng: Thường là hình cái phích cắm hoặc chữ "COM".
- Chức năng: Cho phép bạn chọn cổng serial (ví dụ: COM3 trên Windows hoặc /dev/ttyUSB0 trên Linux) mà bo mạch ESP32 của bạn đang kết nối.
- Select Target (Chọn chip):
- Biểu tượng: Hình con chip.
- Chức năng: Dùng để chọn chính xác dòng chip bạn đang sử dụng (ví dụ: esp32, esp32s3, esp32c3).
- ⚙️ SDK Configuration Editor (Trình chỉnh sửa cấu hình):
- Biểu tượng: Hình bánh răng hoặc các thanh trượt điều khiển.
- Chức năng: Mở giao diện menuconfig (dưới dạng đồ họa) để bạn có thể bật/tắt các tính năng, cấu hình Wi-Fi, FreeRTOS, và nhiều thông số khác của dự án.
- 🧱 Build (Xây dựng):
- Biểu tượng: Hình viên gạch, khối vuông hoặc cái búa.
- Chức năng: Chạy lệnh idf.py build. Nó chỉ biên dịch mã nguồn của bạn và các thành phần ESP-IDF để tạo ra tệp firmware .bin trong thư mục build.
- ⚡ Flash (Nạp):
- Biểu tượng: Hình tia chớp.
- Chức năng: Chạy lệnh idf.py flash. Nó sẽ nạp tệp firmware (đã được build trước đó) vào bộ nhớ flash của ESP32.
- 🖥️ Monitor (Giám sát):
- Biểu tượng: Hình cái màn hình hoặc terminal.
- Chức năng: Chạy lệnh idf.py monitor. Nó mở một terminal để hiển thị dữ liệu log (ví dụ: các lệnh printf hoặc ESP_LOGI) được gửi từ ESP32 qua cổng serial.
- ▶️ Build, Flash, and Monitor (Xây dựng, Nạp và Giám sát):
- Biểu tượng: Hình ngọn lửa.
- Chức năng: Đây là nút tiện lợi nhất. Nó kết hợp cả ba lệnh: build, flash, và monitor theo thứ tự. Đây thường là nút bạn sẽ nhấn nhiều nhất khi phát triển.
- 🧹 Clean (Dọn dẹp):
- Biểu tượng: Hình cái chổi.
- Chức năng: Chạy lệnh idf.py clean. Nó xóa các tệp build tạm thời trong thư mục build nhưng giữ lại tệp sdk config và các tệp biên dịch trước. Lần build sau sẽ nhanh hơn.
- 🗑️ Full Clean (Dọn dẹp toàn bộ):
- Biểu tượng: Thường là hình cái chổi quét mạnh hơn hoặc thùng rác.
- Chức năng: Chạy lệnh idf.py fullclean. Nó xóa toàn bộ thư mục build và tệp sdkconfig. Lần build tiếp theo sẽ phải biên dịch lại từ đầu, hữu ích khi bạn gặp lỗi cấu hình lạ.
- 📊 Size Analysis (Phân tích kích thước):
- Biểu tượng: Hình biểu đồ tròn hoặc cột.
- Chức năng: Chạy lệnh idf.py size hoặc size-components. Giúp bạn xem firmware của mình đang chiếm bao nhiêu dung lượng flash và RAM, và thành phần nào đang tốn nhiều bộ nhớ nhất.
Sau khi cài đặt thành công, anh em cùng mình viết thử 1 chương trình hello world esp32 nhé:
#include <stdio.h>
void app_main(void)
{
printf("IDF Hello world\n");
}
Sau khi viết xong, sử dụng các công cụ ở trên để build code và nạp code vào esp32.
Build xong màn hình terminal sẽ ra như thế này, bấm hình sét để nạp code vào nhé ae.
Chọn phương thức nạp là UART, nạp xong và bật monitor lên, chúng ta sẽ được màn hình thông báo sau:
Là anh em đã thành công rồi nhé.
3. Khám phá các example ( Ví dụ của hãng)
Sau khi cài đặt đầy đủ môi trường ESP-IDF, đây là lúc bạn bắt đầu lập trình ESP32 theo chuẩn công nghiệp, nhưng sau khi cài xong nên làm gì nhỉ ?
Nếu bạn là người mới, việc quan trọng bạn nên làm là nên đọc thử các example ( ví dụ mẫu) mà hãng Espressif cung cấp, vì đây chính là bộ giáo trình chính thức, chuẩn và đầy đủ, cập nhật theo mỗi phiên bản, được viết bởi những kỹ sư của Espressif, thể hiện best-practice khi sử dụng API.
Example nằm ở đâu?
Sau khi cài đặt xong, thư mục chứa các ví dụ mẫu thường nằm trong folder mà bạn đã tải ESP-IDF (hoặc nơi VS Code IDF Extension tự clone về). Đường dẫn mặc định sẽ là:
esp-idf/examples/
Bên trong examples/ chứa toàn bộ ví dụ chính thức do Espressif cung cấp, được chia theo từng nhóm chức năng để bạn dễ học và dễ tra cứu. Cấu trúc thường trông như sau :
examples/
├── bluetooth # Các ví dụ BLE & Classic BT (GATT, GAP, SPP, A2DP...)
├── build_system # Ví dụ về CMake, component, dependency, build advanced
├── common_components # Component dùng chung cho nhiều example (helper, utils)
├── custom_bootloader # Ví dụ tạo bootloader tùy chỉnh
├── cxx # Ví dụ lập trình ESP-IDF bằng C++ (class, component C++)
├── ethernet # Ví dụ kết nối Ethernet (LAN8720, IP101, DHCP...)
├── get-started # Ví dụ cơ bản cho người mới (blinky, hello_world)
├── ieee802154 # Ví dụ giao thức 802.15.4 (cơ sở cho Zigbee/Thread)
├── lowpower # Ví dụ tiết kiệm năng lượng (deep sleep, light sleep)
├── mesh # ESP-Mesh – mạng lưới nhiều node ESP32
├── network # Ví dụ TCP/UDP, socket, HTTP, mDNS, DHCP, SNTP,...
├── openthread # Ví dụ mạng Thread (nền tảng IoT)
├── peripherals # Ví dụ thao tác ngoại vi: GPIO, I2C, SPI, UART, ADC, DAC...
├── phy # Ví dụ liên quan đến cấu hình & kiểm thử radio PHY
├── protocols # Ví dụ các protocol IoT: MQTT, CoAP, HTTP, WebSocket...
├── provisioning # Ví dụ cấu hình WiFi bằng BLE/SoftAP (WiFi provisioning)
├── security # Ví dụ về bảo mật: TLS, secure boot, flash encryption
├── storage # Ví dụ lưu trữ: NVS, SPIFFS, FATFS, SD card
├── system # Ví dụ về FreeRTOS, event loop, heap, multicore, ISR,...
├── wifi # Ví dụ WiFi: station, AP, scan, WPA-Enterprise, WPS,...
└── zigbee # Ví dụ Zigbee (coordinator, router, end device)
Các example do Espressif cung cấp không chỉ đơn thuần là những đoạn code mẫu, mà còn là kim chỉ nam quan trọng cho người mới. Chúng giúp bạn hiểu rõ cấu trúc dự án chuẩn, cách sử dụng API đúng cách và những best-practice đã được kiểm chứng, đồng thời tránh được những sai lầm phổ biến khi tự mò mẫm. Thay vì tốn hàng giờ thử và lỗi, việc tham khảo example sẽ giúp bạn học nhanh hơn, thực hành chính xác hơn, đồng thời có thể dễ dàng mở rộng, chỉnh sửa theo nhu cầu dự án của mình. Nói cách khác, example chính là bản đồ dẫn đường, giúp bất kỳ ai bước vào ESP-IDF đều không bị lạc trong thế giới các module, driver và cấu hình phức tạp của ESP32.
Trình tự khi tìm hiểu một example
1. Đọc README và Tài liệu
Bước đầu tiên và quan trọng nhất là đọc file README.md (hoặc tài liệu liên quan) trong thư mục của ví dụ.
- Mục đích: Hiểu rõ mục đích của ví dụ, chức năng mà nó trình diễn, và yêu cầu về phần cứng/cấu hình (nếu có).
- Chi tiết kỹ thuật: Thường thì README sẽ mô tả các bước thực hiện, các thành phần chính của IDF được sử dụng (ví dụ: Wi-Fi, Bluetooth, FreeRTOS, GPIO), và cách để chạy thử nghiệm.
2. Phân tích Cấu hình Dự án
Xem xét các tập tin cấu hình để hiểu cách dự án được thiết lập.
- sdkconfig: Tập tin này chứa các tùy chọn cấu hình cho toàn bộ IDF và dự án của bạn (được tạo sau khi chạy idf.py menuconfig). Hãy xem nhanh các tùy chọn quan trọng có thể ảnh hưởng đến hoạt động của ví dụ.
- CMakeLists.txt:
- Thư mục gốc: Xem CMakeLists.txt ở cấp độ thư mục gốc của ví dụ để xác định tên dự án và bất kỳ cấu hình thành phần bổ sung nào được thêm vào.
- Thành phần: Nếu ví dụ có các thành phần (components) riêng biệt, hãy xem CMakeLists.txt trong các thư mục thành phần đó để biết nó phụ thuộc vào các thư viện nào (ví dụ: REQUIRES các thư viện khác của IDF) và các tập tin nguồn nào được biên dịch.
3. Phân tích Mã nguồn Chính (main)
Tập trung vào các tập tin mã nguồn (thường là main.c hoặc app_main.c).
- Điểm vào: Tìm hàm app_main() – đây là điểm bắt đầu của ứng dụng (trừ khi dự án sử dụng component riêng).
- Luồng chính: Phân tích luồng thực thi chính của chương trình. Điều này bao gồm:
- Các bước khởi tạo (ví dụ: khởi tạo NVS, cấu hình Wi-Fi).
- Cách các thành phần của IDF được gọi và sử dụng (ví dụ: gọi hàm API để kết nối Wi-Fi).
- Việc tạo các Task (tác vụ) của FreeRTOS, nếu có.
- Sử dụng Debugging (Optional): Nếu cần, sử dụng các câu lệnh in (ESP_LOGI, printf) hoặc một trình gỡ lỗi (debugger) JTAG để theo dõi luồng code chi tiết.
4. Tra cứu API và Cấu trúc Dữ liệu
Khi gặp một hàm hoặc cấu trúc dữ liệu của IDF mà bạn chưa quen, hãy dừng lại và tra cứu.
- Tài liệu ESP-IDF: Đây là nguồn chính xác nhất, bạn có thể tìm thấy mô tả các API tại trang web của nhà phát triển (ở đây), bạn có thể tìm api theo chủ đề mà mình đang đọc, để có thể hiểu được chương trình hoạt động như thế nào
5. Biên dịch, Nạp và Kiểm tra
Sau khi đã hiểu cơ bản, bạn tiến hành thực thi ví dụ:
- Cấu hình: Chạy idf.py set-target <chip> (ví dụ: esp32) và sau đó idf.py menuconfig để tùy chỉnh cấu hình theo hướng dẫn (nếu có).
- Biên dịch: Chạy idf.py build.
- Nạp: Chạy idf.py flash.
- Theo dõi: Chạy idf.py monitor để xem output trên cổng nối tiếp (serial monitor) và kiểm tra xem ví dụ có chạy đúng như mô tả không.
6. Thử nghiệm và Tùy biến
Bước này giúp củng cố kiến thức và kiểm tra mức độ hiểu biết của bạn.
- Thay đổi nhỏ: Thực hiện các thay đổi nhỏ trong code (ví dụ: thay đổi thời gian chờ, thay đổi chuỗi in ra, thay đổi chân GPIO) và xem kết quả.
- Mở rộng: Cố gắng thêm một tính năng nhỏ dựa trên ví dụ (ví dụ: nếu đó là ví dụ Wi-Fi, hãy thêm một tác vụ FreeRTOS để nhấp nháy đèn LED sau khi kết nối thành công).
- Tóm tắt: Tự tóm tắt lại những API và nguyên tắc chính mà ví dụ này đã dạy bạn.
Hy vọng qua blog này, bạn đã thấy việc bắt đầu với ESP-IDF không còn "đáng sợ" như lời đồn. Việc cài đặt môi trường thường là rào cản lớn nhất với người mới, nhưng với VS Code và Idf extension bạn đã vượt qua nó một cách dễ dàng.
Giờ đây, bạn không chỉ có một môi trường lập trình hoàn chỉnh mà còn hiểu rõ "vũ khí" của mình – các nút Build, Flash, và Monitor. Đây là nền tảng vững chắc nhất để bạn bắt đầu biến hóa với con chip ESP32 của mình.


