Уроки / Урок 9

Плавная яркость (ШИМ)

«Дышащий» светодиод и полоска яркости на экране.

Цифровой вывод умеет только включать и выключать. Но если делать это тысячи раз в секунду и менять долю времени «включено», глаз увидит промежуточную яркость. Это ШИМ (широтно-импульсная модуляция).

#include <U8g2lib.h>
#include <Wire.h>

// Встроенный экран 0.42": контроллер SSD1306, видимая область 72×40.
// Аргументы: поворот, вывод сброса (нет), SCL = GPIO6, SDA = GPIO5.
U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, 6, 5);

const int LED = 8;

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

void show(int level) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.drawStr(0, 10, "PWM");
  u8g2.setCursor(36, 10);
  u8g2.print(level * 100 / 255);
  u8g2.print("%");
  u8g2.drawFrame(0, 20, 72, 14);
  u8g2.drawBox(2, 22, map(level, 0, 255, 0, 68), 10);
  u8g2.sendBuffer();
}

void loop() {
  for (int level = 0; level <= 255; level += 5) {
    ledcWrite(LED, 255 - level);  // светодиод инверсный: 0 = ярче всего
    show(level);
    delay(15);
  }
  for (int level = 255; level >= 0; level -= 5) {
    ledcWrite(LED, 255 - level);
    show(level);
    delay(15);
  }
}

ledcAttach() и ledcWrite(вывод, ...) — это API ядра ESP32 версии 3.x. В старых примерах из интернета встречаются ledcSetup() и ledcAttachPin(): они относятся к версии 2.x и в 3.x не компилируются.