Микроконтроллер ESP32 — это мощный инструмент для создания умных устройств. В этой статье мы разберем практический проект на его основе: регулятор мощности с визуальным интерфейсом. Устройство позволяет плавно управлять напряжением на нагрузке (например, яркостью светодиодной ленты, скоростью двигателя, температурой паяльника) с помощью двух кнопок и отображать текущую мощность на OLED-экране.
Для чего это нужно?
-
Образовательная цель: Изучение основ ШИМ, работы с периферией ESP32 (кнопки, дисплей) и создания простого пользовательского интерфейса.
-
Практическое применение: Создание диммера для светодиодов, регулятора оборотов вентилятора, управление нагревательными элементами с обратной связью.
1. Аппаратная часть (Что нам понадобится)
-
Плата ESP32 (любая, например, ESP32 DevKit V1).
-
OLED-дисплей на чипе SSD1306 с интерфейсом I2C.
-
N-канальный MOSFET-транзистор (например, IRFZ44N, IRLZ44N, 2N7000 или более мощный, в зависимости от нагрузки). Он выступает в роли электронного ключа.
-
Две тактовые кнопки.
-
Нагрузка для теста (например, 12В светодиодная лента + отдельный блок питания 12В).
-
Соединительные провода и макетная плата.
-
Резисторы: 10кОм (2 шт. для подтяжки кнопок) и, опционально, резистор на 100-470 Ом между пином ESP32 и затвором MOSFET для защиты от выбросов напряжения.
Схема подключения:
ESP32: GPIO32 (MOSFET_PIN) -> Затвор (G) MOSFET через резистор ~100-200 Ом GPIO21 (SDA) -> SDA дисплея GPIO22 (SCL) -> SCL дисплея GPIO26 (BTN_UP) -> Один контакт кнопки UP. Второй контакт -> +3.3V. Параллельно кнопке: резистор 10кОм к GND (подтяжка вниз). GPIO27 (BTN_DOWN) -> Аналогично кнопке DOWN. 3.3V -> VCC дисплея и кнопок GND -> Общая земля (дисплей, кнопки, исток MOSFET, минус нагрузки) MOSFET взят 2n7000: Сток (D) MOSFET -> Минус нагрузки (например, светодиодной ленты). Плюс нагрузки -> Плюс внешнего блока питания (например, +12V). Минус блока питания -> Общая земля (GND).
ВАЖНО по безопасности:
-
Если вы управляете нагрузкой с напряжением выше 5В (например, 12В, 24В, 220В), необходима гальваническая развязка (оптореле, симистор с оптодрайвером). Представленная схема с MOSFET подходит только для управления низковольтной нагрузкой, где цепь управления (ESP32) и цепь нагрузки имеют общую землю.
-
принципиальная схема ШИМ контроллера с экраном. (1 кнопка на схеме условно лишняя, на всякий случай для других проектов. (пин14))
-
Мощный MOSFET может сильно нагреваться. При больших токах используйте радиатор.

- пример собранного устройства. Работоспособность проверена.
2. Детальный разбор программного кода (скетча)
Программа состоит из нескольких логических блоков.
2.1. Настройка и инициализация (блок setup())
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
Подключаем библиотеки: Wire для работы с I2C, Adafruit_GFX и Adafruit_SSD1306 для управления дисплеем.
#define MOSFET_PIN 32 #define BTN_UP 26 #define BTN_DOWN 27
Определяем пины для удобства чтения и изменения кода.
Adafruit_SSD1306 display(128, 64, &Wire, -1); int pwmValue = 127; // Стартовое значение ШИМ (50%)
Создаем объект дисплея и переменную для хранения значения ШИМ (от 0 до 255).
void setup() { Serial.begin(115200); pinMode(MOSFET_PIN, OUTPUT); pinMode(BTN_UP, INPUT); pinMode(BTN_DOWN, INPUT);
Начинаем последовательный порт для отладки. Настраиваем пины: MOSFET — выход, кнопки — входы.
ledcAttach(MOSFET_PIN, 5000, 8); ledcWrite(MOSFET_PIN, pwmValue);
Ключевой момент: Вместо стандартного analogWrite() ESP32 использует более гибкий LEDC (LED Control) для ШИМ.
-
ledcAttach(PIN, FREQUENCY, BIT_RESOLUTION)— привязывает пин к каналу ШИМ с частотой 5 кГц и разрядностью 8 бит (256 значений). -
ledcWrite(PIN, VALUE)— устанавливает скважность ШИМ.
Wire.begin(21, 22); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); // ... настройка текста Serial.println("Система запущена"); }
Инициализируем шину I2C на пинах 21 (SDA) и 22 (SCL), запускаем дисплей с адресом 0x3C и очищаем его.
2.2. Основной цикл (блок loop())
Цикл постоянно выполняет три задачи: опрос кнопок, обновление дисплея и небольшая задержка.
Опрос кнопок:
if (digitalRead(BTN_UP) == HIGH) { pwmValue = pwmValue + 10; if (pwmValue > 255) pwmValue = 255; ledcWrite(MOSFET_PIN, pwmValue); delay(200); // Простой антидребезг }
При нажатии кнопки UP значение ШИМ увеличивается на 10. Функция delay(200) выполняет две роли: антидребезг (фильтрация механических колебаний контактов) и регулировка скорости изменения.
ВАЖНО: В реальных проектах для обработки кнопок лучше использовать библиотеки (Bounce2) или техники с отслеживанием времени (millis()), чтобы не блокировать работу системы.
Обновление дисплея:
display.clearDisplay(); display.setCursor(0,0); display.print("MOSFET PWM Test"); // ... вывод значения и процентов display.display();
Весь вывод на дисплей происходит в буфер. Команда display.display() отправляет содержимое буфера на экран.
Полный код