جلسه هجدهم : راه اندازی LCD کاراکتری 1602

به نام خدا
اول جلسه یه پیشنهاد دارم : این که اول کل جلسه رو یه دور تا آخر بخونین بعد قسمت های سخت افزاریش رو اجرا کنین چون دو روش ارائه میشه. پس تا آخر جلسه رو بخونید هر کدوم از دو روش رو که خواستین انجام بدین.
این جلسه قصد داریم در مورد LCD کاراکتری 1602 حرف بزنیم . اول بگیم که چرا به این میگن 1602: این نمایشگر 16 تا ستون و دو تا سطر داره همین ! در مورد این که چرا لازمه تو پروژه هامون LCD داشته باشیم فکر نمی کنم هیچ نیازی داشته باشه که توضیح بدم. فقط همینو بگم که تا الان هر چیزی رو که می خواستیم ببینیم (مثلا عدد پتانسیومتر ) روی کنسول سریال آردوینو می دیدیم ولی خب خیلی مواقع ممکنه مدارمون رو از کامپیوتر جدا کنیم و با یه سوئیچ آداپتور ببریمش یه جایی وصلش کنیم که هیچ نوع کامپیوتری نباشه که بتونیم از کنسول سریالش استفاده کنیم. وقتی تو همچین شرایطی گرفتار شدیم می ریم سراغ استفاده از انواع LCD ها.
character_2x16_modules_lcd_display_hd44780_controller_black_on_yg
این نمایشگر 16 تا پایه داره که اگه به عکس بالا یه کم دقیق بشید کنار پینها یه شماره 1 می بینید یه شماره 16 . ارتباط آردوینو و این LCD به صورت پارالل هست به همین خاطر باید یه عالمه پین رو وصل کنیم پس بدون فوت وقت بریم سراغ سخت افزار مدرا .

مواد لازم :
هر نمونه آردوینو در دسترس
LCD کاراکتری 1602
برد بورد کوچیک
پتانسیومتر
مقاومت 220 اهم
سیم نری به نری

خب حالا مدارتون رو مثل عکس زیر ببندید :
LCD_Base_bb_Fritz
LCD_Base_bb_Schem
میدونم مدارش زیاد دل و روده داشت بنابراین خسته نباشید.
پروژه ای که می خوایم انجام بدیم اینه که هر چیزی رو که از کنسول سریال دریافت کردیم توی LCD نمایش بده .
برای این کار کتابخونه Liquid Crystal رو به کتابخونه های آردوینو اضافه کنید:
Adafruit_LiquidCrystal-master
آموزش اضافه کردن کتابخونه هم اینجاست:

بعد از این که کتابخونه رو به صورت موفقیت آمیز به آردوینو اضافه کردید مثل عکس زیر کد serialdisplay رو بیارید :
2016-01-30_14-07-20
خب با یه همچین کدی مواجه میشید (البته من نیم کیلو کامنت بالاش رو پاک کردم ):
2016-01-30_14-09-10

قسمت های مختلف :
1:معرفی کتابخونه LiquidCrystal

2: اگه یادتون باشه قبلا هر وقت یه پین رو استفاده می کردیم میومدیم توی هدر برنامه بهش اسم می دادیم . الان اگه بشمارید 6 تا سیم از LCD وصل کردیم به پین های آردوینو . قائدتا باید 6 تا متغیر تو هدر تعریف می کردیم . پس کو ؟ چرا نکردیم ؟ همین خط دستوری که اینجا نوشتیم (LiquidCrystal lcd(12, 11, 5, 4, 3, 2 دقیقا همین کار رو میکنه. فقط فرقش اینه که اون تعریف کردنا به جای اینه اینجا نوشته بشه رفته تو کتابخونه نوشته شده .

3.توی این قسمت کانفیگ پین هایی که تو قسمت 2 معرفی شد انجام میشه.تابع begin در کتابخونه LiquidCrystal پین های معرفی شده در قسمت 2 رو به صورت ورودی / خروجی کانفیگ میکنه. علاوه بر این تعداد سطر و ستون های LCD به عنوان آرگومان های ورودی این تابع قرار داده میشه (یعنی 2 و 16).

4: کانفیگ ارتباط سریال با baude rate مساوی 9600.

بافر ارتباط سریال : قبل از توضیح پارت پنجم لازمه در مورد بافر سریال یه توضیح خیلی ساده بدم. در همین حد بدونید که بافر سریال یه واسطه . یعنی هر آنچه که شما توی کنسول سریال آردوینو تایپ می کنید قبل از این که با دستور Serial.read بریزیدش تو یه متغیر، توی بافر سریال ذخیره میشه. بافر رو یه چیزی مثل شکل زیر تصور کنید که هر کاراکتری که ما تو کنسول تایپ می کنیم میره تو یکی از خونه های این بافر می شینه.

2016-01-30_14-53-39
5: این جا داریم میگیم اگه چیزی توی بافر ارتباط سریال وجود داشت بیا کارای توی کروشه رو انجام بده . دقت کنید با if نوشته . دستور Serial.available میاد تعداد متغیرهایی رو که توی بافر ارتباط سریال هست رو خروجی میده. یعنی مثلا اگه شما تو کنسول سریال تایپ کرده باشید salam خروجی دستورSerial.available عدد 5 هست (یعنی 5 تا کاراکتر). اینجا داره میگه اگه خروجی این دستور بزرگتر از صفر بود (یعنی یه چیزی توی کنسول سریال آردوینو نوشته شده بود (اصلا مهم نیست چند تا)) بیا دستور های بین دو کروشه مربوط به این if رو اجرا کن.

6: اینجا 100 میلی ثانیه صبر می کنه تا کل اون چیزی که ما توی کنسول سریال تایپ کردیم تو بافرارتباط سریال جا بگیره .

7: با دستور clear تمام داده های روی LCD پاک میشه در واقع LCD رو خالی می کنه تا داده بعدی روش چاپ بشه.

8 و 9 : اتفاقی که توی این دو خط کد می افته اینه که داده های خونه های بافر ارتباط سریال دونه دونه روی LCD چاپ میشن تا جایی که بافر خالی بشه. علت این که از while استفاده شده اینه که باید تک تک خونه ها رو خالی کنه تا جایی که دیگه بافر خالی بشه . بعد با دستور (()lcd.write(Serial.read میاد هر چیزی رو که از کنسول سریال میگیره توی LCD چاپ می کنه.

دقیق تر بگم ؟
بار اول که وارد دستور (while (Serial.available() > 0 میشه خروجی دستور Serial.available() مساوی 5 خواهد بود (چون salam توی بافر سریاله ) .بنابراین شرط برقراره و از while عبور میکنه میاد دستور (()lcd.write(Serial.read رو اجرا می کنه .

اگه یادتون باشه توی جلسه ای که در مورد ارتباط سریال حرف میزدیم می گفتیم Serial.read فقط یک کاراکتر رو بر می گردونه . یعنی اگه توی بافر سریال ما مثل بالا salam نوشته شده باشه نمیاد کل salam رو به عنوان خروجی بده فقط S رو برمیگردونه و بعد بافر سریال رو به این شکل در میاره یعنی S رو از اون خارج می کنه :
2016-01-30_15-23-13
توی همین بار اول کاراکتر S با دستور (()lcd.write(Serial.read روی LCD چاپ میشه.
به آخر while  می رسیم .طبق خاصیت حلقه while یک باردیگه شرایط while چک میشه. اگر شرط برقرار باشه وارد حلقه میشه اگه شرط برقرار نباشه از حلقه while خارج میشه.
بار دوم که قراره شرط while چک بشه خروجی دستور Serial.available() مساوی 4 خواهد بود بنابراین بازم شرط برقراره و یک بار دیگه دستور (()lcd.write(Serial.read اجرا میشه و این بار a از بافر سریال خارج میشه و توی LCD چاپ میشه .

اینطوریه که کارکاترها دونه دونه از بافر خارج میشن و روی LCD چاپ میشن تا جایی که بافر خالی بشه و خروجی دستور Serial.available() مساوی صفر بشه. در این حالت شرط while  برقرار نمیشه و از حلقه خارج میشیم.

برای این که حرف منو بهتر درک کنین این قسمت از کد رو تغییر بدید و اپلود کنید:
2016-01-30_16-42-17
همونطور که میبیند هر کدوم از کاراکترها با فاصله زمانی 2 ثانیه روی LCD چاپ میشن.

خب تا این جای داستان پارت اول جلسه تموم شد که راه اندازی اولیه نمایشگر بود. توی کتابخونه LiquidCrystal علاوه بر serialdisplay مثال های دیگه ای هم وجود داشت که می تونید اجرا کنید و ببینید و اگه سوالی داشتید تو انجمن بپرسید .

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

آزار دهنده ترین قسمت انجام این پروژه قسمت سیم بندی اون بود که مجبور بودیم n تاسیم رو با مقاومت و پتانسیومتر استفاده کنیم .
یه راه حل خیلی خوب وجود داره که به جای این همه بند و بساط با 4 تا دونه سیم بتونیم ارتباط نمایشگر و آردوینو رو فراهم کنیم.
برای این کار فقط باید دستمونو بکنیم تو جیبمون و یه دونه از درایور های LCD بخریم :2016-01-30_16-17-22

بعد از این که اینو خریدید لحیمش کنیمد پشت LCD به این شکل :
2016-01-30_16-15-27

وقتی لحیم کاری تموم شد الان سخت افزارمون رو به این شکل می بندیم :
LCD 1602 I2C SCH

می بینید فقط 4 تا دونه سیم .بدون پتانسیومتر ، بدون مقاومت و بدون n تا سیم. اگه دقت کنید علاوه بر VCC و GND دو تا پین دیگه وجود داره به نام های SCL و SDA. این دو تا پین ، پین های ارتباط I2C هستن . ارتباط I2C یکی از پرکاربردترین پروتکل های ارتباطی تو کار ماست . خیلی از سنسورها خیلی از نمایشگرهامون با این پروتکل کار میکنن و ما باید بتونیم تشخیصشون بدیم و راهشون بندازیم. حالا یه سوال پیش میاد و اونم اینه که یه قطعه رو که پروتکل ارتباطیش I2C هست چطوری تشخیص بدیم؟
جواب سوال اینه که به پین های قطعه نگاه می کنیم در صورتی که روی پینهای قطعه اسم های SCL و SDA وجود داشت پروتکل ارتباطی اون قطعه I2C هست.

حالا قطعه هایی رو که پروتکل ارتباطیشون I2C هست چجوری به آردوینو وصل کنیم ؟آیا پین خاصی دارن ؟
مطابق جدول زیر این قطعه ها رو به آردوینو وصل می کنیم :
2016-01-30_16-39-40

یعنی اگه با آردوینو UNO کار می کنید باید به پایه های آنالوگ 4 و 5 وصل کنید. اگه با مگا کار می کنید به پایه های دیجیتال 20 و 21 وصل کنید و الی آخر.

ما روی UNO کار می کنیم بنابراین به پایه های آنالوگ 4 و 5 وصل می کنیم . دقت کنین که ترتیب پایه ها تغییر نکنه که اگه جا به جا بزنین پروژه به هیچ عنوان کار نمی کنه.

خب مدار رو بستید حالا کتابخونه زیر رو به نرم افزار آردوینو اضافه کنید:
LiquidCrystal_I2C

مثل حالت قبل مطابق عکس زیر مثال serialdisplay رو بیارید :
2016-01-30_16-47-28

کدی مثل همون کد قبلی رو به این صورت میبینید (البته من بازم کامنت ها رو پاک کردم ) :
2016-01-30_16-50-17

1: معرفی کتابخونه Wire (در مواقع استفاده از پروتکل I2C صدا زده میشه )

2.معرفی کتابخونه LiquidCrystal_I2C

3.این جا تعداد سطر ها و ستون ها و آدرس I2C نمایشگر معرفی میشه (دقت کنید هر قطعه ای که با I2C کار کنه یه آدرس خاص داره مثلا مال این LCD آدرسش 0X27 هست)

4. بک لایت (نوز زمینه) نمایشگر صدا زده میشه.

بقیه قسمت های کد دقیقا مثل قبله و با همون توشیحات می تونید درکش کنید. کد رو آپلود کنید و استفاده کنید.

همون کیفیت کد با یه کتابخونه متفاوت و البته با سادگی سخت افزار بسیار زیاد اجرا شد.
پایان

جلسه هفدهم : ساخت ولت متر با آردوینو

سلام
در این پروژه قصد داریم با استفاده از آردوینو و دو تا دونه مقاومت خشک و خالی یه ولت متر دیجیتال بسازیم.
مسلما همگی می دونید ولت متر چیه دیگه : یه دستگاهی هست که با کمک اون می تونید ولتاژهای قسمت های مختلف یک مدار رو اندازه گیری کنید (به این شرط که با اون مدار زمین مشترک (کامان گراند common ground ) بشید و یا در حالت کلی اختلاف ولتاژ دو نقطه از مدار رو بهتون میده.

خب یک راست میریم سراغ سخت افزار مورد نیاز. مواد لازم :
آردوینو از هر مدلی
یه دونه مقاومت 10 کیلو اهم
یه دونه مقاومت 100 کیلو اهم
یه دونه برد بورد کوچیک

حالا مثل عکس زیر مدار رو ببندید:

adruino-sketch

خیلی خیلی خیلی حواستون جمع باشه که مقاومت ها را جا به جا نزارید.
طبق قوانین موجود در مدار و تقسیم ولتاژ این رابطه بین ورودی و خروجی وجود داره :
Vout = (R2 / (R1 + R2)) * Vin

Vout همون ولتاژی هست که روی پایه آنالوگ اردوینو می افته و توسط ADC داخلی آردوینو به یه عدد بین 0 تا 1023 تبدیل میشه .
Vin ولتاژی هست که میخوایم اندازی گیریش کنیم. امیدوارم با فرمول مشکلی نداشته باشید چون دقیقا قانون تقسیم ولتاژ مدار هست.
حالا یه سوال اساسی پیش میاد و اون اینه که ولتاژی که قراره اندازی گیری بشه تا چند ولت می تونه باشه؟ یعنی 100 ولت ؟ 50 ولت ؟ 10 ولت ؟ چقدر؟

جواب این سوال تو همون فرمول در میاد. ما میدونیم که ماکزیمم ولتاژی که می تونه به پین آنالوگ آردوینو داده بشه و آردوینو بدون مشکل باهاش کار کنه 5 ولته (به شرطی که ولتاژ آنالوگ رفرنس همون 5 ولت باشه . در مورد این آخر آموزش حرف میزنم زیاد درگیرش نشید.) طبق مداری هم که بستیم R1 مقاومت 100 کیلو اهمی و R2 مقاومت 10 کیلو اهمی هست ( مطابق عدد گذاری های عکس دارم میگم ) . اگر تو فرمول بالا به جای vout مقدار 5 و به جای مقاومت ها مقادیر متناظرشون رو بزارم مقدار vin به دست میاد 55. یعنی ورودی اگر 55 ولت باشه روی پین آنالوگ آردوینو ماکزیمم حد تحملش یعنی 5 ولت می افته. وقتی داشتید مدار رو می بستید بهتون گفتم حواستون باشه مقاومت ها رو جا به جا نذارید یادتونه ؟ حالا بیاید تصور کنیم شما جای R1 و R2 رو برعکس تومدار می ذاشتید. در اون صورت بازم طبق فرمول به ازای vout مساوی 5 ولت و اون مقدار مقاومت ها ماکزیمم مقدار ولتاژ قابل اندازی گیری 5.5 ولت می شد. حالا قابل درک شد براتون ؟ حالا شما اگه می خواید این محدوده اندازه گیری رو بزرگ تر یا کوچیک تر کنید می تونید با بازی با این مقاومت ها به هدفتون برسید فقط باید به یه نکته توجه داشته باشید که هر چی دامنه ولتاژ ورودی قابل اندازه گیری بالاتر بره دقت اندازه گیری پایین تر میاد و حساسیت اندازه گیری نسبت به تغییرات ولتاژ کمتر میشه.

خب مدار رو بستید ؟ حالا بریم سراغ کد نویسی .
این کد رو آپلود کنید تا در مورد قسمت های مختلفش حرف بزنیم:
2016-01-27_10-29-04

قسمت هدر برنامه میاد مقدار مقاومت های R1 و R2 رو به عنوان متغیر تعریف می کنه. فایده این کار اینه که اگه کسی خواست رنج اندازه گیری ولتاژش متفاوت باشه و در نتیجه اومد این مقاومت ها رو عوض کرد با همین تغییر ساده بتونه کد رو برای مدار خودش ادیت کنه. توجه کنید که اندازه ها بر حسب اهم وارد میشن یعنی 10 کیلو اهم میشه 10000.
اما تو همین هدر یه متغیر دیگه هم وجود داره به نام Vref. Vref یه مفهوم خیلی مهم در دنیای آنالوگ آردوینو هست که لازمه کامل در موردش توضیح داده بشه.
برای درک بهتر قضیه آردوینوتون رو با کابل USB به کامپیوتر وصل کنید تا روشن بشه. وقتی روشن شد ولتاژ های دو پایه نشون داده شده تو عکس زیر رو با یه ولت متر اندازه بگیرید.
arduino_uno
جالبه نه ؟ پایه ای که روش زده 5v روی ولت متر 5 ولت نیست! پایه Aref هم 5 ولت نیست. مثلا من 4.4 اندازه گرفتم. ممکنه شما یه عدد دیگه مثلا 4.8 یا 4.5 یا هر عددی رو اندازه بگیرید. ولی پایه 3.3v کنار 5v رو که اندازه بگیرید می بینید اون عینا 3.3 ولته. چه خبره ؟ چرا پایه 5v تو واقعیت 5 ولت نیست؟
حالا برید من همین برد آردوینوتون  رو با یه منبع تغذیه سوئیچینگ 9 ولت روشن کنید و ولتاژ همون دو تا پین رو اندازه بگیرید. عجب! تو اندازه گیری من که هر دو 5.00 شدن.

بنابراین می بینید نوع پاور دادنمون به آردوینو چقدر می تونه مهم باشه که از طریق USB بهش پاور بدیم یا از طریق منبه تغذیه های سوئیچینگ.
حالا این پایه Aref چیه که گیر دادیم بهش هی ولتاژشو اندازه می گیریم؟ Aref پایه ای هست که ولتاژش حد ماکزیمم ولتاژ های آنالوگه قابل درک برای آردوینو هست. یعنی در واقع ADC آردوینو ولتاژ های 0 تا Aref ولت رو به عدد بین 0 تا 1023 تبدیل کنه . حالا اگه این Aref همون 5 ولت باشه که خب عالیه و داره درست کار می کنه (مثل حالتی که با منبع تغذیه سوئیچینگ بهش پاور دادیم) اما اگه مثل حالتی که با USB بهش پاور دادیم این ولتاژ روی 4.4 باشه فاجعه پیش میاد! چرا ؟ چون فقط ولتاژهای 0 تا 4.4 ولت به 0 تا 1023 تبدیل میشن . یه کم واضح تر بگم :
فرض کنید سنسور آنالوگی که به آردوینو وصل کردیم یه سنسور فاصله سنج باشه که هر چی فاصله تشخیص داده شده توسط سنسور کمتر میشه ولتاژی که روی پایه آنالوگ سنسور که متصل به پین آنالوگ آردوینو هست بیشتر بشه. یعنی وقتی مثلا فاصله 2 متری رو تشخیص بده ولتاژ آنالوگش 3.5 ولت باشه، وقتی فاصله 1 متر رو تشخیص بده ولتاژ آنالوگش 4.4 باشه و موقعی که فاصله تشخیص داده شده نیم متر باشه بشه ولتاژ آنالوگ 4.8 باشه.
اگه آردوینو من ولتاژ Aref اش 5 ولت باشه هیچ مشکلی نداره به ازای هر فاصله ای که سنسور تشخیص بده آردوینو یه عدد تو بازه 0 تا 1023 بر می گردونه چون سقف ولتاژ آنالوگ قابل درکش همون 5 ولته.
اما اگه ولتاژ Aref آردوینو من 4.4 باشه یه مشکل بزرگ پیش میاد. تا فاصله یک متر رو که عدد ولتاژ آنالوگ 4.4 هست هیچ مشکلی نداره. ولی وقتی که عدد ولتاژ آنالوگ سنسور بالاتر از 4.4 بشه (که معنیش اینه که فاصل کمتر از 1 متر رو تشخیص داده ) تو خروجی ADC آردوینو هیچ تغییری بوجود نمیاد (نسبت به فاصله 1 متر) چون تو فاصله یک متر که عدد ولتاژ آنالوگ 4.4 ولت شده خروجی این ADC اومده روی 1023 و چسبیده به سقفش. حالا وقتی سنسور فاصله نیم متر رو تشخیص بده که در نتیجه ولتاژ 4.8 رو پایه آنالوگش بیفته خروجی ADC آردوینو همون 1023 می مونه. یعنی براش فرقی نمی کنه فاصله تشخیصی 1 متر باشه ، نیم متر باشه یا ده سانت باشه و این یعنی همون فاجعه یعنی فاصله زیر 1 متر یا بعبارتی ولتاژ بالاتر از 4.4 ولت برای آردوینو یک رفتار محصوب خواهد شد.

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

برگردیم به کد. این متغیر Vref که تو هدر برنامه تعریف شده ولتاژ اندازه گیری شده پایه Aref هست. یعنی باید اول ولتاژ پایه Aref رو اندازه بگیرید ببینید مال شما چقدره و تو کدتون تومتغیر Vref جایگزین کنید. من چون 4.4 بودم این عدد رو به 4.4 تغییر میدم.

تو تابع setup هم که اومده ارتباط سریال و پین آنالوگ رو کانفیگ کرده. بعد دو خطر سریال پرینت کرده که فقط برای زیبایی برنامه هست که تو کنسول سریال موقع استارت برنامه بگه قراره چیکار کنه و ماکزیمم ولتاژ قابل اندازه گیری با این ولت متر دستی چقدره. اما یه خط کد داره به این صورت:
;((((Serial.print((int)(Vref / (R2 / (R1 + R2
یادتونه اول این آموزش حساب کردیم ماکزیمم ولتاژ قابل اندازه گیری این ولت متر چقدره ؟ همون فرموله رو میگم. الان کد با این خط دستور دقیق داره همون کار رو میکنه فقط به صورت کلی . ما برای حالت خاص 5 ولت حساب کردیم که شد 55 . این داره میگه اگه شرایط بحرانی بود و ولتاژ پایه Aref کمتر از 5 ولت بود هم طوری نمیشه. جای همون 5 که خودمون حساب کردیم الان مقدار Vref (ولتاژ اندازه گیری شده پایه Aref ) رو بزارید و تمام. فرق دوم اینه که نوشته (((int)(Vref / (R2 / (R1 + R2) .اگه دقت کنید متغیرهای R1 و R2 و Vref تو هدر برنامه از نوع float انتخاب شدن وقتی می نویسه (int) داره متغیر float رو به int تبدیل می کنه . شما می تونید برش دارید و هیچ مشکلی هم بوجود نیاد. بنابراین با این خط کدنویسی فقط داریم تو تابع setup میگیم که حداکثر ولتاژ قابل اندازه گیری با این ولت متر انقدره. ادامه هم که باز یک سری سریال پرینت هایی هست که برای زیبایی خروجی برنامه در کنسول نوشته شده.

و اما تابع loop .
خط ; float v = (analogRead(0) * Vref) / 1024.0
قسمت analogRead که معلومه داره چیکار می کنه (می بینید که ننوشته A0 نوشته 0 و مشکلی هم بوجود نمیاد ) . اما این وسط یه سری ضرب و تقسیم ها وجود داره که باید بفهمیم اینا چیه .
هدف ما تو این برنامه این بود که با فرمول مطرح شده تو قسمت بالای جلسه بتونیم ولتاژ رو اندازه بگیریم. اگه به فرمول اول جلسه دقت کنید دو تا متغیر داشت vout و vin . جنس هر دوی این متغیر ها ولتاژه دیگه درسته ؟ vout ولتاژ روی پایه آنالوگ آردوینو بود و vin ولتاژی بود که ما می خواستیم اندازه بگیریم . چیزی که analogRead تنها به ما میده یه عدد تو بازه 0 تا 1023 هست. حالا ما باید ببینیم چه ولتاژی روی پین آنالوگ شماره 0 افتاده بوده (یعنی vout ) که بعد با استفاده از فرمول بریم vin رو پیدا کنیم. در واقع الان باید عدد تو بازه 0 تا 1023 رو که با دستور analogRead خوندیم به یه ولتاژ تو بازه 0 تا Vref تبدیل کنیم که بشه همون vout فرمولمون. یه تناسب ساده بسته برای این کار. عدد خروجی analogRead رو تو Vref ضرب کرده .و به 1024 تقسیم کرده. خروجی این ضرب و تقسیم ها ریخته میشه تو متغیر v که در واقع همون vout ماست.

خط ;((float v2 = v / (R2 / (R1 + R2
تو این خط همون فرمول بالای جلسه رو پیاده سازی کرده . ریخته تو متغیر v2 که درواقع همون vin ماست وپرینت کرده. یه delay پونصد میلی ثانیه هم گذاشته تا روند نمایش دادن یه ذره کند بشه.
خب کد رو آپلود کنید و تو کنسول نتیجه رو ببینید.

پایان جلسه.

جلسه شانزدهم : راه اندازی فتوسل

سلام

دوستان از این جلسه به بعد تصمیم داریم دونه دونه بریم سراغ سنسورها. چه آنالوگ چه دیجیتال. هر جلسه یه سنسور رو آموزش می دیدم که چیه چجوری کار می کنه و کد آردوینو براش می نویسیم.

این جلسه می خوایم در مورد فتوسل حرف بزنیم.
09088-02-L

PHOTOCELL2A

 

به زبون خیلی خیلی ساده بخوایم بگیم فوتوسل یه مقاومته. حالا یه سوال پیش میاد که آیا عین همون مقاومتهای خودمونه که تا الان باهاشون کار می کردیم؟ جواب اینه که هم آره هم نه.
بدون شک تا حالا مقاومت دیدید دیگه درسته ؟
imgres
این مقاومت هایی که تا الان باهاشون کار می کردیم اصطلاحا بهشون میگن مقاومت های ثابت. یعنی وقتی میگیم این مقاومت 10 کیلو اهمه یعنی بالا بری پایین بیای، تو مدار این سر دنیا بزنی تو مدار اون سر دنیا بزنی، هر کاری کنی کنی این مقاومت 10 کیلو اهمه. البته همونطور که میدونید بر حسب رنگ چهارم مقاومت ها که طلایی باشه یا نقره ای یه تلورانسی در حد دهم اهم دارن ولی فارق از این تلورانس ،یک مقاومت ثابت هستن و با هیچ واکنش محیطی و یا واکنش مداری این عدد (مثلا همون ده کیلو ) تغییر نمی کنه .

فتوسل هم یه مقاومته ولی از نوع مقاومت متغیر. یعنی وقتی میزان نور محیطی که این فتوسل توشه تغییر کنه مقاومتی که از دو سر این فتوسل دیده میشه تغییر می کنه. بنابراین هم مقاومته و هم مثل اون مقاومت های معمولی نیست. حالا این که چجوری این انرژی نورانی میاد و کاری می کنه که مقاومت دو سر فتوسل تغییر کنه یه سری فعل و انفعالات داخلیه که من به شخصه علاقه ای بهش ندارم ولی شما می تونید سرچ کنید و با این تکنولوژی آشنا بشید. در کل چیزی که واسه ما مهمه اینه که وقتی شدت نور تابیده شده به این سنسور تغییر می کنه مقاومت دوسرش هم تغییر می کنه. واسه اطلاعات تکمیلی هم بگم که به فوتوسل مقاومت نوری و یا  light-dependent resistor) LDR ) گفته می شه.

خب حالا قصد داریم این سنسور رو با آردوینو راه بندازیم.
مواد لازم:
آردوینو (هر نوعی )
سنسور فتوسل
برد بورد کوچیک
سیم نری به نری

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

همونطور که می بینید اومده یه مقاومت 10 کیلو اهمی (ثابت ) رو با فتوسل سری کرده و از پایه مشکترک بینشون به پین آنالوگ آردوینو داده. منطق این کار همون منطق تقسیم ولتاژه.
images

وقتی مقاومت فتوسل (با تغییر نور ) تغییر می کنه طبق قانون تقسیم ولتاژ ، ولتاژی که روی پایه وسط (مشترک بین مقاومت و فتوسل ) می افته هم تغییر می کنه که چون این تغییر به صورت پیوسته هست این پایه وسط رو به پین آنالوگ آردوینو (پین شماره 0 ) وصل می کنیم.

خب مدار رو بستید؟
بریم سراغ کد. برای کد عینا عینا عینا همون کد پتانسیومتر رو آپلود کنید. یعنی این کد :
2016-01-20_13-07-301

خب کد رو آپلود کنید و کنسول سریال رو باز کنید:
2016-01-26_12-26-48

همونطور که می بینید مقدار دیفالت سنسور روی حدود 600 بود . بعد دستم رو گذاشتم روی فتوسل ( روی قسمت بالایی ) و داده نشون داده شده از 600 به حدود 200 افت پیدا کرد. دوباره که دستم رو برداشتم برگشت رو همون حدودای 600 . این یعنی تو محیطی که تست کردم محدوده روشنایی 600 و محدوده تاریکی 200 هست. جایی که شما دارید تست می کنید می تونه اعداد تو رنج های کاملا متفاوتی بده بر حسب نور محیطی تون.

حالا کنسول رو ببندید و سریال پلاتر رو باز کنید و هی دستتون رو بزارید رو فتوسل و بردارید تا براتون شکل موج بکشه ( محض تفریح البته ).
2016-01-26_12-34-38

می تونیم همینجا پروژه رو تموم کنیم اما نمی کنیم. می خوایم سیستم روشنایی اتوماتیک بسازیم. یعنی هر موقع نور کم شد و احتیاج به روشنایی داشتیم لامپ روشن بشه .نه این که هر دقه و هر ثانیه اون لامپ بدبخت کار کنه.
برای این کار به مدار قبلیمون یه LED به صورت زیر اضافه می کنیم:
Photocell_bb
قسمت فتوسل که عینا همونه . اومدیم یه LED رو با یه مقاومت سری کردیم و به پین دیجیتال شماره 2 وصل کردیم. علت وجود مقاومت سری با LED اینه که از سوختن اون جلوگیری بشه. تو همه مدارا این قانون وجود داره که سر راه هر LED باید مقاومت گذاشته بشه.

خب مدار رو بستید تمام ؟
حالا کد زیر رو آپلود کنید تا براتون توضیح بدم:
2016-01-26_13-04-56

تو قسمت هدر برنامه که فقط اومدیم علاوه بر متغیر های کد قبلی متغیر ledPin رو معرفی کردیم به عنوان پین شماره 2 .
تو قسمت کانفیگ دیگه سریال رو برداشتیم چون نیازی بهش نبود و به جاش پین دیجیتال ledPin رو به عنوان خروجی تعریف کردیم.
تو تابع loop خط اول ، داده کانال ADC شماره 0 رو می خونیم و تو متغیر sensorValue می ریزیم ( همون متغیری که تو هدر برنامه تعریف کردیم ).
تو کد قبلی دیدیم که حد روشنایی 600 و حد تاریکی 200 بود.
حالا کد نوشتیم اگه داده ای که خونده از 300 کمتر بود (یعنی رفته باشیم تو تاریکی ) بیا led رو روشن کن. معقوله دیگه وقتی تاریک میشه باید چراغا رو روشن کنیم.
تو خط بعدی هم نوشتیم اگه داده ای که خوندی از 500 بیشتر بود (یعنی تو روشنایی بودیم ) led رو خاموش کن چون هوا روشنه و نیازی به نور اضافه نداریم.

اعداد 300 و 500 رو که من تو کدم قرار دارم بر اساس محیط تستم بود. یعنی همون عدد هایی که با کد قبلی از کنسول در آوردم . شما هر رنج عددی که دارید می تونید در نظر بگیرید و این کد رو متناسب با محیط تست خودتون تغییر بدید.
یعنی مثلا اگه کسی تو تستش تاریکی رو روی عدد 120 داشت (مثلا ) نیازی نداره مثل کد من مرز تاریکی رو 300 بزاره میتونه 200 یا حتی کمتر انتخاب کنه.

و اما نکته آخر :
اگه دقت کنید من وقتی دستورهای if رو نوشتم هیچ آکولادی باز و بسته نکردم در صورتی که قبلا می گفتیم اگه شرط if برقرار بشه دستورهای بین دو آکولادی که باز و بسته شدن اجرا میشه{}. خب الان هیچ آکولادی نیست پس در صورت برقرار بودن شرط if چی اجرا میشه؟
جواب: این یه قانون برنامه نویسیه که اگر بعد از برقرار شدن شرط if تنها یک کار لازم باشه انجام بشه دیگه نیازی به گذاشتن آکولاد نیست. دقیقا مثل شرایط الان ما. در صورتی که نور از مرز تاریکی کمتر بشه فقط لازمه LED روشن بشه (یعنی فقط یک کار ) پس به آکولاد نیازی نیست.

پایان جلسه

جلسه پانزدهم : رسم نمودار ( پلات ) با استفاده از آردوینو

سلام
تو این جلسه قصد دارم بهتون یاد بدم چجوری با استفاده از آردوینو نمودار رسم کنید. چیزی که شاید خیلی از جاها به دردتون بخوره . ورژنای قدیمی نرم افزار آردوینو این امکان رو نداشت که بتونیم باهاش پلات کنیم (نمودار رسم کنیم ) ولی خب تو ورژنای جدید (از 1.6.6 به بالا) شکر خدا عقلشون کار کرده و این آیتم رو گذاشتن. یعنی ما تنها با استفاده از نرم افزار آردوینو و بدون نیاز به نصب هیچ نرم افزاری می تونیم نمودار تغییرات رو ببینیم.

یه توضیح کلی: اول بزارید ببینیم این امکانی که داریم ازش حرف می زنیم کجای نرم افزاره . از منوی Tools وارد Serial plotter میشیم:
2016-01-24_13-07-57
همونطور که می بیند اسم این آیتم سریال پلاتر هست و ما هم از این به بعد به این آیتم پلاتر میگیم. یه نمای کلی هم بخواید ازشکل رسم نمودارش ببینید این شکلیه:
2016-01-24_13-12-32

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

ما هم نمودار دیجیتال رو رسم می کنیم هم نمودار آنالوگ رو.
اول سوئیچ مدار و کد جلسه سیزدهم رو آماده کنید. مدار آخر رو ببندید که با دیبانس نوشتیم. همچین کدی داشتیم اگه یادتون باشه (البته من برای این که کد کوتاه بشه خط های کامنت ها رو پاک کردم)
2016-01-24_13-33-50

ما تو این کد برای این که ارتباط سریال داشته باشیم لازمه یه تغییراتی رو توی کد نویسیمون اعمال کنیم.
2016-01-24_13-39-31
چون لازم داشتیم ارتباط سریال استفاده کنیم خب تو تابع setup کانفیگش کردیم. اگه یادتون باشه گفتیم اساس کار سریال پلاتر ارتباط سریال هست که خدارو شکر تو آردوینو ایجاد ارتباط سریال بین آردوینو و کامپیوتر فقط با یک خط کد انجام میشه یعنی دستور Serial.print. هر آرگومانی که توی این دستور نوشته بشه عینا به صورت سریال (از طریق همون کابل USB که بین آردوینو و کامپیوتر هست ) به کامپیوتر شما ارسال میشه. بنابراین توی این کد هر جا منطق پین دیجیتال شماره 2 صفره ما هم 0 رو سریال پرینت می کنیم هر جا منطق پین یکه ما هم 1 رو سریال پرینت می کنیم.

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


دقت کنید در فیلم جاهایی که یهو یه تغییر دامنه داریم لحظاتی هست که کلید رو فشار دادیم.

این مدل دیجیتالش حالا مدل آنالوگ.
جلسه چهاردهم رو یادتونه ؟ همون مدار و همون کد رو عینا بیارید.
اگه یادتون باشه تو اون جلسه داده های پتانسیومتر رو روی کنسول سریال می دیدیم پس هیچ احتیاجی به تغییر کد نخواهیم داشت. همون کد رو آپلود کنید و سریال پلاتر رو باز کنید.

همونطور که می بینید دقیقا داره متناسب با تغییر ولوم پتانسیومتر (که دست من بود و شما نمی دیدید) نمودار تغییر می کنه.

اما این سریال پلاتر عزیز ما یه مشکل داره و اونم اینه که همزمان که سریال پلاتر بازه کنسول سریال قبلی رو نمیشه باز کرد . در عین واحد فقط یکیش می تونه کار کنه که امیدواریم یه راه حلی واسه این مشکل بعدا پیدا کنن.

پایان جلسه

جلسه چهاردهم : پتانسیومتر

سلام

حدود 10 جلسه فقط و فقط از پینهای دیجیتال حرف زدیم . این که به پین دیجیتال مقدار بدیم یا از پین دیجیتال مقدار بخونیم .
این جلسه تمرکزمون رو می بریم روی آنالوگ ها . اینجا ببینید که کلا سیگنال آنالوگ چیه.

تو این آموزش قراره یاد بگیریم که چجوری با استفاده از آردوینو داده یک سنسور آنالوگ رو بخونیم. ولی قبل از این درست مثل حالت دیجیتال یه بحث کلی داریم روی ورودی و خروجی بودن پینها. اگه یادتون باشه می گفتیم مثلا وقتی داریم داده یه سوئیچ رو می خونیم از پین دیجیتال آردوینو به عنوان ورودی استفاده می کنیم و وقتی که قراره مثلا یه موتور رو روشن کنیم از پین دیجیتال آردوینو به عنوان خروجی استفاده می کردیم. دقیقا همین قانون در مورد آنالوگ ها هم وجود داره. وقتی یه سنسور آنالوگ داریم که می خوایم داده اون رو بخونیم زمانی که اون سنسور رو به پین آنالوگ آردوینو وصلش می کنیم اون پین رو به عنوان ورودی در نظر می گیریم و زمانی که قراره به یه دستگاه انالوگ فرمان بدیم پین آنالوگ به صورت خروجی تعریف میشه.
اما:
این وسط یه فرق خیلی خیلی بزرگ وجود داره. میکروکنترلر ما که وظیفش پردازش داده هاست دیجیتاله .چه داده از بیرون وارد میکروکنترلر بشه چه خود میکروکنترلر فرمان بده نوع سیگنال های دریافتی و تولیدی باید از جنس دیجیتال باشه ( یعنی 0 و 1 باشه) . هر نوع داده دیگه ای خارج از این تایپ داده برای میکروکنترلر قابل پردازش نیست. تو آموزش های قبلی چه وقتی سوئیچ وصل کردیم به آردوینوچه وقتی موتور یا RGB راه انداختیم جنس داده های رد و بدلی 0 و 1 بود. سوئیچ 0 و 1 داده می داد و به موتور و LED هم 0 و 1 داده می دادیم ( اگه یادتون باشه همیشه سر و کله HIGH و LOW تو کد نویسی مون پیدا می شد.)

اما وقتی از آنالوگ حرف میزنیم دیگه خبری از داده مطلق 0 و1 نیست بلکه با یه طیف پیوسته از اعداد سر و کار داریم. طیف پیوسته ای که میکروکنترلر به هیچ عنوان نمیتونه اون رو پردازش کنه چون زبونش رو نمیفهمه. بنابراین این وسط باید به واسط هایی داشته باشیم که آنالوگ رو بکنن دیجیتال (چون زبون قابل فهم برای میکروکنترلر دیجیتال هست) و در صورت نیاز دیجیتال رو بکنن آنالوگ.

مبدل سیگنال‌های آنالوگ به دیجیتال :
اصطلاحا به این مبدل ها ADC میگن که مخفف Analog to Digital Converter هست. وکارکردش  به طور خلاصه اینه که یه سیگنال آنالوگ دریافت میکنن و طی یه پروسه ای اون رو به سیگنال دیجیتال تبدیل می کنن:
ADC_Symbol

بنابراین ما اگه یه سنسور آنالوگ داشته باشیم باید خروجی سنسور آنالوگمون رو بدیم به مبدل های ADC و بعد خروجی مبدل رو که از جنس دیجیتاله بدیم به میکروکنترلرمون و پردازشش کنیم. اینجا یه آموزش کامل در مورد ADC ها گذاشته. شما اگه یه کم در مورد ADC ها تحقیق کنید یه پارامتر خیلی مهم در مورد این مبدل ها تعداد بیت خروجی اونهاست. تو عالم داده های دیجیتال وقتی میگن یه داده  مثلا 8 بیتیه (طبق قانون احتمال و به دلیل 0 و 1 بودن داده ها ) از 0 تا 255 می تونه تو این داده قرار بگیره (255 معادل 11111111 باینری هست ). حالا وقتی میگیم یه مبدل ADC مثلا 10 بیتیه یعنی از 0 تا عدد 1024 می تونه به عنوان خروجی این مبدل بوجود بیاد. دقیق تر بگیم یعنی این که سمت ورودی این مبدل یه ولتاژ بین 0 تا 5 ولت اعمال میشه (ولتاژ پیوسته :یعنی می تونه مثلا 4.2 ولت باشه ) بعد تو خروجی ADC محاسبه میشه که این ولتاژ معادل با چه عددی هست در صورتی که ADC ده بیتی باشه میشه یه عدد بین 0 تا 1023، در صورتی که ADC هشت بیتی باشه میشه یه عدد بین 0 تا 255. کاملا واضحه دیگه، هرچی بیت های خروجی ADC بیشتر باشه دقت این تبدیل بالاتر میره .چرا میگم منطقیه ؟ ورودی ADC ما (چه خروجی 8 بیت باشه  چه 10 بیت) 0 تا 5 ولته. در صورتی که 8 بیتی باشیم هر 19.6mV در ورودی 1واحد در خروجی خواهد بود ( 5/255= 19.6mV) اما در صورتی که خروجی ADC ده بیتی باشد هر 4.9mV در ورودی 1واحد در خروجی خواهد بود (5/1024= 4.9mV).

حالا یه ترس بوجود میاد: اگه بخوایم داده سنسورهای آنالوگ رو (که سنسورهای خیلی زیادی در مجموعه سنسورهای آنالوگ قرار میگیرن ) بخونیم باید بین آردوینو و سنسورمون یه ADC طراحی کنیم و بزاریم؟ جواب منفیه.
بحث ما عموما روی UNO می چرخه بنابراین فقط در مورد UNO حرف میزنم. برد آردوینو UNO شش تا پایه آنالوگ ورودی داره (دقت کنید ورودی ). به تعداد همین 6 تا پایه آنالوگ ، 6 تا کانال ADC ده بیتی هم داره. یعنی شما هیچ احتیاجی به طراحی و قرار دادن ADC ندارید خودش همه کارها رو کرده یعنی آماده و حاضره. ادامه بحث رو روی همین موضوع ادامه خواهیم داد.

مبدل سیگنال‌های دیجیتال به آنالوگ :
به این نوع مبدل ها اصطلاحا DAC میگن که مخفف Digital to Analog Convertor هست و به طور ساده بخوام بگم یه سیگنال دیجیتال به عنوان ورودی میگیره و در خروجی یه سیگنال آنالوگ میده. این مبدل در مواردی کاربرد داره که دستگاه محرک ما (دستگاهی که از ما فرمان میگیره تا یه کاری بکنه ) ورودی آنالوگ قبول کنه. در چنین مواردی بعد از این که تو میکروکنترلر پردازش ها انجام شد با یه تبدیل DAC سیگنال رو به آنالوگ تبدیل میکنن و به دستگاه محرک میدن.

ما تو دو پاراگراف قبل گفتیم آردوینو 6 تا پایه آنالوگ داره . خب بیاین درمورد دو تا ایده حرف بزنیم که عین دیجیتال ها باهاشون برخورد کنیم یعنی وقتی خواستیم به سنسور وصل کنیم ورودیشون کنیم و وقتی خواستیم به دستگاه محرک وصل کنیم خروجیشون کنیم. حتی شاید یه عده حرف گروه اول رو با با این استدلال غلط تایید کنن که : اره دیگه تو همون مسیری که سیگنال از آنالوگ به دیجیتال تبدیل میشه برعکس از دیجیتال هم به آنالوگ تبدیل بشه و بنابراین 6 تا پین آنالوگ آردوینو هم ورودی هستن هم خروجی.
اما این دو گروه به شدت اشتباه می کنن. مدار های DAC و ADC کاملا کاملا کاملا با هم متفاوت هستن و تبدیل دو طرفه به حساب نمیان. اون 6 تا پین آنالوگ آردوینو هم که قبلا در موردشون حرف زدیم ADC دارن. بنابراین نمیتونن به عنوان خروجی استفاده بشن و تنها و تنها می تونیم از اونها به عنوان ورودی استفاده کنیم. هیچ کدوم از بردهای آردوینو پین آنالوگ خروجی ندارن به جز آردوینو DUE و M0-PRO . این در صورتیه که تمام آردوینو ها بدون استثنا پین آنالوگ ورودی دارن.

خب تا اینجای داستان فقط در مورد فلسفه آنالوگ در آردوینو حرف زدیم. از این جای آموزش میریم سراغ پروژمون یعنی راه اندازی پتانسیومتر.

موارد لازم:
آردوینو از هر نوعی
پتانسیومتر
سیم برد بوردی نری به مادگی

خب حالا مطابق عکس زیر مدار رو ببندید.
tumblr_mc96ar3Q981qanj9i

دقت کنید به پایه آنالوگ شماره 2 وصلش کردیم.
خب حالا این کدرو آپلود کنید:
2016-01-20_13-07-30
قسمت هدر که معرفی پین انالوگ هست که اگه دقت کنید نوشته شده A2. این A نمایشگر اینه که داریم از پین آنالوگ استفاده می کنیم. تو تابع setup این پین به عنوان ورودی و ارتباط سریال با نرخ 9600 کانفیگ شده.
تو تابع loop خط اول با دستور analogRead مقدار پین آنالوگ خونده میشه. عملا مقداری که توی متغیر sensorValue ریخته میشه خروجی ADC هست. یعنی پین وسط پتانسیومتر که متصل شده به پین آنالوگ شماره 2 آردوینو، طبق قانون مداری تقسیم ولتاژ ، یه ولتاژ بین 0 تا 5 ولت رو روی پین شماره 2 می ندازه. این ولتاژ میشه ورودی ADC متصل به پین شماره 2 آردوینو. از اون طرف خروجی این ADC به صورت یک عدد بین 0 تا 1023 (به علت 10 بیتی بودن ADC ) توی متغیر sensorValue ریخته میشه. با دستور پرینت هم این مقدار توی کنسول سریال چاپ میشه. خط آخر هم که دستور delay هست فرمان میده با سر فاصله های یک ثانیه این روند تکرار بشه.

پایان.

جلسه سیزدهم : استفاده از کتابخانه 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 که اگه کسی خواست بدونه اینا چیکار می کنن می تونه تو انجمن سوالش رو مطرح کنه.