Dariush Tasdighi - داریوش تصدیقی
Dariush Tasdighi - داریوش تصدیقی
خواندن ۷ دقیقه·۱ سال پیش

آموزش جامع برنامه‌نویسی بر روی برد Arduino Uno و یا Arduino Nano از پایه، قدم به قدم، دقیق و کامل (قسمت دوم)

آموزش جامع برنامه‌نویسی بر روی برد Arduino
آموزش جامع برنامه‌نویسی بر روی برد Arduino
توجه: این مقاله به مرور زمان، ویرایش و یا تکمیل می‌شود!
تقاضا: در صورتی که با مشکل تایپی، دستوری و یا مفهومی در این مقاله برخورد کردید، از شما دوست عزیز و گرامی، صمیمانه تقاضا می‌کنم که اینجانب را مطلع کرده، تا نسبت به تصحیح و یا تکمیل آن، در اسرع وقت، اقدام نمایم.
با کمال تشکر
داریوش تصدیقی
کلیه اطلاعات تماس: https://DTAT.ir
نسخه مقاله: ۱.۰ - تاریخ بروزرسانی: ۱۴۰۱/۰۳/۲۳

حال می‌خواهیم در ابتدای راه‌اندازی Board (یعنی زمانی که Board را به صورت مستقل به منبع انرژی متصل می‌کنیم، ابتدا اگر چراغ LED روشن است، آن‌را خاموش کرده، و سپس به صورت تکراری چراغ را روشن و خاموش کنیم. طبیعتا چون می‌خواهیم به صورت تکراری، این عمل را انجام دهیم! باید کدهای مورد نظر را در تابع loop بنویسیم:

نکته: پس از نوشتن و تست کردن کد ذیل، لطفا به سرعت آن کد را به کد بعدی تغییر دهید! چرا که ضمن آن‌که چراغ روشن و خاموش نمی‌شود! بلکه حتی ممکن است با ما قهر کند! و دیگر هیچ‌وقت روشن نشود!

سورس‌کد شماره یک

void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, LOW); }

در تابع loop به حدی سریع (با فرکانس بالا) ولتاژ مثبت و منفی به LED منتقل می‌کنیم! که LED تصمیم می‌گیرد که هیچ واکنشی نشان ندهد! لذا باید بعد از هر بار تغییر وضعیت LED، یک وقفه (delay) کوتاه ایجاد نماییم.

برای این منظور از تابع دیگری به نام delay استفاده می‌کنیم. این تابع یک پارامتر ورودی دارد که از جنس عددی (int) بوده و مقیاس آن بر اساس میلی‌ثانیه می‌باشد. از آن‌جایی که هر ثانیه، هزار میلی‌ثانیه می‌باشد، اگر به عنوان پارامتر ورودی از عدد ۱۰۰۰ استفاده نماییم، اجرای برنامه، با یک مکث یا وقفه یک ثانیه‌ای روبرو می‌شود:

سورس‌کد شماره دو

void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { delay(1000); digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, LOW); }

در صورت اجرای دستور فوق نیز در عین ناباوری شاهد هستیم که برنامه به درستی کار نمی‌کند و LED نه تنها روشن خاموش نمی‌شود! بلکه اساسا روشن نمی‌شود!

ولی چرا!؟

در تابع setup، و صرفا در ابتدای کار، چرا اگر به طور پیش‌فرض روشن باشد، خاموش می‌شود و سپس Board تا روزی که زنده است! تابع loop را اجرا کرده و این کار را تا ابد تکرار می‌کند. در تابع loop، ابتدا یک مکث یک ثانیه‌ای می‌کنیم و سپس LED را روشن می‌کنیم، ولی دقیقا در دستور بعدی و به سرعت مجددا آن‌را خاموش می‌کنیم! پس اساسا وقت نمی‌دهیم که چراغ روشن شده و لااقل چند ثانیه یا حتی چند میلی‌ثانیه روشن بماند! و از تابع خارج شده و مجددا تابع loop اجرا می‌شود و همین مشکل تا ابد تکرار می‌شود:

لذا برای حل این مشکل، بعد از روشن کردن LED، نیز یک مکث یک ثانیه‌ای ایجاد می‌کنیم:

سورس‌کد شماره سه

void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { delay(1000); digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); }

اگر سورس‌کد فوق را اجرا کنیم، هم برنامه و هم نتیجه، مطلوب و مورد نظر خواهد بود، یعنی هر یک‌ثانیه یک‌بار، چراغ LED، روشن و خاموش می‌شود!

تمرین

برنامه‌ای بنویسید که فقط پنج‌بار چراغ LED را روشن و خاموش کند و پس از آن (پنجمین بار)، دیگر چراغ LED، روشن و خاموش نشود؟

نکته: سعی کنید که سورس‌کد ذیل را مشاهده نکرده و ابتدا خودتان این برنامه را بنویسید.

سورس‌کد شماره چهار

int counter = 1; void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { if (counter <= 5) { delay(1000); digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); counter = counter + 1; } }

سعی کنید که کد فوق را قدم به قدم و خط به خط Trace نمایید. در سورس‌کد فوق، زمانی که برای پنجمین بار چراغ LED، روشن و خاموش می‌شود، متغیر (Variable) Counter، مقدارش، از عدد پنج به عدد شش تغییر پیدا می‌کند و از تابع خارج می‌شود. مجددا زمانی که Board، تابع loop را اجرا می‌کند، ابتدا دستور if اجرا می‌شود و چون مقدار counter از پنج بزرگ‌تر است، دیگر وارد بلوک (Block) if نمی‌شود و صرفا از تابع خارج می‌شود. پس اگر تا ابد این Board، روشن بماند، هرچند که چراغ LED، دیگر روشن و خاموش نمی‌شود، ولی تابع loop تا ابد اجرا می‌شود! پس باید توجه داشته باشیم که ما جلوی اجرا تابع loop را نمی‌توانیم بگیریم! ولی می‌توانیم با نوشتن یک شرط ساده، نگذاریم، کاری که قبل از آن انجام می‌گشت، دوباره انجام شود.

نکته: در تمرین فوق، ما متغیری به نام counter یا شمارنده تعریف کردیم. این متغیر یک کلیدواژه نیست! می‌تواند هر نامی داشته باشد! مثلا googooli!

[تاکتیک]: باید دقت داشته باشیم که به عنوان یک حرفه‌ای در زمان نام‌گذاری متغیرها به نکات ذیل دقت داشته باشیم:

  • از متغیرهای بی‌معنا استفاده نمی‌کنیم! مثلا از متغیرهایی با اسامی x, y , i غیره استفاده نمی‌کنیم! هر چند که در اجرای برنامه هیچ‌گونه تاثیری ندارد و اگر به جای متغیر counter، از i هم استفاده می‌کردیم، برنامه بدون هیچ‌گونه مشکلی و به درستی اجرا می‌شد، ولی این عمل یک عمل حرفه‌ای نیست!
  • از اسامی مخفف شده استفاده نمی‌کنیم! مثلا اگر می‌خواهیم یک متغیر به description تعریف کنیم، دقیقا به همین نام تعریف می‌کنیم، و نام آن‌را مخفف (مثلا desk) نمی‌کنیم!
  • از اسامی پینگلیش استفاده نمی‌کنیم! مثلا اگر می‌خواهیم یک متغیر به نام تعداد درخت تعریف نماییم، خیلی شیک و مجلسی، آن‌را triCount تعریف می‌کنیم، و از نوشتن عبارت tedadeDerakht به شدت اجتناب می‌کنیم!
  • در زمان تعریف یک متغیر، از تکنیک Camel Case استفاده می‌کنیم! یعنی تمام حروف کلمه اول، باید با حروف کوچک نوشته شده و کلمات بعد حرف اول آن‌ها بزرگ و بقیه حروف، با حروف کوچک نوشته شود! مثلا اگر می‌خواهیم متغیری به نام تعداد درخت تعریف نماییم، دقیقا باید به صورت triCount نوشته شود و از نوشتن مدل‌های عجیب و غریب، مانند TriCount, TRICOUNT, TRI_COUNT و غیره به شدت اجتناب می‌کنیم.
  • در زمان تعریف یک متغیر، یک‌بار به خودمان زحمت داده و لغت درست را با معنی درست، از دیکشنری پیدا کرده و یا از طریق Microsoft Word، دیکته درست آن‌را بررسی می‌کنیم! به عنوان مثال، در نمونه‌های فوق، اینجانب به عمد! و به اشتباه! درخت را Tri نوشتم! و قطعا بسیاری از شما که مرا نمی‌شناسید، با خود گفته‌اید که عجب آدم بی‌سوادی است! و قطعا به ریشم نیز خندیده‌اید! و البته کاملا هم حق دارید! در صورتی که اینجانب باید از Google Translate ترجمه درخت، که Tree می‌باشد را جستجو می‌کردم و نام متغیر را به درستی و به صورت treeCount تعریف می‌کردم! پس برای این‌که یک عمر مورد تمسخر دیگران قرار نگیرید! روی ترجمه درست، دیکتیشن درست، به شدت توجه داشته باشید.

تمرین کاربردی

بسیاری از شما با کد مورس آشنایی دارید، و یا آن‌را شنیده‌اید. این کدها یا به صورت صدا و یا نور ایجاد و منتشر می‌شوند. حال می‌خواهیم با استفاده از چراغ LED، اقدام به ارسال کد مورس SOS (یعنی کمک) کنیم:

کد مورس برای SOS:

S O S: . . . _ _ _ . . .

ابتدا خودتان سعی کنید که کد مذکور را بنویسید و سپس از کدی که در اختیار شما قرار داده می‌شود استفاده نمایید:

سورس‌کد شماره پنج

int dit = 150; // Setting Value of dit as 150 milliseconds int dah = 500; // Setting Value of dah as 500 milliseconds int longWait = 1000; // Setting value of longWait as 1000 milliseconds void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { // *** S *** // DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dit); //DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dit); //DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dah); // *** O *** //DAH digitalWrite(LED_BUILTIN, HIGH); delay(dah); digitalWrite(LED_BUILTIN, LOW); delay(dah); //DAH digitalWrite(LED_BUILTIN, HIGH); delay(dah); digitalWrite(LED_BUILTIN, LOW); delay(dah); //DAH digitalWrite(LED_BUILTIN, HIGH); delay(dah); digitalWrite(LED_BUILTIN, LOW); delay(dah); // *** S *** // DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dit); //DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dit); //DIT digitalWrite(LED_BUILTIN, HIGH); delay(dit); digitalWrite(LED_BUILTIN, LOW); delay(dah); //Giving a Gap before restarting delay(longWait); }

تشکر و تقدیر

  • با تشکر از امیر بادامچی عزیز، بابت ویرایش علمی و متنی این مقاله

پایان

arduinoarduino ideبرنامه نویسیآموزشکد مورس
محقق، معمار، مشاور، مدرس و برنامه‌نویس حوزه فن‌آوری اطلاعات - تحلیل‌گر و فعال بازار بورس و سرمایه
شاید از این پست‌ها خوشتان بیاید