Уроки / Урок 7

ШИМ: плавная яркость

Плавно зажигаем светодиод и управляем яркостью потенциометром.

Цифровой вывод умеет только 0 или 3,3 В. Чтобы светодиод светился вполсилы, его очень быстро включают и выключают — тысячи раз в секунду. Глаз видит среднюю яркость. Это ШИМ (широтно-импульсная модуляция). У ESP32 ШИМ можно вывести на любой вывод, работающий на выход.

const int LED = 2;

void setup() {
  ledcAttach(LED, 5000, 8);  // вывод, частота 5 кГц, 8 бит (0…255)
}

void loop() {
  for (int d = 0; d <= 255; d++) { ledcWrite(LED, d); delay(4); }  // разгорается
  for (int d = 255; d >= 0; d--) { ledcWrite(LED, d); delay(4); }  // гаснет
}

Яркость от потенциометра

Соединим два урока: потенциометр на GPIO34 из прошлого урока задаёт яркость.

const int LED = 2;
const int POT = 34;

void setup() {
  ledcAttach(LED, 5000, 8);
}

void loop() {
  int duty = map(analogRead(POT), 0, 4095, 0, 255);
  ledcWrite(LED, duty);
  delay(10);
}
  • ledcAttach(вывод, частота, разрядность) включает ШИМ на выводе.
  • ledcWrite(вывод, скважность) задаёт долю времени во включённом состоянии: 0 — выключен, 255 — полностью включён.
  • map() пересчитывает число из одного диапазона в другой: 0…4095 в 0…255.

Ошибка ledcSetup was not declared? Это пример для старого ядра 2.x. В ядре 3.x вместо пары ledcSetup() + ledcAttachPin() используется одна функция ledcAttach(), а ledcWrite() принимает номер вывода, а не канала.

Глаз воспринимает яркость нелинейно: между 200 и 255 разница почти не видна, а между 0 и 20 — огромная. Для плавности попробуйте duty = v * v / 255.