پایه های دیجیتال میکروکنترلر معمولا فقط دو حالت دارند: روشن یا خاموش. در بردهای 5 ولتی مانند Arduino Uno، پایه در حالت روشن تقریبا 5 ولت و در حالت خاموش صفر ولت است. در بردهای ESP8266 و ESP32 نیز سطح روشن معمولا 3.3 ولت و سطح خاموش صفر ولت است.
اما گاهی لازم است مقداری بین صفر و حداکثر ولتاژ خروجی ایجاد کنیم؛ برای مثال بخواهیم شدت نور یک LED یا سرعت یک موتور را کنترل کنیم. برای انجام این کار می توان از PWM یا مدولاسیون پهنای پالس استفاده کرد.
در PWM، پایه خروجی با سرعت زیادی روشن و خاموش می شود. با تغییر نسبت مدت روشن بودن پایه به کل زمان هر چرخه، می توان توان متوسطی را که به مصرف کننده می رسد تغییر داد. به این نسبت Duty Cycle یا چرخه کاری گفته می شود.
برای مثال، اگر پایه در نیمی از هر چرخه روشن و در نیم دیگر خاموش باشد، Duty Cycle برابر 50 درصد خواهد بود. در این حالت یک LED تقریبا نصف توان کامل را دریافت می کند و کم نورتر دیده می شود.
PWM ولتاژ آنالوگ واقعی و پیوسته تولید نمی کند. خروجی در هر لحظه یا صفر ولت است یا به حداکثر ولتاژ پایه می رسد، اما چون این تغییر با سرعت زیادی انجام می شود، LED و بسیاری از مصرف کننده ها آن را به صورت یک توان متوسط احساس می کنند. یک مولتی متر نیز ممکن است مقداری نزدیک به ولتاژ متوسط را نمایش دهد.
در یک برد آردوینو 5 ولتی، PWM با چرخه کاری 50 درصد می تواند اثری تقریبا مشابه میانگین 2.5 ولت ایجاد کند. در یک برد ESP با خروجی 3.3 ولتی، همین چرخه کاری اثری نزدیک به میانگین 1.65 ولت خواهد داشت.
برای محاسبه تقریبی ولتاژ متوسط می توان از رابطه زیر استفاده کرد:
ولتاژ متوسط = ولتاژ پایه × چرخه کاری
به عنوان مثال، اگر چرخه کاری 25 درصد باشد، ولتاژ متوسط تقریبی در آردوینو 1.25 ولت و در ESP حدود 0.825 ولت خواهد بود.
در Arduino Uno و Nano همه پایه های دیجیتال قابلیت PWM ندارند. پایه های دارای این قابلیت با علامت ~ روی برد مشخص شده اند. پایه های 3، 5، 6، 9، 10 و 11 در Arduino Uno و Nano از PWM پشتیبانی می کنند. در این آموزش از پایه 11 استفاده می کنیم.
برای ساخت مدار به یک برد Arduino Uno یا Nano، یک LED، یک مقاومت 220 تا 330 اهم و یک پتانسیومتر ترجیحا 10 کیلواهم نیاز داریم.
یکی از پایه های کناری پتانسیومتر را به 5V و پایه کناری دیگر را به GND متصل کنید. پایه وسط پتانسیومتر را به ورودی آنالوگ A0 وصل کنید. اگر جهت کم و زیاد شدن نور برعکس انتظار شما بود، جای دو پایه کناری پتانسیومتر را عوض کنید.
پایه مثبت LED یا آند را از طریق یک مقاومت 220 تا 330 اهم به پایه دیجیتال 11 متصل کنید. پایه منفی LED یا کاتد نیز باید به GND وصل شود. LED را بدون مقاومت مستقیما به پایه آردوینو متصل نکنید؛ زیرا ممکن است LED یا پایه خروجی برد آسیب ببیند.
تابع analogRead مقدار ولتاژ پایه A0 را می خواند. مبدل آنالوگ به دیجیتال در Arduino Uno و Nano دارای دقت 10 بیت است؛ بنابراین مقدار خوانده شده بین صفر تا 1023 خواهد بود.
تابع analogWrite در این بردها مقداری بین صفر تا 255 دریافت می کند. مقدار صفر یعنی پایه همیشه خاموش و مقدار 255 یعنی پایه همیشه روشن باشد. مقادیر بین این دو، چرخه کاری PWM را تعیین می کنند.
برای تبدیل محدوده صفر تا 1023 ورودی پتانسیومتر به محدوده صفر تا 255 خروجی PWM، مقدار خوانده شده را بر 4 تقسیم می کنیم. برای مثال، اگر مقدار پتانسیومتر حدود 512 باشد، نتیجه تقسیم تقریبا 128 خواهد شد و PWM با چرخه کاری نزدیک به 50 درصد تولید می شود.
با چرخاندن پتانسیومتر، ولتاژ ورودی A0 تغییر می کند. برنامه این مقدار را می خواند، آن را به محدوده PWM تبدیل می کند و با دستور analogWrite روی پایه 11 قرار می دهد. در نتیجه شدت نور LED متناسب با موقعیت پتانسیومتر کم یا زیاد می شود.
کد این آموزش برای Arduino Uno و Arduino Nano نوشته شده است. مفهوم PWM در ESP8266 و ESP32 نیز مشابه است، اما شماره پایه های PWM، دامنه ورودی آنالوگ و روش تنظیم دقت PWM ممکن است بر اساس مدل برد و نسخه هسته Arduino متفاوت باشد. همچنین پایه های ESP فقط با سطح منطقی 3.3 ولت کار می کنند و نباید ورودی 5 ولت مستقیما به آنها متصل شود.
PWM برای کنترل شدت نور LED، سرعت موتور DC، توان گرم کننده ها، تولید صدا و بسیاری از پروژه های کنترلی کاربرد دارد. برای راه اندازی بارهایی مانند موتور، پمپ یا نوار LED پرقدرت نباید از پایه میکروکنترلر به صورت مستقیم استفاده کرد و به مدار راه انداز مناسب مانند ترانزیستور یا MOSFET نیاز است.
PWM با تغییر سریع وضعیت پایه، یک خروجی شبه آنالوگ ایجاد می کند؛ این روش در مستندات رسمی آردوینو نیز برای کم و زیاد کردن نور LED معرفی شده است.
ولتاژ متوسط تقریبی PWM
| چرخه کاری | مقدار analogWrite | آردوینو 5 ولتی | ESP با خروجی 3.3 ولتی |
|---|---|---|---|
| 0٪ | 0 | 0 ولت | 0 ولت |
| 25٪ | 64 | حدود 1.25 ولت | حدود 0.83 ولت |
| 50٪ | 128 | حدود 2.5 ولت | حدود 1.65 ولت |
| 75٪ | 191 | حدود 3.75 ولت | حدود 2.48 ولت |
| 100٪ | 255 | حدود 5 ولت | حدود 3.3 ولت |
این مقادیر، میانگین تقریبی پالس ها هستند و به معنی تولید ولتاژ DC کاملا صاف و تنظیم شده نیستند. اتصالات مدار قطعه اتصال پایه کناری اول پتانسیومتر 5V پایه وسط پتانسیومتر A0 پایه کناری دوم پتانسیومتر GND پایه مثبت LED از طریق مقاومت 220 تا 330 اهم به D11 پایه منفی LED GND
/*
ARDUnia - PWM LED Control
Control LED brightness using a potentiometer
Potentiometer: A0
PWM LED: D11
*/
const int ledPin = 11;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
// خواندن پتانسیومتر در محدوده صفر تا 1023
int sensorValue = analogRead(A0);
// تبدیل مقدار ورودی به محدوده صفر تا 255
int light = sensorValue / 4;
// تعیین شدت نور LED با PWM
analogWrite(ledPin, light);
}