
آموزش گام به گام آردوینو بخش سوم: کار با ورودی و خروجیهای آنالوگ
در بخشهای قبلی، با مفاهیم پایه الکترونیک، ساختار برنامهنویسی آردوینو و کار با ورودی/خروجیهای دیجیتال آشنا شدیم. دیجیتال فقط دو حالت دارد: صفر یا یک، خاموش یا روشن. اما دنیای واقعی پر از مقادیر پیوسته است: نور محیط میتواند کمرنگ یا پررنگ باشد، دما میتواند ۲۳/۵ درجه باشد، و صدا میتواند آرام یا بلند باشد. در این بخش، یاد میگیریم چگونه این مقادیر پیوسته (آنالوگ) را با آردوینو بخوانیم و تولید کنیم.
فهرست محتوای بخش سوم
- فصل ۱: مفهوم سیگنال آنالوگ و تفاوت آن با دیجیتال
- فصل ۲: ورودی آنالوگ – آشنایی با پتانسیومتر
- فصل ۳: کار با سنسورهای آنالوگ (مثال LDR)
- فصل ۴: خروجی آنالوگ – مفهوم PWM
- پروژه عملی پایان بخش سوم: دیمر هوشمند با کنترل دستی و نوری
- خلاصه بخش سوم
فصل ۱: مفهوم سیگنال آنالوگ و تفاوت آن با دیجیتال
۱.۱ سیگنال دیجیتال در مقابل سیگنال آنالوگ
برای درک بهتر، یک لامپ را تصور کنید:
- کنترل دیجیتال: لامپ یا کاملاً روشن است یا کاملاً خاموش. حالت بینابین وجود ندارد .
- کنترل آنالوگ: لامپ میتواند با شدتهای مختلف روشن شود؛ مثل دیمرهای منزل که نور را تنظیم میکنند.
در الکترونیک:
- سیگنال دیجیتال: فقط دو سطح ولتاژ دارد (معمولاً ۰ ولت و ۵ ولت). در آردوینو، این سیگنالها را با
digitalReadوdigitalWriteمدیریت میکنیم . - سیگنال آنالوگ: ولتاژ آن در یک بازه پیوسته تغییر میکند (مثلاً از ۰ تا ۵ ولت). سنسور دما، پتانسیومتر (ولوم)، و سنسور نور نمونههایی از منابع سیگنال آنالوگ هستند .
۱.۲ میکروکنترلر و دنیای دیجیتال
میکروکنترلرهای آردوینو در هسته خود دیجیتال هستند و فقط صفر و یک را میفهمند. پس چطور میتوانند مقادیر آنالوگ را بخوانند؟
پاسخ: مبدل آنالوگ به دیجیتال (ADC – Analog to Digital Converter). این قطعه داخلی، ولتاژ آنالوگ ورودی را به یک عدد دیجیتال تبدیل میکند .
ویژگیهای ADC در آردوینو Uno:
- تفکیکپذیری (Resolution): ۱۰ بیت. یعنی مقادیر بین ۰ تا ۱۰۲۳ (۲^۱۰ حالت مختلف).
- ولتاژ مرجع: معمولاً ۵ ولت. یعنی ولتاژ ۰ ولت → عدد ۰، ولتاژ ۵ ولت → عدد ۱۰۲۳، ولتاژ ۲/۵ ولت → عدد تقریباً ۵۱۲.
- پینهای آنالوگ: روی برد Uno، پینهای A0 تا A5 برای ورودی آنالوگ اختصاص داده شدهاند .
رابطه ریاضی:
|
1 2 |
مقدار دیجیتال = (ولتاژ ورودی / ولتاژ مرجع) × 1023 |
فصل ۲: ورودی آنالوگ – آشنایی با پتانسیومتر
۲.۱ پتانسیومتر چیست؟
پتانسیومتر در واقع همان “ولوم” یا مقاومت متغیر است. با چرخاندن دستگیره آن، مقاومت تغییر میکند و در نتیجه ولتاژ نقطه میانی آن تغییر میکند .
ساختار: پتانسیومتر سه پایه دارد:
- پایههای کناری: به ولتاژ (۵ ولت) و زمین (GND) وصل میشوند.
- پایه میانی (ویپر): به پین آنالوگ آردوینو وصل میشود. ولتاژ این پایه بین ۰ تا ۵ ولت تغییر میکند.
۲.۲ تابع analogRead
برای خواندن مقادیر آنالوگ از تابع analogRead(pin) استفاده میکنیم .
|
1 2 |
int sensorValue = analogRead(A0); // مقدار پین A0 را خوانده و در متغیر ذخیره میکند |
مثال ساده: خواندن مقدار پتانسیومتر و نمایش در Serial Monitor.
|
1 2 3 4 5 6 7 8 9 10 11 |
void setup() { Serial.begin(9600); // راهاندازی ارتباط سریال } void loop() { int potValue = analogRead(A0); // خواندن پتانسیومتر متصل به A0 Serial.print("Potentiometer Value: "); Serial.println(potValue); // چاپ مقدار (0 تا 1023) delay(500); // نیم ثانیه تأخیر } |
پروژه عملی ۱: نمایش ولتاژ
کد بالا را اجرا کنید. پتانسیومتر را بچرخانید و اعداد نمایش داده شده در Serial Monitor را مشاهده کنید. حالا با فرمول زیر ولتاژ را محاسبه کنید:
|
1 2 3 4 |
float voltage = potValue * (5.0 / 1023.0); // تبدیل به ولتاژ Serial.print("Voltage: "); Serial.println(voltage); |
فصل ۳: کار با سنسورهای آنالوگ (مثال LDR)
۳.۱ سنسور نور (LDR – Light Dependent Resistor)
LDR مقاومتی است که مقدار آن با شدت نور محیط تغییر میکند. هرچه نور بیشتر باشد، مقاومت کمتر میشود .
برای استفاده از LDR با آردوینو، باید یک مدار تقسیم ولتاژ بسازیم:
![مدار تقسیم ولتاژ با LDR: LDR بین ۵ ولت و پین A1 وصل میشود و یک مقاومت ثابت (مثلاً ۱۰ کیلواهم) بین پین A1 و GND قرار میگیرد.]
- اگر نور زیاد شود: مقاومت LDR کم میشود ← ولتاژ پین A1 کاهش مییابد.
- اگر نور کم شود: مقاومت LDR زیاد میشود ← ولتاژ پین A1 افزایش مییابد.
۳.۲ کد خواندن سنسور نور
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int ldrPin = A1; // پین سنسور نور int ldrValue = 0; // متغیر ذخیره مقدار void setup() { Serial.begin(9600); } void loop() { ldrValue = analogRead(ldrPin); Serial.print("Light Level: "); Serial.println(ldrValue); delay(500); } |
۳.۳ تابع map برای تغییر محدوده
گاهی میخواهیم محدوده ۰ تا ۱۰۲۳ را به محدوده دیگری مثلاً ۰ تا ۲۵۵ تبدیل کنیم. تابع map این کار را انجام میدهد .
|
1 2 3 |
// ساختار: map(مقدار, از_حداقل, از_حداکثر, به_حداقل, به_حداکثر) int brightness = map(ldrValue, 0, 1023, 0, 255); |
مثال عملی: با افزایش نور محیط، LED کمرنگتر شود (عکسالعمل معکوس):
|
1 2 |
int brightness = map(ldrValue, 0, 1023, 255, 0); // معکوس کردن |
۳.۳ تابع constrain برای محدود کردن
گاهی مقدار خروجی ممکن است از محدوده خارج شود. constrain مقدار را در بازه مشخصی نگه میدارد .
|
1 2 |
int safeValue = constrain(rawValue, 0, 255); // مقدار بین ۰ تا ۲۵۵ باقی میماند |
فصل ۴: خروجی آنالوگ – مفهوم PWM
۴.۱ مشکل خروجی آنالوگ واقعی
آردوینو Uno خروجی آنالوگ واقعی (یعنی تولید ولتاژ قابل تنظیم مثل ۲/۳ ولت) ندارد. پس چطور میتوانیم شدت نور LED را تنظیم کنیم یا سرعت موتور را کنترل نماییم؟
پاسخ: مدولاسیون عرض پالس (PWM – Pulse Width Modulation) .
۴.۲ PWM چگونه کار میکند؟
PWM یک موج مربعی با فرکانس ثابت تولید میکند که در آن، زمان روشن بودن (HIGH) و خاموش بودن (LOW) تغییر میکند.
- Duty Cycle (نسبت روشنی): درصد زمانی که سیگنال در حالت HIGH است .
- Duty cycle 0%: همیشه خاموش (۰ ولت)
- Duty cycle 100%: همیشه روشن (۵ ولت)
- Duty cycle 50%: نیمی از زمان روشن، نیمی خاموش (میانگین ۲/۵ ولت)
![نمودار PWM: سه موج با duty cycle 25%، 50% و 75% نشان داده شده است. در 25%، پالسها باریک و در 75%، پالسها پهن هستند.]
چشم انسان و بسیاری از قطعات الکترومکانیکی، این روشن و خاموش شدن سریع را به صورت یک مقدار میانگین (مثلاً نور کمتر) درک میکنند .
پیشنهاد ویژه
خرید قطعات الکترونیکی با ارسال سریع
اگر به دنبال قطعات الکترونیکی با قیمت مناسب، کیفیت قابل اعتماد و ارسال سریع هستید، همین حالا محصولات منتخب ما را بررسی کنید.
۴.۳ تابع analogWrite و پینهای PWM
برای تولید سیگنال PWM از تابع analogWrite(pin, value) استفاده میکنیم .
- پارامتر اول: شماره پین (باید از پینهای PWM پشتیبانی کند)
- پارامتر دوم: مقدار ۰ تا ۲۵۵ (۰ = 0% duty cycle، ۲۵۵ = 100% duty cycle)
پینهای PWM در آردوینو Uno: پینهای ۳، ۵، ۶، ۹، ۱۰، و ۱۱ (معمولاً با علامت ~ در کنار شماره پین مشخص میشوند) .
|
1 2 3 4 5 6 7 8 9 10 |
int ledPin = 9; // یک پین PWM void setup() { pinMode(ledPin, OUTPUT); } void loop() { analogWrite(ledPin, 128); // حدود 50% روشنایی (2.5 ولت میانگین) } |
۴.۴ مثال: محو شدن تدریجی LED (Fading)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int ledPin = 9; void setup() { pinMode(ledPin, OUTPUT); } void loop() { // افزایش تدریجی روشنایی for (int brightness = 0; brightness <= 255; brightness++) { analogWrite(ledPin, brightness); delay(10); // تأخیر کوتاه برای دیدن تغییرات } // کاهش تدریجی روشنایی for (int brightness = 255; brightness >= 0; brightness--) { analogWrite(ledPin, brightness); delay(10); } } |
۴.۵ نکات مهم درباره PWM
- فرکانس PWM: در آردوینو Uno، فرکانس پیشفرض برای پینهای ۵ و ۶ حدود ۹۸۰ هرتز و برای سایر پینهای PWM حدود ۴۹۰ هرتز است.
- تفکیکپذیری: ۸ بیت (۰ تا ۲۵۵). در برخی بردها میتوان با
analogWriteResolutionاین مقدار را تغییر داد. - کاربردها: کنترل روشنایی LED، کنترل سرعت موتور DC، تولید صداهای ساده با اسپیکر .
پروژه عملی پایان بخش سوم: دیمر هوشمند با کنترل دستی و نوری
حالا همه مفاهیم این بخش را در یک پروژه جامع ترکیب میکنیم. هدف: سیستمی که بتواند روشنایی یک LED را به دو صورت کنترل کند:
- با پتانسیومتر (کنترل دستی)
- با سنسور نور (کنترل خودکار بر اساس نور محیط)
قطعات مورد نیاز:
- برد آردوینو Uno
- ۱ عدد LED
- ۱ عدد مقاومت ۲۲۰ اهم
- ۱ عدد پتانسیومتر ۱۰ کیلواهم
- ۱ عدد LDR (سنسور نور)
- ۱ عدد مقاومت ۱۰ کیلواهم (برای مدار تقسیم ولتاژ با LDR)
- برد بورد و سیم جامپر
نحوه بستن مدار:
![شماتیک کامل مدار: LED به پین ۹ (PWM) از طریق مقاومت ۲۲۰ اهم وصل شده است. پتانسیومتر: پایه چپ به ۵ ولت، پایه راست به GND، پایه وسط به A0. LDR: یک سر به ۵ ولت، سر دیگر به A1 و یک مقاومت ۱۰k به GND.]
| قطعه | اتصال |
|---|---|
| LED (آند – پایه بلند) | مقاومت ۲۲۰Ω ← پین ۹ |
| LED (کاتد – پایه کوتاه) | GND |
| پتانسیومتر (پایه چپ) | ۵ ولت |
| پتانسیومتر (پایه راست) | GND |
| پتانسیومتر (پایه وسط) | A0 |
| LDR (یک سر) | ۵ ولت |
| LDR (سر دیگر) | A1 |
| مقاومت ۱۰ کیلو اهم | بین A1 و GND |
کد پروژه:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
// تعریف پینها const int ledPin = 9; // LED به پین PWM 9 const int potPin = A0; // پتانسیومتر به A0 const int ldrPin = A1; // سنسور نور به A1 // متغیرها int potValue = 0; // مقدار خام پتانسیومتر (0-1023) int ldrValue = 0; // مقدار خام سنسور نور (0-1023) int brightness = 0; // روشنایی نهایی LED (0-255) int mode = 0; // 0: حالت دستی، 1: حالت خودکار unsigned long lastButtonPress = 0; // برای رفع نویز دکمه (اگر دکمه اضافه کنیم) void setup() { Serial.begin(9600); // برای نمایش مقادیر pinMode(ledPin, OUTPUT); // پیام خوشآمدگویی Serial.println("Smart Dimmer Started"); Serial.println("Mode 0: Manual (Potentiometer)"); Serial.println("Mode 1: Automatic (Light Sensor)"); Serial.println("Send 'm' via Serial Monitor to switch mode"); } void loop() { // خواندن سنسورها potValue = analogRead(potPin); ldrValue = analogRead(ldrPin); // بررسی تغییر حالت از طریق Serial Monitor if (Serial.available() > 0) { char command = Serial.read(); if (command == 'm') { mode = !mode; // تغییر حالت Serial.print("Switched to Mode "); Serial.println(mode); } } // محاسبه روشنایی بر اساس حالت if (mode == 0) { // حالت دستی: روشنایی با پتانسیومتر کنترل میشود brightness = map(potValue, 0, 1023, 0, 255); Serial.print("Manual Mode - Pot: "); Serial.print(potValue); } else { // حالت خودکار: هرچه نور محیط کمتر، LED روشنتر // (عکسالعمل معکوس - مناسب برای نور شب) brightness = map(ldrValue, 0, 1023, 255, 0); // محدود کردن اطمینان از بازه 0-255 brightness = constrain(brightness, 0, 255); Serial.print("Auto Mode - LDR: "); Serial.print(ldrValue); Serial.print(", Light Level: "); if (ldrValue < 200) Serial.print("Dark"); else if (ldrValue < 600) Serial.print("Normal"); else Serial.print("Bright"); } // اعمال روشنایی به LED analogWrite(ledPin, brightness); // نمایش اطلاعات Serial.print(" | Brightness: "); Serial.println(brightness); delay(200); // کمی تأخیر برای خوانایی بهتر } |
توضیح کد:
- تعریف پینها و متغیرها: همه پینها و متغیرهای مورد نیاز در ابتدا تعریف شدهاند .
- حالتهای مختلف: یک متغیر
modeمشخص میکند که سیستم در حالت دستی (پتانسیومتر) است یا خودکار (سنسور نور). - تعویض حالت: با ارسال کاراکتر ‘m’ از طریق Serial Monitor میتوان بین دو حالت جابجا شد.
- تبدیل مقادیر: در حالت خودکار، از
mapبا پارامترهای معکوس استفاده شده تا با تاریک شدن هوا، LED روشنتر شود . - اطلاعرسانی: Serial Monitor مقادیر خوانده شده و روشنایی نهایی را نمایش میدهد .
توسعه پروژه (تمرین بیشتر):
- اضافه کردن دکمه فیزیکی: به جای Serial Monitor، با یک دکمه فیزیکی حالت را تغییر دهید.
- حافظه حالت: با استفاده از حافظه EEPROM، آخرین حالت ذخیره شود تا پس از قطع برق، همان حالت بازیابی گردد.
- منحنیهای غیرخطی: به جای
mapخطی، از توابع غیرخطی برای تنظیم روشنایی استفاده کنید (مثلاً باpow). - کنترل چند LED: سه LED با رنگهای مختلف را همزمان کنترل کنید .
خلاصه بخش سوم
در این بخش یاد گرفتیم:
- تفاوت سیگنال دیجیتال و آنالوگ را درک کنیم و بدانیم چرا به هر دو نیاز داریم .
- با مبدل آنالوگ به دیجیتال (ADC) و نحوه عملکرد آن آشنا شویم .
- از تابع
analogReadبرای خواندن مقادیر سنسورهای آنالوگ مثل پتانسیومتر و LDR استفاده کنیم . - از توابع
mapوconstrainبرای تبدیل و محدود کردن محدوده مقادیر بهره ببریم . - با مفهوم مدولاسیون عرض پالس (PWM) و کاربرد آن در شبیهسازی خروجی آنالوگ آشنا شویم .
- از تابع
analogWriteبرای کنترل روشنایی LED و تولید سیگنالهای PWM استفاده کنیم. - پینهای PWM را روی برد آردوینو شناسایی کنیم .
- یک پروژه جامع “دیمر هوشمند” را پیادهسازی کنیم که بین کنترل دستی و خودکار جابجا میشود.
در بخش چهارم، به سراغ پروژههای ترکیبی و نمایشگرها میرویم و با نمایشگرهای ۷ سگمنت و LCD کار خواهیم کرد تا بتوانیم اطلاعات را به صورت بصری به کاربر نمایش دهیم.



