← До всіх проєктів
Основи Початковий

Потенціометр і ШІМ: АЦП ESP32 керує яскравістю світлодіода

Читаємо напругу з потенціометра через 12-бітний АЦП і перетворюємо її на ШІМ за допомогою LEDC. Розбираємо, чому брати ADC1, а не ADC2, і як працює широтно-імпульсна модуляція.

Складність
Початковий
Час
30 min
Категорія
Основи
Оновлено

Про проєкт

Двоє базових «перекладачів» між світом аналогових величин і цифровою програмою: АЦП перетворює напругу на число, а ШІМ — число на «середню» напругу. Крутимо ручку потенціометра, і світлодіод плавно змінює яскравість.

Що знадобиться

  • ESP32 DevKit
  • Потенціометр 10 кОм
  • Світлодіод і резистор 220 Ом

Схема

Деталь Підключення
Потенціометр, крайні виводи 3V3 і GND
Потенціометр, середній (повзунок) GPIO34
Світлодіод GPIO25 → 220 Ом → анод; катод → GND

Потенціометр працює як дільник напруги: повзунок видає від 0 до 3.3 В залежно від положення ручки.

АЦП: від напруги до числа

analogRead() на ESP32 повертає 0…4095 (12 біт). Кілька нюансів:

  • Беріть виводи ADC1 (GPIO32–39). ADC2 (GPIO0, 2, 4, 12–15, 25–27) не працює, коли ввімкнено Wi-Fi.
  • Шкала нелінійна біля країв: приблизно до 0.1 В і понад 3.1 В точність падає. Для точних вимірювань використовуйте analogReadMilliVolts(): він враховує заводську калібровку.
  • Ніколи не подавайте на вхід понад 3.3 В.

ШІМ: від числа до яскравості

Світлодіод не вміє світити «наполовину», але його можна дуже швидко вмикати й вимикати. Якщо 5000 разів на секунду тримати його ввімкненим 30 % часу, око бачить 30 % яскравості. Частка часу «увімкнено» називається коефіцієнтом заповнення (duty cycle).

В ESP32 за ШІМ відповідає апаратний блок LEDC. В ядрі arduino-esp32 3.x:

  • ledcAttach(pin, freq, bits) — прив'язує вивід, задає частоту й розрядність;
  • ledcWrite(pin, duty) — задає заповнення від 0 до 2^bits − 1.

Код

// Потенціометр (АЦП) → яскравість світлодіода (ШІМ LEDC)
const int POT_PIN = 34;   // ADC1: працює й з увімкненим Wi-Fi
const int LED_PIN = 25;

void setup() {
  Serial.begin(115200);
  ledcAttach(LED_PIN, 5000, 8);   // 5 кГц, 8 біт (0..255)
}

void loop() {
  int raw = analogRead(POT_PIN);             // 0..4095
  int duty = map(raw, 0, 4095, 0, 255);
  ledcWrite(LED_PIN, duty);
  Serial.printf("АЦП=%4d  заповнення=%3d\n", raw, duty);
  delay(200);
}

Корисно знати

  • Яскравість на око нелінійна: зміна від 0 до 10 % помітна сильніше, ніж від 80 до 100 %. Для плавного регулятора підносьте значення до квадрата: duty = raw * raw / 65793 (дає 0…255).
  • analogWrite() в ядрі 3.x теж працює, але через LEDC ви самі обираєте частоту та розрядність.
  • Частота понад ~20 кГц не чути (важливо для двигунів), а для світлодіодів вистачає 1–5 кГц.

Що далі

Той самий потенціометр може керувати сервоприводом або швидкістю двигуна через MOSFET: у симуляторі є обидва приклади.