Introduction
This guide explains how to build and run the OpenThread Application Framework on ESP32‑C6 using ESP‑IDF v5.4.1 and Visual Studio Code (ESP‑IDF extension). It covers three device roles:
- Controller / Sensor / Switch node (JOINER + SRP client)
- Control Panel node (COMMISSIONER + JOINER)
- Border Router node (BORDER_ROUTER + COMMISSIONER + JOINER)
Example application devices:
Clone Project and Install ESP‑IDF
- Install ESP‑IDF v5.4.1:
- Clone this project repository:
git clone [github_repo_address]
- Open the project folder in Visual Studio Code.
- In the ESP‑IDF extension, configure the ESP‑IDF tools and select the installation path pointing to v5.4.1 (e.g. esp-idf-v5.4.1).
Prerequisites
- ESP32‑C6 development boards:
- at least 1 × Border Router node (Espressif Thread Border Router)
- 1 × Control Panel node (it is not necessary)
- minimum 1 x switch device and 1 x light device
- ESP‑IDF v5.4.1 installed and working from the ESP‑IDF terminal in VS Code.
- Python and CMake available in PATH (handled automatically by the ESP‑IDF installer).
- Basic knowledge of Thread / OpenThread concepts (Joiner, Commissioner, Border Router).
Hardware Setup
Button Device (control device )
Example GPIO connections for a 3‑button controller node (switch device):
- BUTTON_1 → GPIO 3
- BUTTON_2 → GPIO 9
- BUTTON_3 → GPIO 15
Recommended wiring:
- Buttons connected between GPIO and GND.
- Internal pull‑ups enabled in GPIO configuration (or external pull‑up resistors).
RGB Light Device (end point device)
WS2812B RGB LED strip:
- DIN (data in) → GPIO 8 (RMT output used by ws2812b_drv_RMT)
- VCC → 5 V (or 3.3 V if supported by LEDs)
- GND → common ground with ESP32‑C6 board.
- Note
- Exact pins can be adjusted in the board‑specific HAL / ESP‑IDF configuration.
Software Structure
The application is organised into the following main modules:
- main.c – FreeRTOS app_main() entry, initializing:
- selected device (button or light),
- OpenThread Application Framework (otapp_init()),
- timers (xTim_Init()),
- WS2812B interface and FX engine (ws2812b_if_init(), WS2812BFX_*).
- main API for OpenThread hardware application – device driver API (ot_app_drv.h, ot_app_drv.c), providing:
- pairing API, URI management, device name support, NVS and CoAP helpers.
- Button Device – controller device implementation:
- Light Device – RGB light device:
Light Device Example (Application Node)
Example app_main() for a pure light node, based on main.c:
void app_main(void)
{
........
}
void ad_light_init(char *deviceNameGroup)
Initialize the RGB light device and register it in the framework.
Definition ad_light.c:114
int8_t otapp_init(void)
Main initialization of the OpenThread Application Framework. Initializes the driver instance,...
Definition ot_app.c:231
Key steps:
Next build project using the instruction: Controller device (button) / End device (light)
Button Device Example (Controller Node)
Example app_main() for a button controller node:
void app_main(void)
{
........
}
Key steps:
Next build project using the instruction: Controller device (button) / End device (light)
Build Configurations (Device Roles)
The project uses separate Kconfig fragments in components/app_devices/kconfigs path and helper commands executed from the ESP‑IDF terminal in Visual Studio Code.
All commands below assume they are run from the project root directory in the ESP‑IDF Terminal.
Controller device (button) / End device (light)
Configuration (JOINER + SRP client):
- CONFIG_DEVICE_TYPE_ID="CS"
- CONFIG_OPENTHREAD_BORDER_ROUTER=n
- CONFIG_OPENTHREAD_COMMISSIONER=n
- CONFIG_OPENTHREAD_JOINER=y
- CONFIG_OPENTHREAD_SRP_CLIENT=y
- CONFIG_LWIP_IPV6_NUM_ADDRESSES=12
Apply configuration:
- press in vscode press CTR + SHIFT + P
- search "tasks: run task"
- next "termina idf"
- and than paste into the terminal:
cp components/app_devices/kconfigs/kconfig.controllerORSensor sdkconfig
Get-ChildItem -Filter "X_Config_*.txt" | Rename-Item -NewName "X_Config_CONTROLLER_SENSOR.txt"
idf.py reconfigure
Then build and flash:
idf.py build
idf.py -p COMx flash monitor
You can also use vsc tasks (CTR + SHIFT + P): "Tasks: Run tTasks" / "project *" (project build, project flash, project reBuild, project flash, project build & flash)
Control Panel
Configuration (COMMISSIONER + JOINER):
- CONFIG_OPENTHREAD_BORDER_ROUTER=n
- CONFIG_OPENTHREAD_COMMISSIONER=y
- CONFIG_OPENTHREAD_JOINER=y
- CONFIG_OPENTHREAD_SRP_CLIENT=y
- CONFIG_LWIP_IPV6_NUM_ADDRESSES=12
Apply configuration:
- press in vscode press CTR + SHIFT + P
- search "tasks: run task"
- next "termina idf"
- and than paste into the terminal:
Apply configuration:
cp components/app_devices/kconfig.controlPanel sdkconfig
Get-ChildItem -Filter "X_Config_*.txt" | Rename-Item -NewName "X_Config_CONTROL_PANEL.txt"
idf.py reconfigure
You can also use vsc tasks (CTR + SHIFT + P): "Tasks: Run tTasks" / "project *" (project build, project flash, project reBuild, project flash, project build & flash)
Border Router
Configuration (BORDER_ROUTER + COMMISSIONER + JOINER):
- CONFIG_OPENTHREAD_BORDER_ROUTER=y
- CONFIG_OPENTHREAD_COMMISSIONER=y
- CONFIG_OPENTHREAD_JOINER=y
- CONFIG_OPENTHREAD_SRP_CLIENT_MAX_SERVICES=5
Apply configuration:
- press in vscode press CTR + SHIFT + P
- search "tasks: run task"
- next "termina idf"
- and than paste into the terminal:
Apply configuration:
cp components/app_devices/kconfig.borderRouter sdkconfig
Get-ChildItem -Filter "X_Config_*.txt" | Rename-Item -NewName "X_Config_BORDER_ROUTER.txt"
idf.py reconfigure
After selecting any role, you can always run:
idf.py build
idf.py -p COMx flash monitor
You can also use vsc tasks (CTR + SHIFT + P): "Tasks: Run tTasks" / "project *" (project build, project flash, project reBuild, project flash, project build & flash)
Pairing and Operation
- Flash and run the Border Router firmware on the border router node using the configuration in Border Router. (moved to a separate repository: [github]) todo
- Flash and run the Control Panel firmware using the configuration in Control Panel. Use it to manage commissioning and Thread network formation. (in progress) todo
- Flash and run application nodes:
- Ensure both application devices share the same device name group string (e.g. "device1"), so they belong to the same logical group.
- Use the pairing procedure described in Procedure for Assigning a New Device to a Button to assign buttons to discovered light devices (button → URI mapping).
- After successful pairing:
VS Code / ESP‑IDF Integration
Recommended workflow in Visual Studio Code:
- Open the project folder.
- Use the ESP‑IDF extension:
- Configure ESP‑IDF v5.4.1 toolchain and Python environment.
- Set the correct serial port (COMx) for your ESP32‑C6 board.
- Use ESP‑IDF: Open ESP‑IDF Terminal to execute:
- Role selection commands (copy devices/kconfig.* + idf.py reconfigure).
- idf.py build, idf.py flash, idf.py monitor.
Project includes helper configuration files for VS Code:
- .vscode/launch.json – debug launch configuration.
- .vscode/tasks.json – ESP‑IDF build / flash / monitor tasks.
- .vscode/c_cpp_properties.json – IntelliSense include paths and defines.
- .vscode/settings.json – ESP‑IDF extension settings and project metadata.
Next Steps
- Explore API details in api_reference.
- Modify device implementations (Button Device, Light Device) to add custom behaviors or sensors.
- Study unit tests:
- See also
- Quick Start for a condensed overview on the main page
-
main API for OpenThread hardware application for the device driver API
-
Button Device and Light Device for implementation details