جلسه سیزدهم : استفاده از کتابخانه Bounce2

سلام

اگه یادتون باشه توی آموزش جلسه 11 استفاده از پین دیجیتال آردوینو به عنوان ورودی و تو جلسه 12 نحوه اضافه کردن کتابخونه به محیط آردوینو رو یاد گرفتیم.
این جلسه تلفیقی از 2 جلسه قبله. یعنی قراره داده یه سوئیچ رو بخونیم ولی نه با یه digitarRead معمولی بلکه با استفاده از کتابخونه Bounce2.
مهم ترین سوالی که برتون پیش میاد اینه که خب مگه digitalRead معمولی چشه که بخوایم بریم کتابخونه اضافه کنیم و از لحاظ نرم افزاری کارمون رو یه کم مشکل تر کنیم.

برای این که دلیل این کار رو بدونید ترجیح میدم انجامش بدید تا خودتون بفهمید.
برای این کار اول سخت افزارمون رو می بندیم یه آردوینو می خوایم (هر مدلی دارید فرقی نمی کنه ) و یه سوئیچ و یه برد بورد کوچیک .

خب وقتی سوئیچ رو نگاه کنید می بینید 4 تا پایه داره! داستان چیه؟ داستان اینه که این پایه ها مطابق عکس زیر 2 تا 2 تا به هم وصلن:
BUTT-4_3-500x500

حالا مطابق عکس زیر مدار رو ببندید:
button

یعنی یه پایه رو به 5 ولت و یه پایه رو به پین دیجیتال شماره 2 وصل کنید. دقت کنید که پایه های متصل به هم به صورت عکس زیرهستن و سوئیچ باید درست توی مدار قرار بگیره:
button می دونید که هیچ اصراری به پین شماره 2 نداریم هر پین دیجیتال دلخواهی میشه. دقت کنید بین پایه شماره 2 آردوینو (که به سوئیچ هم وصله )و زمین یه مقاومت قرار داده شده. این مقاومت برای این گذاشته شده که زمانی که کلید فشار داده نشده روی پین شماره 2 دقیقا ولتاژ 0 ولت بیفته و زمانی که کلید فشار داده میشه دقیقا ولتاژ 5 ولت و منطق باینری HIGH بیفته.
یه کم دقیق تر حرف بزنیم:
زمانی که کلید رو فشار ندادیم بین دو قسمت مشخص شده سوئیچ در شکل اول هیچ ارتباطی وجود نداره. یه طرف که  مستقیم به 5 ولت وصله خب تکلیفش معلومه. ولی اون طرف سوئیچ که به پین دیجیتال آردوینو وصله داستان داره. اگه مقاومت نزاریم یعنی پین آردوینو رو مستقیم  به اون سر سوئیچ وصل کنیم پین وضعیت آزاد داره یعنی مختاره روش منطق باینری 0 یا 1 بیفته چون هیچ کس نیست بهش فرمانی دستوری چیزی بده. اونم مختاره هر چی خواست باشه که اصلا پدیده خوشایندی نیست و اگه مدار رو همینطوری ببندید بینهایت پر خطا خواهد بود. بنابراین یه مقاومت بر می داریم و اون پین رو به واسطه این مقاومت زمین می کنیم. با این کار یه مسیر بین این پین و زمین برقرار میشه . این مسیر طبق قوانین مداری باعث میشه روی پین دیجیتال شماره 2 آردوینوهم ولتاژ 0 ولت معادل منطق باینری LOW بیفته و هر چی که خواست نباشه. به این مقاومت ، مقاومت Pull-down گفته میشه . برای دریافت توضیحات بیشتر این لینک رو بخونید.
اما زمانی که کلید رو وصل می کنیم بین دو قسمت نشون داده سوئیچ تو شکل اول یه ارتباط به وجود میاد و دو تا قسمت به هم وصل می شن. بنابراین اون قسمتی که به پین شماره 2 وصل بود الان به خاطر این اتصال ولتاژی معادل 5 ولت و منطق باینری HIGH خواهد داشت.

خب حالا این کد رو آپلود کنید:
2016-01-16_11-53-44

روال این کد به این صورته که به محض فشار داده شدن کلید در کنسول سریال پیغام Pressed نمایش داده میشه. دقت کنید شرط if رو چجوری نوشتم. نوشتم اگه داده پین دیجیتال HIGH بود (که معادل فشار داده شدنه کلیده ) برو رو کنسول سریال چاپ کن.
خب کد رو آپلود کنید و کنسول سریال رو باز کنید و یک بار کلید رو فشار بدید . با این نتیجه دلخراش در کنسول مواجه خواهید شد:
2016-01-16_12-10-01
می بینید شما یک بار کلید رو فشار دادید ولی این طفلک بیشتر از 10 بار اینو چاپ کرده چرا؟
علتش اینه که فرض کنید مدت زمانی که شما کلید رو فشار می دید مثلا 10 میلی ثانیه باشه ( این عددها همش مثاله و دقیق نیست ) . آردوینو هر 1 میلی ثانیه یک بار میاد این پین شماره 2 رو سرکشی می کنه که مقدارش چقدره ( به خاطر دستور digitalRead که خودمون نوشتیم ) . بنابراین اون 10 میلی ثانیه ای که دست شما روی کلیده آردوینو 10 بار اون پین رو خونده و هر 10 بار هم منطق باینری اون رو HIGH دیده ( چون دست روی کلید بوده و طبق مدار ما در زمان اتصال کلید 5 ولت معادل منطق باینری HIGH روی پین افتاده ) . بنابراین طبق دستوری که ما نوشتیم عین 10 بار پیام Pressed نمایش داده میشه. خب این اصلا خوب نیست. ما به نظر خودمون یه بار کلید رو فشار دادیم ولی 10 بار پیام چاپ شده.

حالا باید دنبال راه حل بگردیم تا این مشکل رو حل کنه:
یکی از راه حل ها استفاده از دستور delay هست به صورت زیر:
2016-01-18_11-18-30
این ساده ترین راه حل هست که الان اگر کد رو آپلود کنیم با هر بار فشار دادن کلید فقط 1 بار پیام Pressed چاپ می شه. با دستکاری مقدار آرگومان تابع delay می تونید دقت های متفاوتی رو به دست بیارید .

راه حل دوم استفاده از خطوط کدنویسی پیچیده تر با استفاده از دستور millis و غیره هست که خب چون ما اول کاریم سراغ این مورد نمیریم.

راه حل سوم استفاده از کتابخونه Bounce2 هست.
این کتابخونه رو با یکی از روش های جلسه قبل به نرم افزار آردوینو اضافه کنید.
لینک فایل زیپ هم اینجاست در صورتی که احتیاج داشتید.

خب حالا مطابق تصویر زیر به مثال bounce برید:
2016-01-18_11-25-35

خب مثال رو که باز کنید با قسمت های زیر مواجه میشید. قبلش من یه آلارم بدم بهتون . معمولا کتابخونه های آردوینو رو با کلاس می نویسن. برای این که با نوشتن کد با کلاس آشنا بشید می تونید از این آموزش استفاده کنید. اگه حوصله یاد گرفتن و این داستانا رو هم ندارید صرفا جاهایی که میگم رو می تونید دقت کنید ولی به نطر من حتما بخونیدش تا در آینده به مشکل برخورد نکنید.
2016-01-18_11-28-03
این قسمت بخش هدر برنامه هست که معرفی کتابخونه ، پینها و آبجکت درون اون قرار داده شده.
2016-01-18_11-46-21

قسمت اول پین متصل به سوئیچ به عنوان ورودی پول آپ تعریف شده است. یعنی چی؟ اگه یادتون باشه تو قسمت سخت افزاری این پروژه ما اومدیم اون پایه ای که به پین دیجیتال آردوینو وصل بود رو با یه مقاومت به زمین وصل کردیم (Pull-down کردیم ). حالا اگه لینک آموزش رو خونده باشید در مقابل Pull-down یه Pull-Up داریم. یعنی به جای این که اون سر مقاومت رو زمین کنیم به 5 ولت وصل کنیم .
511568b6ce395f1b40000000
حالا یه نکته جالب وقتی Pull-down کردیم خودمون رفتیم یه مقاومت برداشتیم و به صورت خارجی تو مدار قرار دادیم. شاید این تصور به وجود بیاد که پول آپ هم همینه دیگه یعنی یه مقاومت بر میداریم منتها به جای این که زمین کنیم 5 ولت می کنیم. اما یه اتفاق خوب این وسط وجود داره .وقتی با آردوینو کار می کنیم دیگه نیازی نیست مقاومت پول آپ رو به صورت خارجی بزاریم بلکه تو خود سخت افزار آردوینو یه فکرایی کردن که سر راه پایه های دیجیتال مقاومت داخلی گذاشتن. فقط باید از آردوینو بخوای این مقاومت داخلی رو بیاره تو مدار که با فرمت INPUT_PULLUP موقع کانفیگ پین دیجیتال بهش میگیم این کار رو بکنه. همونطور که می بینید این اسم دو قسمته: اول INPUT که بهش میگیم این پایه دیجیتال ورودیه و بخش دوم PULLUP هست که بهش میگیم سر راه این پایه دیجیتال یه مقاومت بزار. بنابراین در مقوله Pull-Up ( نه Pull-down ) نیازی به مقاومت خارجی نداریم فقط خود کلید رو میزاریم تو مدار و یکی از پایه هاش رو به پین دیجیتال مورد نظرمون وصل می کنیم.
اما اگه از Pull-Up استفاده کردیم باید به یه نکته حواسمون رو جمع کنیم. وقتی پول آپ می کنیم داریم ولتاژ اون پایه ای از سوئیچ رو که به آردوینو وصله (در حالتی که کلید فشار داده نشده ) رو 5 ولت نگه می داریم (یا همون منطق HIGH ) . بنابراین اون یکی سر سوئیچ رو باید گراند کنیم . منطقیه دیگه مگه نه ! اگه قرار بود اون یکی سر سوئیچ هم مثل مدار اول 5 ولت باشه وقتی سوئیچ رو فشار بدیم به خاطر اتصال دو پایه سوئیچ ، 5 ولت رو به پین دیجیتال وصل می کنه. خب با پول آپ کردن که خودش 5 ولت شده بود .بنابراین برای این که با فشار داده شدن کلید اختلاف سطح منطقی روی پین دیجیتال به وجود بیاد باید اون سر سوئیچ رو به زمین وصل کنیم مطابق عکس زیر:
Button_bb

و اما دستور debouncer.attach:
این دستور یه آرگومان داره که از شما شماره پینی که سوئیچ رو بهش وصل کردید می خواد . تو کد ما در قسمت هدر این پین BUTTON_PIN معرفی شده بنابراین آرگومان ورودی این دستور رو هم BUTTON_PIN قرار دادیم.

دستور debouncer.interval :
این دستور هم یه آرگومان میگیره که زمان اینتروال هست . واحد این آرگومان میلی ثانیه است و مثلا وقتی نوشته 5 یعنی 5 میلی ثانیه زمان نویز نوگیری در نظر گرفته بشه. خب به نظر من که کمه می تونید تا حدود 50 (در اکثر کدها روی 50 تنظیم میشه) افزایشش بدید.

تابع setup هم تموم شد و اما میریم سر وقت تابع loop :
2016-01-19_11-21-33

خب اول دستور debouncer.update :
با این کار وضعیت پین دیبانس که در حال نمونه برداریه به روز می شه بعد از اون با دستور debouncer.read این مقدار خونده میشه. اگه این داده ای که خونده سطح منطقی LOW باشه LED شماره 13 آردوینو رو که همون LED داخلی آردوینو هست روشن میکنه. دقت کنید چون مدارمون رو عوض کردیم وقتی کلید وصل بشه پایه دیجیتال شماره 2 آردوینو به زمین متصل میشه و سطح منطقیش برابر LOW میشه (به همین دلیل این مدلی کد نویسی شده).

بنابراین با این سخت افزار ساده که فقط و فقط خود کلید وصله بدون هیچ نویزی تونستیم اثر فشار داده شدن کلید رو لحاظ کنیم.
تو این کد که کد پیش فرض این کتابخونه بود برای فشار داده شدن سوئیچ عمل روشن شدن LED در نظر گرفته شده بود . شما میتونید هر عملیاتی رو از جمله چاپ پیام در کنسول سریال انجام بدید.

*************************

کتابخونه دیبانس 2 تا دستور دیگه داره fell و rise که اگه کسی خواست بدونه اینا چیکار می کنن می تونه تو انجمن سوالش رو مطرح کنه.