GPIO initialization on the ESP32 in ESP-IDF
This is just a quick post on how not to initialize a GPIO in ESP-IDF. A tutorial on Embedded Explorer discusses GPIO use in ESP-IDF and suggests initialization in this way:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define LED_PIN GPIO_NUM_32
#define BUTTON_PIN GPIO_NUM_36
void app_main(void)
{
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT);
while(1) {
if (gpio_get_level(BUTTON_PIN) == 0) { // If button is pressed
gpio_set_level(LED_PIN, 1); // Turn the LED on
} else {
gpio_set_level(LED_PIN, 0); // Turn the LED off
}
vTaskDelay(1); // Add 1 tick delay (10 ms) so that current task does not starve idle task and trigger watchdog timer
}
}
This of course works, but I wanted to clear up matters because I think this takes some major shortcuts. Here is what I would suggest instead:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_err.h"
#define LED_PIN GPIO_NUM_32
#define BUTTON_PIN GPIO_NUM_36 // classic ESP32: input-only, no internal pullups
static void gpio_init(void)
{
// LED output
gpio_config_t out_conf = {
.pin_bit_mask = 1ULL << LED_PIN,
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
ESP_ERROR_CHECK(gpio_config(&out_conf));
// Button input (assume external pull-up; pressed pulls to GND)
// GPIO36 can't do internal pulls on classic ESP32, though
gpio_config_t in_conf = {
.pin_bit_mask = 1ULL << BUTTON_PIN,
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
ESP_ERROR_CHECK(gpio_config(&in_conf));
}
void app_main(void)
{
gpio_init();
while (1) {
int pressed = (gpio_get_level(BUTTON_PIN) == 0);
gpio_set_level(LED_PIN, pressed);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
The problem with the original code which is simply calling gpio_set_direction() is that in more complex code, other portions of the code may be doing something to your GPIO configuration; so it’s better to be explicit about the configuration. It’s just a good habit to specific exactly what you intend in the GPIO configuration. Never assume prior state. This isn’t Arduino.