Caso você esteja iniciando na utilização do ESP32 com o Arduino, recomendo a leitura deste artigo, no qual Fábio Souza explica o processo de preparação do ambiente de desenvolvimento e descreve os passos necessários para compilar a aplicação Arduino e fazer o upload do firmware para a memória Flash do ESP32. Além disso, recomendo o tutorial do Pedro Minatel para a familiarização com o ESP-IDF.
Neste artigo, mostraremos como configurar e utilizar o Arduino para ser utilizado como um componente do ESP-IDF. Vale notar que este tutorial foi criado para ESP-IDF v5.1 e arduino-esp32 v3.0.0-alpha3, podendo estar desatualizado dependendo da data em que estiver lendo isto.
O que é um componente do ESP-IDF ?
“Componentes” são peças modulares de código independente que são compiladas em bibliotecas estáticas (arquivos .a) e vinculadas a um aplicativo. Alguns são fornecidos pelo próprio ESP-IDF, outros podem ser provenientes de outros locais.
Um projeto ESP-IDF pode ser visto como uma fusão de vários componentes. Por exemplo, para um servidor web que mostra a umidade relativa atual, podem haver os seguintes componentes:
- As bibliotecas base ESP-IDF (libc, bindings da ROM, etc.)
- Os drivers Wi-Fi
- Uma pilha TCP/IP
- O sistema operacional FreeRTOS
- Um servidor web
- Um driver para o sensor de umidade
- Código principal unindo tudo
O ESP-IDF torna esses componentes explícitos e configuráveis. Para fazer isso, quando um projeto é compilado, o sistema de build irá procurar todos os componentes nas pastas do ESP-IDF, do projeto e, opcionalmente, em componentes personalizados. Em seguida, o usuário pode configurar o projeto e seus componentes utilizando o menuconfig. Depois que os componentes do projeto forem configurados, o sistema de build compilará o projeto.
Por que utilizar o Arduino como um Componente?
Usar o Arduino como parte do ESP-IDF é como combinar duas ferramentas poderosas para programar ESP32. É como combinar a facilidade das bibliotecas do Arduino com os fortes recursos do ESP-IDF. Esta configuração é ótima para fãs do Arduino que estão entrando no mundo mais avançado do ESP-IDF. Você pode ficar com o IDE simples do Arduino, aproveitar sua enorme comunidade para obter ajuda e explorar gradualmente as coisas mais legais que o ESP-IDF tem a oferecer.
No entanto, há um contraponto. Embora o núcleo do Arduino no ESP-IDF torne as coisas mais fáceis e acessíveis, isso pode significar sacrificar algum controle e eficiência que você obteria codificando diretamente com o ESP-IDF. A escolha entre o Arduino como componente e o uso completo do ESP-IDF depende das necessidades do seu projeto, da sua familiaridade com cada sistema e se esses recursos avançados do ESP-IDF são essenciais ou não.
Instalação
Para esse tutorial, utilizaremos o sistema operacional Ubuntu 20.04 LTS. Caso esteja utilizando outro sistema, consulte a documentação do ESP-IDF para realizar o processo de instalação.
Primeiramente precisamos instalar o ESP-IDF e seus pré-requisitos. Para isso iremos instalar os pacotes necessários e baixar uma cópia do repositório do ESP-IDF em esp/esp-idf dentro da pasta home do usuário. Para obter os pacotes necessários, execute:
sudo apt update
sudo apt upgrade
sudo apt install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
Agora podemos obter uma cópia do repositório do ESP-IDF e instalá-lo:
mkdir -p ~/esp
cd ~/esp
git clone -b release/v5.1 --recursive https://github.com/espressif/esp-idf.git
cd ~/esp/esp-idf
./install.sh
Para utilizar o ESP-IDF, não se esqueça de inicializar as variáveis de ambiente quando abrir um novo terminal executando:
source ~/esp/esp-idf/export.sh
Caso a instalação tenha sido bem sucedida, a seguinte mensagem será exibida em seu terminal:
Com a instalação do ESP-IDF concluída, podemos agora obter o núcleo Arduino para os microcontroladores ESP32. Para fazer isso iremos fazer uma cópia deste repositório dentro da pasta de componentes do ESP-IDF:
cd ~/esp/esp-idf/components/
git clone --recursive https://github.com/espressif/arduino-esp32 arduino
Caso as classes USBHID são necessárias em seu projeto, é preciso clonar dois repositórios adicionais para o funcionamento correto da aplicação:
cd ~/esp
git clone https://github.com/espressif/esp32-arduino-lib-builder.git
git clone https://github.com/hathach/tinyusb.git esp32-arduino-lib-builder/components/arduino_tinyusb/tinyusb
Criando um Projeto com Arduino no ESP-IDF
Com os requisitos preparados, estamos prontos para criar um projeto do ESP-IDF que utilize as APIs do Arduino. Para facilitar esta etapa, podemos criar uma cópia de algum exemplo já existente e alterá-lo conforme a necessidade. Vamos utilizar o projeto de exemplo presente na ferramenta:
cd ~/esp/esp-idf
cp -rf examples/get-started/sample_project/ examples/get-started/arduino
cd examples/get-started/arduino
Novamente, caso deseje utilizar as classes USBHID, alterações são necessárias no arquivo CMakeLists.txt na pasta do projeto para configurar a variável EXTRA_COMPONENT_DIRS. Para isso, adicione a linha que inicia com “set” em algum lugar entre “cmake_minimum_required” e “project”:
Antes de começar a desenvolver, o núcleo do Arduino requer que o Tick Rate do FreeRTOS esteja configurado para 1000 Hz. Para isso, precisamos primeiro gerar o arquivo sdkconfig para podermos alterar essa informação. Isto pode ser feito através de qualquer comando que gera as configurações para determinado chip. Nesse exemplo utilizaremos a placa ESP32-DevKitC V4 da Espressif. Para configurar o projeto para o ESP32, executamos no terminal:
idf.py set-target esp32
O comando irá falhar com a mensagem de erro a seguir. Isso é esperado e o arquivo que precisamos alterar foi gerado com sucesso.

Para alterá-lo para o valor correto, podemos abrir o arquivo e editar manualmente ou executar o seguinte comando de substituição:
sed -i 's/^\(CONFIG_FREERTOS_HZ=\).*/\11000/' sdkconfig
Como os sketches do Arduino usam C++, precisamos, também, alterar a extensão do arquivo main para .cpp tanto no próprio arquivo quanto em CMakeLists.txt (ambos na pasta main). Isso pode ser feito manualmente ou executando os seguintes comandos:
mv main/main.c main/main.cpp
sed -i 's/main\.c/main.cpp/g' main/CMakeLists.txt
Neste momento temos duas opções de como estruturar nosso código: Utilizar o setup() e loop() do Arduino ou o app_main() do ESP-IDF. Esta escolha é feita com base na opção: Autostart Arduino setup and loop on boot localizada no menu Arduino Configuration dentro do menuconfig. Caso esta opção esteja habilitada, setup() e loop() serão esperados no código-fonte. Caso contrário, o tradicional app_main() será utilizado. Para acessar os menus, basta executar idf.py menuconfig.
Para alterar alguma opção, utilize as setas do teclado para movimentar o cursor e Enter ou Espaço para acessar ou modificar a opção selecionada. Após finalizado, aperte Q e Y para salvar e sair.
Após essas alterações, podemos começar a implementar nossa aplicação utilizando as APIs do Arduino com base em nossa opção selecionada.
Opção 1: setup() e loop()
Caso opte por utilizar uma estrutura de código similar à do Arduino, a única alteração que precisamos fazer é garantir que o arquivo Arduino.h (que normalmente é adicionado de forma autônoma) esteja incluído em nosso projeto. Como exemplo vamos demonstrar a seguinte aplicação:
//Este arquivo é incluído de maneira automática na IDE do Arduino
#include "Arduino.h"
void setup() {
Serial.begin(115200);
while(!Serial) { delay(10); } // Espera a Serial inicializar
}
void loop() {
// Imprime na serial a cada 1 segundo
Serial.println("Usando setup() e loop()");
delay(1000);
}
Opção 2: app_main()
Caso prefira utilizar as estruturas padrões do ESP-IDF, devemos garantir que o arquivo Arduino.h esteja incluído e que a função initArduino() seja executada no começo da aplicação. Como as bibliotecas do Arduino utilizam C++, não esqueça de adicionar extern “C” no começo da declaração de app_main(). Podemos utilizar o seguinte código-fonte como exemplo:
#include "Arduino.h"
extern "C" void app_main()
{
// Inicializa o Arduino
initArduino();
// Equivalente ao setup()
Serial.begin(115200);
while(!Serial) { delay(10); } // Espera a Serial inicializar
// Equivalente ao loop()
while(true)
{
Serial.println("Usando app_main()");
delay(1000);
}
// Caso o programa termine, o ESP32 é reiniciado
}
Executando a Aplicação em Hardware
Para compilar sua aplicação, fazer o upload para a placa e executar o monitor do ESP-IDF, utilizamos o seguinte comando (note que o número da USB dependendo do seu sistema):
idf.py -p /dev/ttyUSB0 flash monitor
Podemos, então, ver a saída do serial da placa no terminal. Caso algum erro sobre acesso a porta USB ocorra, confira este artigo (em inglês):
Para fechar o monitor basta apertar Ctrl + ].
Utilizando uma Biblioteca do Arduino
Caso seja necessário, é possível a instalação de bibliotecas externas do Arduino. Para isso devemos baixar a biblioteca e alterar o CMakeLists.txt do componente para compilar e disponibilizar a biblioteca. Pegando como exemplo uma suposta biblioteca, precisamos primeiro fazer o download da mesma na pasta libraries do componente Arduino:
cd ~/esp/esp-idf/components/arduino/
git clone --recursive git@github.com:Author/new_library.git libraries/new_libraryApós o download precisamos pegar a lista de arquivos de código-fonte adicionados pela biblioteca. Para isso podemos utilizar o comando find:
find libraries/new_library/src/ -name '*.c' -o -name '*.cpp'Esse comando deverá retornar uma lista de arquivos, como, por exemplo:
libraries/new_library/src/new_library.cpp
libraries/new_library/src/new_library_extra_file.c
Agora iremos editar o arquivo CMakeLists.txt dentro da pasta ~/esp/esp-idf/components/arduino/ para compilar a biblioteca junto de nosso projeto. Adicione a lista de arquivos obtida anteriormente ao comando iniciado com set(LIBRARY_SRCS (como demonstrado abaixo):
set(LIBRARY_SRCS
libraries/new_library/src/new_library.cpp
libraries/new_library/src/new_library_extra_file.c
libraries/ArduinoOTA/src/ArduinoOTA.cpp
libraries/AsyncUDP/src/AsyncUDP.cpp
Ainda neste arquivo, adicionamos também a pasta em que esses arquivos se encontram no comando que começa com set(includedirs:
set(includedirs
variants/${CONFIG_ARDUINO_VARIANT}/
cores/esp32/
libraries/new_library/src
libraries/ArduinoOTA/src
libraries/AsyncUDP/src
Salve e pronto! A biblioteca já está instalada e poderá ser utilizada como normalmente seria no Arduino.
Considerações Finais
Nesse tutorial você viu como instalar e utilizar o Arduino como componente do ESP-IDF e instalar bibliotecas externas do Arduino.
Para informações mais avançadas, consulte a documentação do ESP-IDF e do arduino-esp32.
Referências
Documentação arduino-esp32: https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/esp-idf_component.html
Documentação ESP-IDF: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html





Obrigado, Lucas!
git clone –recurse-submodules -b release/v5.1 https://github.com/espressif/esp-idf.git
Só assim consegui gerar o sdkconfig