پرش به محتوای اصلی
آزمایشگاه‌های مجازی یادگیری با شبیه‌سازی ورود ثبت‌نام
درس ۳ از ۹ مقدماتی ۲۰ دقیقه

خروجی شبه‌آنالوگ: PWM و کنترل روشنایی

با analogWrite و چرخهٔ کار، روشنایی یک ال‌ای‌دی را پیوسته کم و زیاد کن و ولتاژ متوسط را حساب کن.

در پایان این درس می‌توانید

  • چرخهٔ کار را تعریف کنی و رابطه‌اش را با ولتاژ متوسط روی بار بنویسی.
  • با analogWrite و بازهٔ ۰ تا ۲۵۵ روشنایی یک ال‌ای‌دی را پیوسته تغییر دهی.
  • بدانی کدام پایه‌های برد Uno علامت ~ دارند و چرا فقط همان‌ها PWM می‌دهند.
  • دورهٔ تناوب و زمان بالابودن پالس را از بسامد ۴۹۰ یا ۹۸۰ هرتز حساب کنی.
  • توضیح دهی چرا PWM ولتاژ آنالوگ واقعی نمی‌سازد و میانگین‌گیری کجا رخ می‌دهد.

تا اینجا هر پایهٔ دیجیتال فقط دو حالت داشت: نزدیک صفر ولت یا نزدیک پنج ولت. پس چطور یک ال‌ای‌دی را نیمه‌روشن کنیم یا دور یک موتور را کم کنیم؟ میکروکنترلر ATmega328P مبدل دیجیتال به آنالوگ ندارد و اصلاً نمی‌تواند روی یک پایه دو و نیم ولت بسازد. راهی که به‌جایش دارد ساده و زیرکانه است: پایه را چنان تند خاموش و روشن می‌کند که چشم و موتور فقط میانگین را حس کنند. نام این ترفند مدولاسیون پهنای پالس یا همان PWM است.

چرخهٔ کار

موجی که پایه می‌سازد یک مربع تکرارشونده است: مدتی بالا و مدتی پایین. مجموع این دو زمان، دورهٔ تناوب است و ثابت می‌ماند. آنچه تغییر می‌کند سهم بخش بالا از کل دوره است؛ به این نسبت چرخهٔ کار می‌گویند و معمولاً با درصد بیانش می‌کنند. چرخهٔ کار صفر یعنی پایه همیشه پایین، صد یعنی همیشه بالا و پنجاه یعنی نیمی از هر دوره بالا. توانی که به بار می‌رسد با همین نسبت کم و زیاد می‌شود، بی‌آنکه دامنهٔ ولتاژ ذره‌ای عوض شود؛ پالس‌ها همیشه بین صفر و پنج ولت‌اند.

تابع analogWrite و بازهٔ ۰ تا ۲۵۵

تابع analogWrite(pin, value) این موج را برایت می‌سازد. آرگومان دوم عددی بین ۰ و ۲۵۵ است، چون شمارندهٔ سخت‌افزاری پشت این تابع هشت‌بیتی است و ۲۵۶ پله دارد؛ صفر یعنی چرخهٔ کار صفر، ۲۵۵ یعنی صد درصد، و هر یک واحد نزدیک چهار دهم درصد می‌ارزد. نکتهٔ مهم این است که پس از این فراخوانی دیگر کاری از برنامه خواسته نمی‌شود: تایمر داخل تراشه موج را در پس‌زمینه و بدون دخالت پردازنده ادامه می‌دهد، تا وقتی مقدار تازه‌ای بنویسی یا با digitalWrite() پایه را دستی بالا و پایین کنی. پس برخلاف چشمک‌زدن با delay()، اینجا هیچ وقتی از پردازنده گرفته نمی‌شود.

نام این تابع گمراه‌کننده است. analogWrite() هیچ ولتاژ آنالوگی نمی‌سازد و پایه هرگز روی یک سطح میانی نمی‌ایستد؛ فقط نسبت زمان روشن به خاموش عوض می‌شود. اگر با اسیلوسکوپ نگاه کنی، همان پالس‌های تیز صفر و پنج ولت را می‌بینی، نه یک خط صاف. میانگین‌گیری را چشم تو، لَختی محور موتور یا خازن مدار انجام می‌دهد، نه پایهٔ برد.

چرا فقط پایه‌های ~

روی برد Uno تنها شش پایه این توانایی را دارند: D3، D5، D6، D9، D10 و D11. کنار شمارهٔ همین‌ها روی خود برد علامت مارپیچ (~) چاپ شده است. علتش این است که فقط این شش پایه به مقایسه‌گر تایمرهای سخت‌افزاری تراشه وصل‌اند. بسامد موج هم از همین تایمرها می‌آید: روی D3، D9، D10 و D11 حدود ۴۹۰ هرتز است و روی D5 و D6 حدود ۹۸۰ هرتز، یعنی نزدیک دو برابر، چون تایمری که این دو پایه را می‌راند با تقسیم‌کنندهٔ متفاوتی راه‌اندازی شده است. اگر analogWrite() را روی پایه‌ای بدون ~ صدا بزنی، نه خطای کامپایل می‌گیری و نه موجی ساخته می‌شود؛ پایه برای مقدارهای کمتر از ۱۲۸ پایین و برای ۱۲۸ و بیشتر بالا می‌ماند، درست مثل یک digitalWrite() ساده.

یک نمونهٔ عددی

ولتاژ مؤثری که بار حس می‌کند برابر است با ولتاژ تغذیه ضربدر چرخهٔ کار. برای analogWrite(128) چرخهٔ کار برابر ۱۲۸ تقسیم بر ۲۵۵ یعنی حدود ۵۰٫۲ درصد است، پس ولتاژ متوسط می‌شود ۵ ضربدر ۰٫۵۰۲، یعنی نزدیک ۲٫۵ ولت. برای analogWrite(51) نسبت برابر ۵۱ تقسیم بر ۲۵۵ یعنی دقیقاً ۲۰ درصد است و ولتاژ متوسط می‌شود ۵ ضربدر ۰٫۲ یعنی ۱ ولت. حالا زمان‌ها را هم درآور: روی پایهٔ D9 با بسامد ۴۹۰ هرتز، دورهٔ تناوب برابر یک تقسیم بر ۴۹۰ یعنی حدود ۲٫۰۴ میلی‌ثانیه است. با چرخهٔ کار ۲۰ درصد، پایه در هر دوره حدود ۰٫۴۱ میلی‌ثانیه بالا و ۱٫۶۳ میلی‌ثانیه پایین می‌ماند. این رفت و برگشت آن‌قدر تند است که چشم فقط یک نور کم‌جان می‌بیند.

روشنایی‌ای که چشم می‌بیند با چرخهٔ کار خطی بالا نمی‌رود. چشم انسان به نورهای کم حساس‌تر است، پس فاصلهٔ ۰ تا ۶۰ به‌مراتب محسوس‌تر از فاصلهٔ ۲۰۰ تا ۲۵۵ به نظر می‌رسد. اگر کم‌ونور کاملاً نرم می‌خواهی، به‌جای پله‌های مساوی باید مقدارها را روی یک منحنی نمایی بالا ببری.

کجا به کار می‌آید

کم‌ونور کردن چراغ، تنظیم روشنایی نمایشگر و ساختن هر رنگ از سه ال‌ای‌دی قرمز و سبز و آبی، همگی همین یک تابع‌اند. کنترل دور موتور هم همین است، با این تفاوت که جریان موتور از پایهٔ برد نمی‌گذرد و یک ترانزیستور یا درایور واسطه می‌شود. مزیت بزرگ این روش راندمان است: کلید یا کاملاً بسته است یا کاملاً باز، پس برخلاف یک مقاومت متغیر تقریباً توانی به گرما هدر نمی‌رود. در کیت این درس یک ال‌ای‌دی روی پایهٔ ~ با حلقهٔ for نفس می‌کشد و ال‌ای‌دی دوم روی پایه‌ای بدون ~ نشسته است، تا تفاوت را با چشم خودت ببینی.

رابطه‌های کلیدی

V_avg = Vcc x (value / 255) = 5 x (128 / 255) = 2.51 Vولتاژ متوسط پایه برای analogWrite(128)؛ چرخهٔ کار حدود ۵۰ درصد
V_avg = 5 x (51 / 255) = 1.00 V (duty = 20%)همان رابطه برای analogWrite(51)؛ یک پنجم زمان بالا و بقیه پایین
T = 1 / 490 Hz = 2.04 ms ; t_on = 0.20 x 2.04 = 0.41 msدورهٔ تناوب PWM روی پایهٔ D9 و زمان بالابودن آن در چرخهٔ کار ۲۰ درصد
درس قبلی

مأموریت روی میز کار

کیت را اجرا کن؛ ال‌ای‌دی قرمز روی یک پایهٔ PWM نفس می‌کشد و ال‌ای‌دی سبز روی پایه‌ای بدون این توانایی بسته شده است. اعداد کد را عوض کن و تفاوت را با چشم بسنج.

  1. کد را اجرا کن و بشمار؛ ال‌ای‌دی قرمز باید هر چهار ثانیه یک نفس کامل بکشد.
  2. مکث هر پله را از ۸ به ۲ میلی‌ثانیه کم کن و ببین نفس‌کشیدن چهار برابر تندتر می‌شود.
  3. هر دو حلقهٔ for را بردار و به‌جایشان روی همان پایه فقط مقدار ثابت ۵۱ را بنویس؛ ال‌ای‌دی باید کم‌جان و بی‌حرکت بماند.
  4. همان مقدار ثابت را به ۱۲۸ ببر و روشنایی را با حالت قبل مقایسه کن؛ ولتاژ متوسط از ۱ ولت به حدود ۲٫۵ ولت می‌رود.
  5. سر سیم ال‌ای‌دی قرمز را از پایهٔ ۹ به پایهٔ ۸ ببر و شمارهٔ پایه را در کد هم عوض کن؛ ببین نفس‌کشیدن به یک پرش ناگهانی تبدیل می‌شود.
انتظار می‌رود: ال‌ای‌دی قرمز به‌نرمی پر و خالی می‌شود، ولی ال‌ای‌دی سبز فقط وسط هر نفس ناگهان روشن و در برگشت ناگهان خاموش می‌شود.
مدار و کد این درس همین حالا اجرا می‌شود و حساب لازم ندارد. با حساب رایگان پیشرفت و نمرهٔ شما هم ثبت می‌شود و سقف روزانه بالاتر می‌رود.

مدار و کد این درس از پیش چیده شده‌اند. آزادانه تغییرشان بدهید — پروژه‌های خودتان دست‌نخورده می‌مانند. تمام‌صفحه با همین کیت

آزمون این درس

۵ پرسش چهارگزینه‌ای. پس از ثبت، پاسخ درست و توضیح هر پرسش را می‌بینید. می‌توانید هر چند بار که خواستید تلاش کنید؛ بهترین نمره در کارنامه ثبت می‌شود.