terça-feira, 23 de junho de 2026

Meu primeiro Projeto no Espressif ESP-IDF!

ESP-IDF. Primeiro Blink minimalista comentado!


Meu primeiro piscaLED. (enxuto no úrtimo)
   Vamos criar um novo projeto no vscode via Espressif ESP-IDF, para este projeto, vou usar o ESP32-Devkit 



1. Procure (se tiver instalado o ícone da espressif)
2. Em  "Commands/Advanced" clique em "New Project Wizard"

 




3. No Topo, a direita dos menus, podera aparecer escolha a versão da IDE, 
escolha a versão 6 e no Painel a direita nomeado New Project, escolha em ESP-IDF Templates a opção: sample_project   

 




4- Clique no botão azul "Create project using template sample_project"
 No diálogo abaixo: escolha a placa ESP a ser usada: Pode ser qualquer ESP32, 
No exemplo irei usar a ESP32 Devkit e para ela, escolha em 
5- IDF_TARGET: ESP32
6- ESP-IDF Board: ESP_WROVER-KIT 3.3V
7- serial port: deixe em detect ou  escolha a porta serial onde sua placa esta conectada
8- Clique em Create Project
 
(Nota: ESP32-DevKIT vem com o  clássico ESP32) 
 



Em seguida, o sistema vai criar a estutrura das pastas e aparecerá o botao Open Project







Uma vez que o projeto foi criado, voce verá sua IDE como esta abaixo:



Painel a Esquerda: Explorador do Projeto, a Direita a area de edição dos arquivos:
1- Clique em  main.c
2- A direita vemos o  conteúdo do  arquivo
Para rodar o  código, no rodapé existe diversos ícones, no painel da  Espressif, podemos ligar ou não aqueles botões do rodapé, vamos conhecer os principais:






1-Acesso remoto (acesso por SSH por exemplo)
2- Porta Serial onde seu device esta conectado
3- Plataforma  Alvo (troque se mudar de placa)
4- Menu-Config (abre as propriedades do projeto atual)
5- idf.py fullclean (limpa do projeto o binário construido,  arquivos compilados, fica somente os sources.
6- idf.py build (Compila o projeto)
7- idf.py flash (Grava o binário gerado no alvo (Placa ESP32 na porta selecionada)
8- idf.py monitor (Abre um terminal Serial, que mostra tudo que sai pela Serial da placa ESP32 em execução)
9- idf.py build flash monitor (automatiza fazendo sequencialmente: compila, grava e chama o  monitor Serial)
10- Abre um terminal de linha de comando, na pasta do projeto. permite que voce mesmo possa inserir comandos manualmente via teclado. 

Voce poderá usar tanto os botões do rodapé, quanto abrir a linha de comando e executar os comandos manualmente.  Vamos colocar as mãos na  massa!
No proximo artigo, vamos mudar o código para uma versão enxuta do blink e ir evoluindo em seguida!

Um blink Chique no úrtimo!

No artigo anterior, criamos um  novo projeto no Microsoft Visual Code via Espressif ESP-IDF.
Agora, com o  projeto  criado, vamos mudar o  template basico para o nosso  projeto BLINK otimizado: Substitua o conteúdo do main.c para o  código  abaixo:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define BLINK_GPIO 2 
static const char *TAG = "PISCA";

void app_main(void)
{
    gpio_reset_pin(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

    while (1) {
        ESP_LOGI(TAG, "LED 2 LIGADO");
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(pdMS_TO_TICKS(1000));&nbsp

        ESP_LOGI(TAG, "LED 2 DESLIGADO");
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}


Faça o build, o flash e o monitor e veremos o led piscar na placa. sua IDE deverá estar mais ou menos assim:

Com o código rodando, vamos estudar o que as linhas dizem:

Entendendo o novo código

as primeiras linhas

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define BLINK_GPIO 2 
static const char *TAG = "PISCA";
vamos separar em dois blocos: O primeiro bloco: temos as linhas iniciando com
#include
estas linhas são diretivas de importação de bibliotecas, uma Biblioteca nada mais é que um arquivo .h e arquivo .c ou .cpp com as funções agrupadas para uma certa funcionalidade. stdio.h é uma biblioteca padrão da linguagem C. Note que ela esta sob os caracteres "<" e ">" Esse caractere diz ao compilador que é uma biblioteca padrão do sistema. O compilador sabe onde encontrar. Em seguida, temos o
#include "freertos/freertos.h"
que esta sob áspas. Essas aspas dizem que o arquivo fica na pasta components dentro da pasta esp-idf, onde reside o compilador:
 ~/.espressif/v6.0.1/esp-idf/components/
freertos.h contém funções para o programa possa interagir com o sistema operacional freertos que esta rodando por baixo da aplicação. O freertos é um sistema de tempo real para diversos dispositivos. Em seguida, temos o
#include "driver/gpio.h"
Contém funções para controle do GPIO, como colocar o pino como, entrada, saida, habilitar ou não o resistor de pullup, colocar o estado do pino em zero (Baixo) ou um (alto) entre outras funções. Os programadores de Arduino choram ao ver o proximo include, no ESP-IDF não usamos Serial.print para mensagens de debug. Em seu lugar, a lib "esp_log.h" fornece por exemplo ESP_LOGI entre outras para mostrar mensagens no console. Falemos mais sobre ele, mais tarde, eu prometo! O Segundo bloco, temos uma diretiva
#define BLINK_GPIO 2
Esta diretiva do pré-processador em C que serve para definir macros,  que se o compilador encontrar BLINK_GPIO ele o substitua pelo número 2. Para quê? Estamos definindo que BLINK_GPIO será uma constante que diz qual o número do pino do led. Se precisar mudar o número do pino no futuro, só precisa mudar o valor na diretiva citada define. Isso evita muita confusão futura. por último, temos a misteriosa linha:

static const char *TAG = "BLINK";
Ela define uma constante chamada TAG que vamos usar mais tarde.
Temos agora o procedimento mais importante do código: app_main(void)
void app_main(void)
{
gpio_reset_pin(BLINK_GPIO);
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

while (1) {
ESP_LOGI(TAG, "LED 2 LIGADO");
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1000));

ESP_LOGI(TAG, "LED 2 DESLIGADO");
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

Uma função ou procedimento em c possuem a mesma estrutura, iniciam com o tipo de retorno (no nosso caso um void) que significa: Nada, ou seja, esta é um procedimento pelo contrário é uma função, que possui um tipo de retorno, um int, etc. O procedimento app_main é onde reside o nosso código principal, o conteúdo da função ou procedimento ficam dentro das chaves "{" e "}", o compilador procura esse ponto para executar o programa e vamos conhecer agora o que ela faz. gpio_reset_pin é uma função que reseta o estado do pino para  um padrão, (parando o cursor sobre a função, ele mostra dados de como a função trabalha e seu tipo de retorno). Neste caso, estamos resetando o estado do pino BLINK_GPIO (que é o  GPIO 2) para seu estado padrão.

em seguida temos:   gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); Esta linha faz o pino de GPIO 2 como pino de saída, ou seja, qualquer valor (zero ou um) que o software definir, o pino terá o valor GND (baixo) ou 3v3 (alto).

temos agora uma nova estrutura (a turma do Arduino fica receosa aqui) o temido while(1) ele faz o programa ficar rodando as instruções dentro do bloco indefinidamente. Quem vem do arduino, digamos que as instruções antes do while, seriam as instruções que rodam no procedimento setup() e o  procedimento loop() do Arduino nada mais é que um bloco  while (1) { loop(); }  

Vamos ver o que esta dentro deste bloco while(1): 

while (1) {
ESP_LOGI(TAG, "LED 2 LIGADO");
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1000));

ESP_LOGI(TAG, "LED 2 DESLIGADO");
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(pdMS_TO_TICKS(1000));
}

Aqui temos dois blocos bem parecidos: 

ESP_LOGI (é a mensagem  verde no monitor serial, TAG é aquele static const char do inicio do código  e em seguida a mensagem de informação (LOGI = log_Information) Num outro artigo vamos falar mais do poderoso log do IDF que é muito melhor que usar Serial.println do arduino. No  monitor de código, vemos assim a execução  desta função:
I (370) BLINK: LED 2 LIGADO

A instrução seguinte é bem explicativa:

gpio_set_level(BLINK_GPIO, 1);
  Esta linha coloca o pino 2 no nĩvel alto. no código  da ide Arduino equivale a digitalPin(2,HIGH); 
a proxima linha é importante; ela substituir a instrução delay(1000) do Arduino:
vTaskDelay(pdMS_TO_TICKS(1000));
Ela atrasa a task atual por um numero de TICKS como o TICK é um valor muito pequeno, usamos pdMS_TO_TICKS para transformar o numero 1000 ms (equivalente a 1 segundo) em TICKS do relógio do  ESP32. Este varia dependendo da velocidade do clock, por isso a função pdMS_TO_TICKS

o Bloco seguinte, é identico ao primeiro bloco, suas mudanças são: a mensagem do LOGI e o gpio_set_level para 0 ou Baixo(GND), temos ainda a mesma função vTaskDelay com o mesmo tempo de pausa. brinque  mudando estes valores para ver o led piscar numa frequencia diferente. 

Apesar de ser bem diferente do  mesmo código do Arduino, temos um controle muito maior do que fazemos.  Iremos evoluir este código colocando uma task! Aguardem!