Микроконтроллер ESP32, благодаря своей производительности и встроенным модулям Wi-Fi и Bluetooth, стал популярной платформой для разработки проектов Интернета вещей (IoT) и встраиваемых систем. Одной из первых задач, с которой сталкиваются начинающие разработчики, является управление светодиодом – классическая программа "Blink". Простейший способ – использовать функцию delay()
. Однако она полностью блокирует выполнение программы на заданное время. Для простых задач это приемлемо, но если нужно одновременно выполнять другие операции (опрашивать датчики, проверять кнопки, обмениваться данными по сети), delay()
становится непригодной.
Данный урок демонстрирует, как реализовать выполнение нескольких задач псевдопараллельно на ESP32, избегая delay()
. В качестве примера рассмотрим мигание светодиодом с одновременной проверкой состояния кнопки, используя неблокирующий подход на основе функции millis()
.
delay()
.millis()
.Описанный метод применим не только к светодиодам, но и к любым задачам, требующим выполнения действий через определенные интервалы без блокировки основного цикла.
Примечание: Это руководство посвящено программированию ESP32 на Arduino (C/C++) через Arduino IDE. Если вы предпочитаете MicroPython, обратитесь к руководству: ESP32 MicroPython - LED - Blink.
Кол-во | Компонент | Примечание |
---|---|---|
1 | Отладочная плата ESP32 (например, ESP-WROOM-32 Dev Module) | |
1 | USB-кабель Type-A <-> Type-C | Для ПК с USB-A портом |
1 | Светодиод (красный) | |
1 | Резистор 220 Ом | Для ограничения тока светодиода |
1 | Кнопка тактовая для макетной платы с колпачком | |
1 | Макетная плата (Breadboard) | |
1 | Соединительные провода (Jumper Wires) |
Есть отдельные руководства по светодиодам и кнопкам. Они содержат подробную информацию о распиновке, принципах работы, схемах подключения и примерах кода.
На схеме ниже показано подключение светодиода (через резистор) и кнопки к пинам GPIO ESP32. Кнопка подключена к GND и пину GPIO с внутренним подтягивающим резистором (INPUT_PULLUP).
Рассмотрим два варианта кода для мигания светодиодом и проверки состояния кнопки.
/* * Сравнение: delay() против millis() в ESP32. * https://arduino-tex.ru/news/209/sravnenie-delay-protiv-millis-v-esp32.html */ #define LED_PIN 21 // Пин GPIO21 ESP32, подключенный к светодиоду #define BUTTON_PIN 18 // Пин GPIO18 ESP32, подключенный к кнопке #define BLINK_INTERVAL 1000 // Интервал мигания светодиода (миллисекунды) // Переменные: int ledState = LOW; // Текущее состояние светодиода (LOW - выключен) int previousButtonState = HIGH; // Предыдущее состояние кнопки (HIGH, т.к. INPUT_PULLUP) void setup() { Serial.begin(115200); // Инициализация последовательного порта pinMode(LED_PIN, OUTPUT); // Пин светодиода как выход // Пин кнопки как вход с подтягивающим резистором: pinMode(BUTTON_PIN, INPUT_PULLUP); previousButtonState = digitalRead(BUTTON_PIN); // Начальное состояние кнопки } void loop() { // Инвертируем состояние светодиода: ledState = (ledState == LOW) ? HIGH : LOW; digitalWrite(LED_PIN, ledState); // Установить новое состояние // !!! КРИТИЧЕСКИЙ МОМЕНТ: Ожидание BLINK_INTERVAL миллисекунд !!! delay(BLINK_INTERVAL); // ESP32 НЕ МОЖЕТ выполнять другие действия // Проверка состояния кнопки int currentButtonState = digitalRead(BUTTON_PIN); if (currentButtonState != previousButtonState) { Serial.println(currentButtonState); // Вывод состояния previousButtonState = currentButtonState; // Сохранить состояние } // ЗДЕСЬ МОГЛИ БЫ БЫТЬ ДРУГИЕ ОПЕРАЦИИ, но они выполняются реже из-за delay() }
Краткие инструкции:
Ожидаемый результат delay():
(Не все нажатия будут зарегистрированы)
Во время delay(BLINK_INTERVAL)
ESP32 не выполняет цикл loop()
. Нажатия в этот интервал не будут обнаружены.
/* * Сравнение: delay() против millis() в ESP32. * https://arduino-tex.ru/news/209/sravnenie-delay-protiv-millis-v-esp32.html */ #define LED_PIN 21 // Пин GPIO21 ESP32, подключенный к светодиоду #define BUTTON_PIN 18 // Пин GPIO18 ESP32, подключенный к кнопке #define BLINK_INTERVAL 1000 // Интервал мигания светодиода (миллисекунды) // Переменные: int ledState = LOW; // Текущее состояние светодиода int previousButtonState = HIGH; // Предыдущее состояние кнопки unsigned long previousMillis = 0; // Время последнего изменения светодиода void setup() { Serial.begin(115200); pinMode(LED_PIN, OUTPUT); pinMode(BUTTON_PIN, INPUT_PULLUP); previousButtonState = digitalRead(BUTTON_PIN); // Начальное состояние } void loop() { unsigned long currentMillis = millis(); // Текущее время // Проверяем, прошло ли достаточно времени: if (currentMillis - previousMillis >= BLINK_INTERVAL) { // Инвертируем состояние: ledState = (ledState == LOW) ? HIGH : LOW; digitalWrite(LED_PIN, ledState); previousMillis = currentMillis; // Сохраняем время } // --- Проверка состояния кнопки --- (выполняется в КАЖДОЙ итерации) int currentButtonState = digitalRead(BUTTON_PIN); if (currentButtonState != previousButtonState) { Serial.println(currentButtonState); previousButtonState = currentButtonState; } // --- ЗДЕСЬ МОЖНО ДОБАВИТЬ ДРУГИЕ НЕБЛОКИРУЮЩИЕ ЗАДАЧИ --- }
Объяснение millis():
millis()
возвращает миллисекунды с момента запуска ESP32.
previousMillis
.loop()
получаем текущее время: currentMillis = millis();
.currentMillis - previousMillis
.BLINK_INTERVAL
, выполняем действие.previousMillis = currentMillis;
.Цикл loop()
выполняется быстро, позволяя другим частям кода выполняться почти непрерывно.
Краткие инструкции (millis()):
Ожидаемый результат millis():
(Все нажатия зарегистрированы)
Данный подход позволяет ESP32 управлять светодиодом и реагировать на события.
Комментарии в коде содержат детальные объяснения.
Используя millis()
, можно управлять несколькими задачами. Пример с двумя светодиодами (1000 мс и 500 мс) и кнопкой.
Подключите второй светодиод (с резистором) к GPIO22.
/* * Сравнение: delay() против millis() в ESP32. * https://arduino-tex.ru/news/209/sravnenie-delay-protiv-millis-v-esp32.html */ #define LED_PIN_1 22 // Пин GPIO22, Светодиод 1 #define LED_PIN_2 21 // Пин GPIO21, Светодиод 2 #define BUTTON_PIN 18 // Пин GPIO18, кнопка #define BLINK_INTERVAL_1 1000 // Интервал Светодиода 1 (мс) #define BLINK_INTERVAL_2 500 // Интервал Светодиода 2 (мс) // Переменные для Светодиода 1: int ledState_1 = LOW; unsigned long previousMillis_1 = 0; // Переменные для Светодиода 2: int ledState_2 = LOW; unsigned long previousMillis_2 = 0; // Переменные для кнопки: int previousButtonState = HIGH; void setup() { Serial.begin(115200); pinMode(LED_PIN_1, OUTPUT); pinMode(LED_PIN_2, OUTPUT); pinMode(BUTTON_PIN, INPUT_PULLUP); previousButtonState = digitalRead(BUTTON_PIN); } void loop() { unsigned long currentMillis = millis(); // Текущее время // --- Управление Светодиодом 1 --- if (currentMillis - previousMillis_1 >= BLINK_INTERVAL_1) { ledState_1 = (ledState_1 == LOW) ? HIGH : LOW; digitalWrite(LED_PIN_1, ledState_1); previousMillis_1 = currentMillis; // Обновляем время } // --- Управление Светодиодом 2 --- if (currentMillis - previousMillis_2 >= BLINK_INTERVAL_2) { ledState_2 = (ledState_2 == LOW) ? HIGH : LOW; digitalWrite(LED_PIN_2, ledState_2); previousMillis_2 = currentMillis; // Обновляем время } // --- Проверка состояния кнопки --- int currentButtonState = digitalRead(BUTTON_PIN); if (currentButtonState != previousButtonState) { Serial.println(currentButtonState); previousButtonState = currentButtonState; } // --- ЗДЕСЬ МОЖНО ДОБАВИТЬ ЕЩЕ ЗАДАЧ --- }
Пояснение: Для каждого светодиода свой набор переменных. Цикл loop()
выполняется быстро, создавая псевдо-многозадачность.
Заключение.
Мы рассмотрели проблему delay()
и показали альтернативу – millis()
. delay()
останавливает программу, а millis()
позволяет проверять интервалы без остановки.
Преимущества millis():
Освонова с millis()
– ключевой шаг для сложных проектов на ESP32. Этот паттерн широко применяется при работе с сенсорами, сетевыми протоколами и интерфейсами.
Дополнительная информация к данному уроку:
Понравился урок: Сравнение: delay() против millis() в ESP32? Не забудь поделиться с друзьями в соц. сетях.
А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в Telegram.
Спасибо за внимание!
Технологии начинаются с простого!
Фотографии к статье
Файлы для скачивания
![]() |
Код - Мигание светодиодом с использованием delay().ino | 2 Kb | 24 | Скачать |
![]() |
Код - Мигание светодиодом с использованием millis().ino | 2 Kb | 19 | Скачать |
![]() |
Код 3 - Добавление дополнительных задач .ino | 2 Kb | 18 | Скачать |
Уроки ESP32 (заметки)
26 марта , 2025
Комментариев:0
Файлов для скачивания:3
Фото:6
Понравилась статья? Нажми
Виджеты для Easy HMI
Читайте также
Мы в соц сетях
Комментарии