В этом уроке мы научимся подключать кнопку к ESP32 с помощью ESP-IDF. Мы увидим, как настроить контакты GPIO в качестве цифровых входных контактов. Другими словами, мы увидим, как считывать цифровой вход с ESP32 и управлять цифровым выходом. Для демонстрации мы создадим проект ESP32 в VS Code с расширением ESP-IDF. Проект позволит читателям понять, как настроить контакты GPIO ESP32 как входные и выходные на очень простом примере, который будет включать и выключать светодиод с помощью кнопки. Мы подключим кнопку к контакту GPIO ESP32, который будет настроен как выходной контакт. Светодиод будет подключен к цифровому входному контакту платы. Значение кнопки будет считываться, и в результате светодиод загорится.
Прежде чем продолжить, убедитесь, что у вас установлена последняя версия VS Code и настроено расширение ESP-IDF:
- Установка ESP32 ESP-IDF на Windows и его интеграция с Visual Studio Code
- Установка ESP32 ESP-IDF на Linux Ubuntu
Также на нашем сайте вы можете прочитать статью про начало работы с ESP32 с использованием ESP-IDF.
Контакты GPIO ESP32 в качестве цифровых входов/выходов
Плата разработки ESP32 выпускается в различных моделях с разным количеством выводов GPIO. На рассматриваемой нами плате имеется 36 выводов GPIO. Мы можем использовать выводы в их конфигурации по умолчанию или даже изменить их в программном коде. Выводы GPIO для ESP32 DEVKIT V1 показаны на схеме ниже в их конфигурации по умолчанию.
48 выводов GPIO на микросхеме ESP32, используемой в этой плате, недоступны для подключения через платы разработки. Это означает, что не все выводы GPIO отображаются в схеме расположения контактов. ESP32 Devkit поддерживает 36 выводов GPIO, хотя не все из них могут использоваться в качестве цифровых выходных контактов. Только 24 из 30 выводов могут использоваться как для цифрового ввода, так и для вывода, из которых GPIO34-GPIO39 могут использоваться только в качестве входных контактов.
Примечание: в ESP32 DEVKIT контакты GPIO6 не подключены к GPIO11. Это связано с тем, что эти контакты внутренне соединены со встроенной SPI-флэш-памятью микросхемы ESP-WROOM-32.
На этот раз, при подключении кнопки и светодиода, мы будем использовать контакты GPIO на нашей плате ESP32 в качестве цифровых входных и цифровых выходных контактов соответственно. Контакт GPIO, подключенный к кнопке, обеспечивает цифровой вход, а контакт GPIO, подключенный к светодиоду, — цифровой выход.
На приведенной ниже схеме показаны контакты GPIO для ESP32, которые мы будем использовать для подключения кнопки и светодиода. Мы будем использовать GPIO13 для подключения светодиода и GPIO14 для подключения кнопки.
API ESP-IDF для цифрового ввода и вывода в ESP32
Прежде чем двигаться дальше, давайте обсудим некоторые важные функции, необходимые для программирования GPIO в рамках этого проекта.
ESP-IDF предоставляет библиотеку gpio.h, которая содержит полезные функции для управления цифровыми входными и выходными контактами ESP32. Для этого проекта нам потребуется установить порт в качестве входного или выходного, задать уровень выходного сигнала на выходном порту и считать данные с цифрового входного порта. Давайте посмотрим, как это будет реализовано.
Первым шагом является подключение заголовочного файла:
|
1 |
#include "driver/gpio.h" |
Установка направления работы контактов GPIO
Далее, чтобы настроить порт GPIO как вход или выход, мы будем использовать функцию gpio_set_direction(). Она принимает два аргумента. Первый аргумент — это контакт GPIO, который мы хотим настроить. Второй аргумент — это режим (вход или выход), в котором мы хотим установить контакт. Это будет либо ' GPIO_MODE_OUTPUT' , если вы хотите настроить порт как выход, либо ' GPIO_MODE_INPUT ', если вы хотите настроить порт как вход. В нашем случае мы хотим установить контакт GPIO, подключенный к светодиоду, как выходной контакт, а контакт GPIO, подключенный к кнопке, как входной контакт.
В следующей строке кода мы настраиваем GPIO27 как выходной контакт.
|
1 |
gpio_set_direction(GPIO_NUM_27, GPIO_MODE_OUTPUT); |
В следующей строке кода мы настраиваем GPIO33 как входной контакт.
|
1 |
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_INPUT); |
Установка уровня выходного сигнала цифрового контакта
Следующий шаг — установка уровня выходного сигнала порта GPIO. Для этого мы используем функцию gpio_set_level(). Она также принимает два аргумента. Первый аргумент — это контакт GPIO, состояние которого мы хотим установить. Второй аргумент — это состояние (0 или 1), которое мы хотим установить. Для установки уровня выходного сигнала контакта в состояние HIGH используйте '1' в качестве второго аргумента. Аналогично, для установки уровня выходного сигнала контакта в состояние LOW используйте '0' в качестве второго аргумента.
В следующей строке кода мы устанавливаем GPIO27 в состояние ВЫСОКОГО уровня.
|
1 |
gpio_set_level(GPIO_NUM_27, 1); |
Считывание цифрового входа (получение уровня выходного сигнала входного контакта)
Для считывания цифрового входа мы будем использовать функцию gpio_get_level(). Эта функция принимает один аргумент — номер цифрового входного контакта, с которого необходимо считать данные. Функция возвращает целое число 1 или 0, обозначающее состояние входного контакта как ВЫСОКОЕ или НИЗКОЕ соответственно.
В следующей строке кода мы считываем состояние GPIO33.
|
1 |
int gpio_get_level(GPIO_NUM_33); |
Обзор проекта подключения кнопки к ESP32
Цель нашего проекта — управление светодиодом путем считывания входного состояния контакта GPIO, подключенного к кнопке. При нажатии кнопки светодиод загорается. При отпускании кнопки светодиод гаснет.

На приведенной ниже диаграмме показана последовательность событий. Мы будем считывать состояние кнопок, которое будет либо высоким, либо низким. Если логическое состояние кнопки высокое, светодиод загорится. Аналогично, если логическое состояние кнопки низкое, светодиод погаснет.
С помощью резистора мы подключим кнопку к плате ESP32. В этом проекте можно использовать два типа резисторов: подтягивающие и отключающие. Мы будем использовать отключающие резисторы, принцип работы которых основан на том, что при нажатии кнопки входной сигнал на выводе GPIO будет находиться в высоком логическом состоянии (1), а в противном случае — в низком (0). Светодиод загорится, если логическое состояние высокое (1), и погаснет, если логическое состояние низкое (0). При использовании подтягивающих резисторов принцип работы будет обратным.
Схема управления светодиодом на ESP32 с помощью кнопки и принципиальная схема подключения оборудования
Для этого проекта нам потребуются следующие компоненты:
- Плата разработки ESP32.
- 5-мм светодиод.
- Резистор 220 Ом.
- Резистор 10 кОм.
- Макетная плата.
- Соединительные провода.
На приведенном ниже рисунке показана принципиальная схема данного проекта.
Мы использовали вывод GPIO27 для подключения к аноду светодиода через токоограничивающий резистор сопротивлением 220 Ом. Катод светодиода подключен к выводу GND микроконтроллера ESP32.
На кнопке расположены четыре контакта. ESP32 подает питание на один контакт напряжением 3,3 вольта, а второй контакт соединен через GPIO33 и подтягивающий резистор 10 кОм. Общая земля подключена к противоположному концу резистора.
Вы можете использовать любой другой подходящий цифровой выходной контакт ESP32 для подключения к светодиоду, а цифровой входной контакт ESP32 — для подключения к кнопке.
Вот как выглядит наша схема после подключения всех компонентов.
Управление светодиодом на ESP32 с помощью кнопки
Откройте VS Code и создайте новый проект ESP-IDF. Теперь перейдите к файлу main.c. Здесь мы определим функции и программный код.
Код кнопки ESP32
Это код, который мы будем использовать для управления светодиодом с помощью кнопки.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #define LED_PIN 27 #define PUSH_BUTTON_PIN 33 void app_main(void) { gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(PUSH_BUTTON_PIN, GPIO_MODE_INPUT); while(1) { if (gpio_get_level(PUSH_BUTTON_PIN) == 1) { gpio_set_level(LED_PIN, 1); } else { gpio_set_level(LED_PIN, 0); } vTaskDelay(1); } } |
Как работает код?
Для начала мы подключим необходимые библиотеки для этого проекта. Это включает библиотеку driver/gpio.h, поскольку нам нужно работать с контактами GPIO, и библиотеки FreeRTOS, так как мы хотим добавить задержку.
|
1 2 3 |
#include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" |
Мы подключили светодиод к выводу GPIO27. Поэтому мы определим переменную с именем 'LED_PIN', которая будет хранить значение вывода GPIO 27. Она будет использоваться позже в коде для управления цифровым выходом.
Мы подключили кнопку к выводу GPIO33. Поэтому мы определим переменную с именем 'PUSH_BUTTON_PIN', которая будет хранить значение вывода GPIO 33. Она будет использоваться позже в коде для считывания цифрового входа.
|
1 2 |
#define LED_PIN 27 #define PUSH_BUTTON_PIN 33 |
Настройка GPIO для цифрового ввода/вывода
Внутри функции loop следующим шагом является настройка вывода LED_PIN как выхода и вывода PUSH_BUTTON_PIN как входа. Мы зададим направление вывода как входа или выхода с помощью функции gpio_set_direction(). Эта функция принимает два аргумента. Первый аргумент — это вывод GPIO, а второй — режим (вход или выход), в котором мы хотим установить вывод. В нашем случае мы хотим установить вывод LED_PIN как выходной вывод, а вывод PUSH_BUTTON_PIN как выходной вывод.
|
1 2 |
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(PUSH_BUTTON_PIN, GPIO_MODE_INPUT); |
Далее мы прочитаем состояние контакта PUSH_BUTTON_PIN с помощью функции gpio_get_level() и передадим в качестве аргумента контакт GPIO, подключенный к кнопке. С помощью оператора if-else мы проверим, равно ли состояние этого цифрового входа «1». Если оно равно «1», что означает нажатие кнопки, то включим светодиод. В противном случае выключим светодиод. Используя функцию gpio_set_level(), мы передадим первый аргумент в качестве контакта LED_PIN, состояние которого мы хотим установить, а второй аргумент — в качестве состояния, которое мы хотим установить. Оно будет либо «1», либо «0». Когда второй аргумент равен «1», светодиод включается. Аналогично, когда второй аргумент равен «0», светодиод выключается.
|
1 2 3 4 5 6 7 8 |
if (gpio_get_level(PUSH_BUTTON_PIN) == 1) { gpio_set_level(LED_PIN, 1); } else { gpio_set_level(LED_PIN, 0); } |
Кроме того, мы добавим задержку в 1 такт (10 мс), чтобы сторожевой таймер не сработал.
|
1 |
vTaskDelay(1); |
Компиляция скетча
Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.
|
1 |
idf.py -p COMX flash monitor |
После успешной прошивки кода нажмите кнопку, чтобы включить светодиод. После отпускания кнопки светодиод погаснет.











