سلام
در این پروژه قصد داریم با استفاده از آردوینو و دو تا دونه مقاومت خشک و خالی یه ولت متر دیجیتال بسازیم.
مسلما همگی می دونید ولت متر چیه دیگه : یه دستگاهی هست که با کمک اون می تونید ولتاژهای قسمت های مختلف یک مدار رو اندازه گیری کنید (به این شرط که با اون مدار زمین مشترک (کامان گراند common ground ) بشید و یا در حالت کلی اختلاف ولتاژ دو نقطه از مدار رو بهتون میده.
خب یک راست میریم سراغ سخت افزار مورد نیاز. مواد لازم :
آردوینو از هر مدلی
یه دونه مقاومت 10 کیلو اهم
یه دونه مقاومت 100 کیلو اهم
یه دونه برد بورد کوچیک
حالا مثل عکس زیر مدار رو ببندید:
خیلی خیلی خیلی حواستون جمع باشه که مقاومت ها را جا به جا نزارید.
طبق قوانین موجود در مدار و تقسیم ولتاژ این رابطه بین ورودی و خروجی وجود داره :
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 ولت می شد. حالا قابل درک شد براتون ؟ حالا شما اگه می خواید این محدوده اندازه گیری رو بزرگ تر یا کوچیک تر کنید می تونید با بازی با این مقاومت ها به هدفتون برسید فقط باید به یه نکته توجه داشته باشید که هر چی دامنه ولتاژ ورودی قابل اندازه گیری بالاتر بره دقت اندازه گیری پایین تر میاد و حساسیت اندازه گیری نسبت به تغییرات ولتاژ کمتر میشه.
خب مدار رو بستید ؟ حالا بریم سراغ کد نویسی .
این کد رو آپلود کنید تا در مورد قسمت های مختلفش حرف بزنیم:
قسمت هدر برنامه میاد مقدار مقاومت های R1 و R2 رو به عنوان متغیر تعریف می کنه. فایده این کار اینه که اگه کسی خواست رنج اندازه گیری ولتاژش متفاوت باشه و در نتیجه اومد این مقاومت ها رو عوض کرد با همین تغییر ساده بتونه کد رو برای مدار خودش ادیت کنه. توجه کنید که اندازه ها بر حسب اهم وارد میشن یعنی 10 کیلو اهم میشه 10000.
اما تو همین هدر یه متغیر دیگه هم وجود داره به نام Vref. Vref یه مفهوم خیلی مهم در دنیای آنالوگ آردوینو هست که لازمه کامل در موردش توضیح داده بشه.
برای درک بهتر قضیه آردوینوتون رو با کابل USB به کامپیوتر وصل کنید تا روشن بشه. وقتی روشن شد ولتاژ های دو پایه نشون داده شده تو عکس زیر رو با یه ولت متر اندازه بگیرید.
جالبه نه ؟ پایه ای که روش زده 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 پونصد میلی ثانیه هم گذاشته تا روند نمایش دادن یه ذره کند بشه.
خب کد رو آپلود کنید و تو کنسول نتیجه رو ببینید.
پایان جلسه.