ESP32 PWM (analogWrite): управление яркостью и скоростью без углублений в драйверы

ESP32 поддерживает широтно‑импульсную модуляцию (ШИМ), что позволяет плавно управлять яркостью светодиодов, скоростью вентиляторов и моторов, уровнем подсветки и т. п. В Arduino‑среде для ESP32 доступен простой, знакомый интерфейс analogWrite() — его достаточно, чтобы быстро запустить PWM без изучения низкоуровневых деталей.

Ключевые функции

  • void analogWrite(uint8_t pin, uint32_t duty); — записывает скважность (duty) на вывод pin.
  • void analogWriteResolution(uint8_t pin, uint8_t resolution); — задаёт разрешение ШИМ для пина (в битах). Диапазон значений duty будет 0 … 2resolution-1.
  • void analogWriteFrequency(uint8_t pin, uint32_t freq); — задаёт частоту ШИМ (в Гц) для пина.

Замечание: максимально возможное разрешение зависит от выбранной частоты: чем выше частота, тем меньше доступных бит. Для светодиодов часто используют 5–10 кГц с 8–12 битами; для моторов — 15–25 кГц, чтобы уйти выше слышимого диапазона.

Диапазоны значений duty

Разрешение (бит)Диапазон duty
80…255
100…1023
120…4095
130…8191

Рекомендации по пинам и подключению

  • Для ШИМ‑выходов используйте GPIO из диапазонов 4–19, 21–23, 25–27, 32–33.
  • Никогда не используйте GPIO34–39 — это входы‑только.
  • ESP32 работает на 3.3 В, выводы не 5V‑tolerant. Для светодиода — обязательно токоограничивающий резистор 220–330 Ω.

Пример 1. Плавное «мигание» светодиода

Частота 5 кГц, разрешение 8 бит (0–255). Плавный подъём/спад яркости.


#include <Arduino.h>

const uint8_t LED_PIN = 5;

void setup() {
  // Настраиваем частоту и разрешение для пина
  analogWriteFrequency(LED_PIN, 5000);    // 5 кГц
  analogWriteResolution(LED_PIN, 8);      // 8 бит → duty 0..255
}

void loop() {
  for (int d = 0; d <= 255; d++) {
    analogWrite(LED_PIN, d);
    delay(6);
  }
  for (int d = 255; d >= 0; d--) {
    analogWrite(LED_PIN, d);
    delay(6);
  }
}
  

Как это работает: при увеличении duty коэффициент заполнения ШИМ растёт — среднее напряжение на светодиоде увеличивается, яркость возрастает. При уменьшении — наоборот.

Пример 2. RGB‑светодиод: смешивание цветов

Три независимых канала PWM на 5 кГц, 8 бит. Выводим базовые и смешанные цвета.


#include <Arduino.h>

const uint8_t R_PIN = 21;
const uint8_t G_PIN = 22;
const uint8_t B_PIN = 23;

void setup() {
  // Одинаковая частота/разрешение для всех трёх каналов
  analogWriteFrequency(R_PIN, 5000);
  analogWriteResolution(R_PIN, 8);
  analogWriteFrequency(G_PIN, 5000);
  analogWriteResolution(G_PIN, 8);
  analogWriteFrequency(B_PIN, 5000);
  analogWriteResolution(B_PIN, 8);
}

void solid(uint8_t r, uint8_t g, uint8_t b, uint32_t ms) {
  analogWrite(R_PIN, r);
  analogWrite(G_PIN, g);
  analogWrite(B_PIN, b);
  delay(ms);
}

void loop() {
  solid(255,   0,   0, 800); // Красный
  solid(  0, 255,   0, 800); // Зелёный
  solid(  0,   0, 255, 800); // Синий
  solid(255, 255,   0, 800); // Жёлтый
  solid(  0, 255, 255, 800); // Голубой
  solid(255,   0, 255, 800); // Пурпурный
  solid(128,  32, 255, 800); // Произвольный оттенок
}
  

Как это работает: каждый из трёх каналов управляет яркостью соответствующего кристалла RGB‑светодиода. Комбинируя скважность, получаем любой цвет.

Пример 3. Регулятор скорости/яркости от потенциометра

Частота 20 кГц (выше слышимого диапазона), разрешение 12 бит для более тонкой градации. Значение с потенциометра (ADC) масштабируем в duty.


#include <Arduino.h>

const uint8_t PWM_PIN   = 19;  // Выход PWM (к драйверу/LED)
const uint8_t POT_PIN   = 34;  // Вход ADC (только-вход) - потенциометр
const uint8_t RES_BITS  = 12;  // 12 бит → duty 0..4095
const uint32_t F_PWM    = 20000; // 20 кГц

void setup() {
  Serial.begin(115200);
  analogWriteFrequency(PWM_PIN, F_PWM);
  analogWriteResolution(PWM_PIN, RES_BITS);
  analogReadResolution(12); // чтобы сопоставить с 12-битным duty
}

void loop() {
  int raw = analogRead(POT_PIN);        // 0..4095 (ESP32 ADC 12 бит)
  // Масштабируем ADC к duty (0..4095)
  uint32_t duty = (uint32_t)raw;        // при совпадающих разрядностях просто берём сырой ADC
  analogWrite(PWM_PIN, duty);

  // Телеметрия
  static uint32_t t0 = 0;
  if (millis() - t0 > 300) {
    t0 = millis();
    Serial.printf("ADC=%4d  duty=%4lu\r\n", raw, duty);
  }
}
  

Как это работает: с потенциометра читается 12‑битное значение, которое напрямую подаётся как duty того же разряда. Частота 20 кГц исключает акустический писк при управлении вентиляторами/моторами.


Типовые сочетания частоты и разрешения

ЗадачаЧастота (Гц)Разрешение (бит)Комментарий
Яркость LED5 000–10 0008–12Без мерцания, плавные градации
Мотор/вентилятор18 000–25 0008–11Выше слышимого диапазона
Подсветка/дисплей1 000–20 0008–12Подбирайте на глаз/по шуму

Подсказка: если выставили слишком высокую частоту и «не берётся» выбранное разрешение, уменьшите число бит. Для отладки начните с 5 кГц и 8 бит, затем повышайте частоту и/или разрядность.

Частые ошибки

  • Использование пинов 34–39 как выхода — они вход‑только, ШИМ не получится.
  • Слишком маленькая частота → заметное мерцание LED.
  • Слишком большая частота при высоком разрешении → канал не стартует/яркость «ступенчатая». Снижайте разрядность.
  • Подключение LED без резистора, нагрузок напрямую к GPIO — используйте резистор и соответствующие драйверы.

Итоги

analogWrite() на ESP32 позволяет быстро поднять PWM: задайте analogWriteFrequency(pin, freq), analogWriteResolution(pin, bits), затем меняйте duty через analogWrite(pin, value). Этого достаточно для подавляющего большинства задач — от плавной подсветки до управления вентиляторами и простыми моторами.

<< Проекты << Все товары >> Статьи, уроки >>

Написать отзыв

Примечание: HTML разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Калькуляторы для радиолюбителей и электронщиков

Калькуляторы для радиолюбителей и электронщиков

Онлайн-калькуляторы для расчёта напряжения, тока, сопротивления, делителя напряжения, резистора для ..

lm358dr сдвоенный операционный усилитель

lm358dr сдвоенный операционный усилитель

LM358DR - двухканальный операционный усилитель с низким потреблением, разработанный компанией Texas ..

3.53грн.

Осциллограф на ардуино

Осциллограф на ардуино

Простой осциллограф своими руками без паяльникаОсциллографы бывают дорогие или очень дорогие. Как же..

Держатель аккумулятора 3,7В типа 18650

Держатель аккумулятора 3,7В типа 18650

Держатель для цилиндрических аккумуляторов типа 18650 на 3,7В..

32.03грн.

Термопара K-типа 0...600°C с преобразователем MAX6675

Термопара K-типа 0...600°C с преобразователем MAX6675

Термопара хромель-алюмель рассчитана на измерение температуры в диапазоне 0 ... 600 °CДлина каб..

165.83грн.