🌗 PWM روی ESP32 با ledc: کم و زیاد کردن نور LED
در آردوینو اونو برای کمنور کردن LED از analogWrite استفاده میکنیم. ESP32 برای این کار یک بخش مخصوص و قدرتمند دارد به اسم ledc. در این قسمت از آموزش ESP32 یاد میگیریم با ledc یک چراغ «نفسکش» بسازیم که نرم روشن و خاموش میشود، و بعد نورش را با یک ولوم کنترل کنیم. مثل همیشه همهچیز را در شبیهساز ESP32 فارسی امتحان میکنیم؛ همان نوع تجربهای که در ووکوی (Wokwi) داری، ولی با توضیح فارسی.
PWM یعنی چه؟
پین دیجیتال فقط دو حالت دارد: روشن یا خاموش. PWM یعنی پین را خیلی سریع، مثلاً پنج هزار بار در ثانیه، روشن و خاموش کنیم. اگر بیشتر وقت روشن باشد، LED پرنور به نظر میرسد و اگر کمتر، کمنور. به درصد روشن بودن «دیوتی سایکل» میگویند. چشم ما آنقدر سریع نیست که چشمکها را ببیند و فقط میانگین نور را میبیند.
قطعهها و سیمکشی
| قطعه | پایه | به |
|---|---|---|
| LED + مقاومت ۲۲۰ اهم | آند (از طریق مقاومت) | GPIO4 |
| LED | کاتد | GND |
| پتانسیومتر (برای بخش دوم) | دو پایهی کناری / وسط | 3V3 و GND / GPIO34 |
کد ۱: چراغ نفسکش
این کد برای هستهی ESP32 نسخهی ۳ (Arduino-ESP32 3.x) نوشته شده که دستورهایش سادهتر است:
// ESP32 PWM with the LEDC unit (Arduino-ESP32 core 3.x)
const int LED = 4;
const int FREQ = 5000; // 5000 pulses per second: too fast to see flicker
const int BITS = 10; // 10-bit resolution: duty goes 0..1023
void setup() {
Serial.begin(115200);
ledcAttach(LED, FREQ, BITS); // pin, frequency, resolution
Serial.println("Fading with ledc, 0..1023");
}
void loop() {
for (int duty = 0; duty <= 1023; duty += 16) {
ledcWrite(LED, duty); // core 3.x: write to the PIN
delay(10);
}
for (int duty = 1023; duty >= 0; duty -= 16) {
ledcWrite(LED, duty);
delay(10);
}
}
توضیح خط به خط
FREQ = 5000فرکانس PWM. برای LED هر عددی بالای چند صد هرتز خوب است؛ ۵۰۰۰ انتخاب رایجی است.BITS = 10دقت. با ۱۰ بیت، دیوتی از ۰ تا ۱۰۲۳ است؛ یعنی ۱۰۲۴ پلهی نور، خیلی نرمتر از ۲۵۶ پلهی اونو.ledcAttach(LED, FREQ, BITS);پین را به واحد PWM وصل میکند. دیگرpinModeلازم نیست.ledcWrite(LED, duty);مقدار نور را تعیین میکند. صفر یعنی خاموش و ۱۰۲۳ یعنی کاملاً روشن.- دو حلقهی
forیکی بالا میرود و یکی پایین؛ نتیجه، نفس کشیدن آرام چراغ است.
ledcAttach را نمیشناسد. آنجا باید با «کانال» کار کنی: ledcSetup(0, 5000, 10); ledcAttachPin(4, 0); ledcWrite(0, duty); که در آن عدد اول ledcWrite شمارهی کانال است، نه پین.کد ۲: نور با پتانسیومتر
// Knob on GPIO34 sets the LED brightness (core 3.x)
const int LED = 4;
const int KNOB = 34;
void setup() {
ledcAttach(LED, 5000, 12); // 12-bit: 0..4095, same range as analogRead
}
void loop() {
int value = analogRead(KNOB); // 0..4095 on ESP32
ledcWrite(LED, value);
delay(20);
}
نکتهی قشنگ این کد این است که ADC ورودی ESP32 هم ۱۲ بیتی است (۰ تا ۴۰۹۵). وقتی دقت PWM را هم ۱۲ بیت بگذاریم، عدد خواندهشده را بدون map مستقیم به LED میدهیم.
امتحانش کن
کد اول بهصورت آماده در تینکرکد فارسی هست: کم و زیاد شدن نور با ledc (خواندن رایگان، اجرای ESP32 با اشتراک Plus). درس «PWM در ESP32 با ledc» همین را با تمرین درس میدهد و اگر میخواهی اصل PWM را اول روی اونو یاد بگیری، مقالهی PWM در آردوینو را بخوان.
اشکالهای رایج
- خطای «ledcAttach was not declared»: هستهی نسخهی ۲ داری. یا هسته را بهروز کن یا از روش کانالی بالا استفاده کن.
- LED فقط خاموش و روشن میشود و نرم نیست: دیوتی را بیشتر از حداکثر دادهای. با ۸ بیت سقف ۲۵۵ است، نه ۱۰۲۳.
- پتانسیومتر کار نمیکند: پایهی کناری را به 5V وصل کردهای. ورودی ESP32 حداکثر ۳٫۳ ولت را تحمل میکند؛ از 3V3 استفاده کن.
- با روشن کردن وایفای عدد ورودی خراب میشود: از پینهای ADC2 (مثل GPIO25 تا ۲۷) استفاده کردهای. پینهای ۳۲ تا ۳۹ با وایفای مشکلی ندارند.
قبلی را نخواندهای؟ اولین پروژهی ESP32: چشمکزن دو LED. همین ledc بعداً در داشبورد خانهی هوشمند سرعت پنکه را کنترل میکند. همهی آموزشها در صفحهی ESP32.
چراغ نفسکش ESP32 را باز کن 🌗