طراحی واسط کاربری حرفهای در نرم اقزارها از نقات قوت یک سیستم میباشد.در این پست به آموزش ساخت منو در آردوینو میپردازیم. منو ساختاری سلسله مراتبی و تودرتوست که برای طبقه بندی و دسته بندی منطقی فرامین و یا اطلاعات در نرم افزارهای گوناگون استفاده می شود تا افراد بتوانند آنچه را می خواهند به راحتی پیدا کنند. معمولا در کار روزمره با نرم افزارهای مختلف با انواع منو سروکار داشته ایم . منوی Start ویندوز نمونه ای آشناست , منویی آبشاری که با حرکت اشاره گر روی هر کدام از گزینه هایش , در صورت وجود , مجموعه ای از گزینه های زیر مجموعه را نمایش میدهد و بدینصورت افراد می توانند گزینه نهایی مورد نظر خود را به راحتی پیدا کنند.در ادامه آموزش با مرجع تخصصی آردوینو ، دیجی اسپارک همراه باشید.
شیوههای مختلفی به منظور ساخت منو وجود دارد ولی از آنجایی که آردوینو پلتفرمی دارای کتابخانههای فراوانی میباشد ، به جای برنامه نویسیهای پیچیده از کتابخانه MenuBackend استفاده میکنیم که لینک دانلود آن در قسمت زیر قرار داده شده است.پس از دانلود کتابخانه ، آن را به نرم افزار آردوینو اضافه نمایید. دانلود کتابخانهMenuBackend در این آموزش از کتابخانه دیبانسینگ و همچنین LCD کاراکتری استفاده شده است که قبل از مطالعه این پست پیشنهاد میکنیم دو پست زیر را مطالعه کنید.
آموزش دیبانسیتگ یا نویزگیری کلید در آردوینو
روش اجرای پروژه
پیش از انجام هر کاری ابتدا باید یک ساختار کلی از منویی که مدنظرمان میباشد ترسیم کنیم. طرحی از منویی که در ذهن داریم. برای منوی خود باید کلیدهایی در نظر بگیریم که هر کدام از آنها عملیات خاصی را انجام بدهد. ما در منوی خود از چهار کلید استفاده کردهایم که به ترتیب زیر میباشند:
- ۱ عدد کلید برای رفتن به سمت راست منو(جابه جایی در بین آیتمهای منو)
- ۱ عدد کلید برای رفتن به سمت چپ منو (جابهجایی در بین آیتمهای منو)
- ۱ عدد کلید به منظور وارد شدن به منو ( عملیات Enter)
- ۱ عدد کلید به منظور رفتن به ابتدای منو ( عملیات)
کدهای پروژه منو با آردوینو
ابتدا کدهای زیر را در آردوینو خود آپلود کنید و نتیچه را مشاهده کنید. اگر مراحل را به درستی انجام داده باید مشاهده میکنید که در صورت فشردن کلید ها منوی شما مطابق ساختار زیر عمل میکند:
پس از فراخوانی کتابخانهها و تنظیمات آنها ابتدا باید از کلاس MenuBackend یک آبجکت بسازیم(منظور از آبجکت همان منو میباشد) همانند زیر:
MenuBackend menu = MenuBackend (menuUse, menuChange);
menuChange : تابعی است که هنگامی که جابهجایی بین گزینههای منو به صورت خودکار فراخوانی میشود( این تابع را باید خودمان بعد از loop برنامه بنویسیم.
menuUse : تابعی است که هنگامی که منوی را مورد استفاده قرار میدهیم به صورت خودکار فراخوانی میشود ( ابن تابع را نیز باید در پایان کدها بنویسیم)
پس باید اینگونه عمل کنیم:
#include <MenuBackend.h> MenuBackend menu = MenuBackend (menuUse, menuChange); void setup () { } void loop () { } void menuChange (MenuChangeEvent changed) { //بعد از جابه حایی بین گزینه های منو کد های این قسمت به صورت خودکار اجرا میشوند } void menuUse (MenuUseEvent used) { //بعد از استفاه از یک منو ، کد های موجود در این قسمت به صورت خودکار فراخوانی مشود }
در مرحلهی بعدی باید ایتمهایی که در منوی ما به کار برده میشود را تعریف کنیم.بری تعریف ایتمها مطایق دستور العمل زیر عمل میکنیم.
MenuItem menuItem = MenuItem ("Name of menuItem");
پس طبق ساختار فوق ، ایتمهای منو را طبق قطعه کد زیر تعریف میکنیم:
#include <MenuBackend.h> MenuBackend menu = MenuBackend (menuUse, menuChange); MenuItem menu1Item1 = MenuItem ("Item1"); MenuItem menuItem1SubItem1 = MenuItem ("Item1SubItem1"); MenuItem menuItem1SubItem2 = MenuItem ("Item1SubItem2"); MenuItem menu1Item2 = MenuItem ("Item2"); MenuItem menuItem2SubItem1 = MenuItem ("Item2SubItem1"); MenuItem menuItem2SubItem2 = MenuItem ("Item2SubItem2"); MenuItem menuItem3SubItem3 = MenuItem ("Item2SubItem3"); MenuItem menu1Item3 = MenuItem ("Item3"); void setup () { } void loop () { } void menuChange (MenuChangeEvent changed) { //بعد از جابه حایی بین گزینه های منو کد های این قسمت به صورت خودکار اجرا میشوند } void menuUse (MenuUseEvent used) { //بعد از استفاه از یک منو ، کد های موجود در این قسمت به صورت خودکار فراخوانی مشود } MenuItem menuItem = MenuItem ("Name of menuItem");
معرفی چند تابع ایجاد منو در آردوینو
getRoot ()
به وسیله این تابع به ابتدای منوی ساخته شده میرویم.
add(menu Name)
به وسیله این تابع میتوان یک آیتم را به آیتم دیگر اضافع نمود ( یعنی میتوان یک آیتم را به عنوان زیرشاخه یک آیتم دیگر قرار داد یا به عبارت دیگر یک منو را به منویی دیگر اضافه نمود). به عنوان مثال در قطعه کد زیر ، آیتم subMenuItem1 را به عنوان زیر شاخه آیتم menuItem1 اضافه میکنیم:
menuItem1.add(subMenuItem1);
آیتمها را در setup برنامه به یکدیگر اضافه میکنیم.
مرحله اول
menu.getRoot ().add (menu1Item1);
مرحله دوم
menu1Item1.addRight (menu1Item2).addRight (menu1Item3);
مرحله سوم
menu1Item1.add (menuItem1SubItem1).addRight (menuItem1SubItem2);
و در نهایت
menu1Item2.add (menuItem2SubItem1).addRight (menuItem2SubItem2).addRight (menuItem3SubItem3);
پس کدهای برنامه تا این قسمت به صورت زیر میشود:
محدودیت در دسترسی کامل به این مجموعه آموزش
دسترسی کامل به آموزش برای اعضای دیجی اسپارک امکان پذیر است. بخش اصلی آموزش شامل سورس کدهای توسعه داده شده توسط مهندسهای دیجی اسپارک است. به همین دلیل این آموزش خاص و یکتاست. برای استفاده از آن بایستی عضویت تهیه کنید. تبادل نظر با کاربران و پرسش سوال رایگان است و میتوانید از بخش نظرات همین آموزش اقدام کنید. |
هم اکنون باید وضعیت LOW شدن هر یک از ۴ عدد تاچ سوئیچ را بررسی کرده و در صورت فشرده شدن هر کدام ، شمارهی پین آن را در متغیر lastButtonPushed میریزیم. کدهای ما به صورت زیر میشود:
#include <Bounce2.h> #include <MenuBackend.h> const int buttonPinLeft = 8; // pin for the Up button const int buttonPinRight = 9; // pin for the Down button const int buttonPinEsc = 10; // pin for the Esc button const int buttonPinEnter = 11; // pin for the Enter button int lastButtonPushed = 0; //ایجاد یک آبجکت برای هر کلید از کلاس Bounce Bounce esc = Bounce (); Bounce enter = Bounce (); Bounce left = Bounce (); Bounce right = Bounce (); //ایجاد منو MenuBackend menu = MenuBackend (menuUse, menuChange); //اایجاد آیتم های منو MenuItem menu1Item1 = MenuItem ("Item1"); MenuItem menuItem1SubItem1 = MenuItem ("Item1SubItem1"); MenuItem menuItem1SubItem2 = MenuItem ("Item1SubItem2"); MenuItem menu1Item2 = MenuItem ("Item2"); MenuItem menuItem2SubItem1 = MenuItem ("Item2SubItem1"); MenuItem menuItem2SubItem2 = MenuItem ("Item2SubItem2"); MenuItem menuItem3SubItem3 = MenuItem ("Item2SubItem3"); MenuItem menu1Item3 = MenuItem ("Item3"); void setup () { //////////////////////////////////////////////////تنظیم دیبانسینگ کلیدها pinMode (buttonPinEsc, INPUT_PULLUP); pinMode (buttonPinEnter, INPUT_PULLUP); pinMode (buttonPinLeft, INPUT_PULLUP); pinMode (buttonPinRight, INPUT_PULLUP); esc.attach (buttonPinEsc); enter.attach (buttonPinEnter); right.attach (buttonPinRight); left.attach (buttonPinLeft); esc.interval (50); enter.interval (50); right.interval (50); left.interval (50); //////////////////////////////////////////////////// menu.getRoot ().add (menu1Item1); menu1Item1.addRight (menu1Item2).addRight (menu1Item3); menu1Item1.add (menuItem1SubItem1).addRight (menuItem1SubItem2); menu1Item2.add (menuItem2SubItem1).addRight (menuItem2SubItem2).addRight (menuItem3SubItem3); menu.toRoot (); } void loop () { } void menuUse (MenuUseEvent used) { } void menuChange (MenuChangeEvent changed) { } void readBuutton () { enter.update (); right.update (); left.update (); esc.update (); if ( enter.fell () ) { lastButtonPushed = buttonPinEnter; } else if ( esc.fell () ) { lastButtonPushed = buttonPinEsc; } else if ( right.fell () ) { lastButtonPushed = buttonPinRight; } else if ( left.fell () ) { lastButtonPushed = buttonPinLeft; } else{ lastButtonPushed = 0; } }
اکنون باید تابعی بنویسیم که بعد از هر بار فشرده شدن کلیدها وضعیت بین منوها تغییر کند. تابع مورد نظر ما به صورت زیر میباشد:
void navigateMenus () { //ایتمی که بر روی آن قرار داریم را بدست می آوریم MenuItem currentMenu = menu.getCurrent (); switch ( lastButtonPushed ){ case buttonPinEnter: if ( !(currentMenu.moveDown ()) ){ //if the current menu has a child and has been pressed enter then menu navigate to item below menu.use (); } else{ //otherwise, if menu has no child and has been pressed enter the current menu is used menu.moveDown (); } break; case buttonPinEsc: menu.toRoot (); //به ابتدای منو باز می گردیم break; case buttonPinRight: //به ایتم سمت راست حرکت می کنیم menu.moveRight (); break; case buttonPinLeft: //به آیتم سمت چپ حرکت میکنیم menu.moveLeft (); break; } lastButtonPushed = 0; }
اکنون برای نمایش دادن نام هر یک از ITEM ها در LCD هنگام جابهجایی در میان آیتمها تابع menuChange را باید طبق کدهای زیر توسعه دهیم:
void menuChange (MenuChangeEvent changed) { lcd.clear (); MenuItem newMenuItem = changed.to; //آیتمی را که بر روی آن قرار داریم بدست می آوریم if ( newMenuItem.getName () == menu.getRoot () ){ lcd.print ("Main Menu "); } else if ( newMenuItem.getName () == "Item1" ){ lcd.print ("Item1 "); } else if ( newMenuItem.getName () == "Item1SubItem1" ){ lcd.print ("Item1SubItem1"); } else if ( newMenuItem.getName () == "Item1SubItem2" ){ lcd.print ("Item1SubItem2 "); } else if ( newMenuItem.getName () == "Item2" ){ lcd.print ("Item2 "); } else if ( newMenuItem.getName () == "Item2SubItem1" ){ lcd.print ("Item2SubItem1 "); } else if ( newMenuItem.getName () == "Item2SubItem2" ){ lcd.print ("Item2SubItem2 "); } else if ( newMenuItem.getName () == "Item2SubItem3" ){ lcd.print ("Item2SubItem3 "); } else if ( newMenuItem.getName () == "Item3" ){ lcd.print ("Item3 "); } }
و همچنین برای نمایش دادن نام هر یک از زیرمنوها که مورد استفاه (use) قرار میدهیم تابع menuUse را طبق کدهای زیر توسعه میدهیم:
void menuUse (MenuUseEvent used) { lcd.clear (); lcd.print ("You used "); lcd.setCursor (1, 1); lcd.print (used.item.getName ()); menuUs = used.item.getName (); }
و در پایان ؛ کدهای نهایی پروژه به صورت زیر میباشد:
محدودیت در دسترسی کامل به این مجموعه آموزش
دسترسی کامل به آموزش برای اعضای دیجی اسپارک امکان پذیر است. بخش اصلی آموزش شامل سورس کدهای توسعه داده شده توسط مهندسهای دیجی اسپارک است. به همین دلیل این آموزش خاص و یکتاست. برای استفاده از آن بایستی عضویت تهیه کنید. تبادل نظر با کاربران و پرسش سوال رایگان است و میتوانید از بخش نظرات همین آموزش اقدام کنید. |
وسایل مورد نیاز
آردوینو Uno
میکروسوئیچ بزرگ
LCD کاراکتری ۲*۱۶
برد بورد
آقای قربانی سلام
آقا واقعا دمت گرم، خیلی مفصل توضیح دادی، من برم برای تست روی آردوینو بعد میام سوالامو میپرسم.
چاکریم
سلام
در خدممتون هستم
سلام آقای قربانی
بابت مطالبتون کمال تشکر رادارم.متاسفانه هیج کدام از فایلهای کتابخانه قابل دانلود نبوده ومینویسد فایل مذکور پیدا نشد.
سلام
ممنون از شما
در صورتی که پست های خاصی مد نظر شماست لطفا نام آن ها را ذکر کنید
با تشکر از توجه شما دوست عزیز
با سلام
با تعویض مرورگر موفق به دانلود اکثر کتابخانه ها شدم ولی متاسفانه کماکان امکان دانلود کتابخانه OLED را ندارم.
با تشکر از زحمات شما ومطالب بسیار عالی سایت
سلام
ارتباطی ب مرور گر نداره – کتابخانه ها را مجددا آپلود کردم – کتابخانه مرتبط به OLED نیز قرار گرفت و میتونین دانلود کنید
موفق و موید باشید
سلام
این آموزش ها بسیار عالی هستند از زحماتتان متشکرم
سئوالی داشتم
آیا میتوان به جای این که این همه سیم و کلید برای استفاده از منوها گذاشته میشه و به جای ال سی دی کاراکتری از شیلد ال سی دی لمسی که در این لینک
https://daneshjookit.com/1737-%D9%85%D8%A7%DA%98%D9%88%D9%84-lcd-24-%D8%B4%DB%8C%D9%84%D8%AF-uno.html?search_query=lcd&results=16
آورده شده استفاده کرد . و به جای کلیدهای فشاری از امکان تاچ ال سی دی استفاده کرد ؟
یعنی با یک تیر تقریبا ۳ نشون زد
۱: استفاده از ال سی دی تاچ به جای کاراکتری که از کیفیت بهتری برخورداره
۲: استفاده از تاچ ال سی دی برای منوها به جای کلید
۳: استفاده از امکان درگاه اس دی کارت نصب شده روی ال سی دی تاچ . به جای شیلد sd card
????????
آیا میتوان این روش را استفاده کرد ؟
سلام
خواهش میکنم
بله تمامی این کار ها را می توان توسط این شیلد انجام داد
با سلام و تشکر از زحمات شما.
در این برنامه من با مشکل روبرو شدم که نمیدونم چطور حلش کنم. موقع verify خطای زیر رو ب من میده.
MenuBackend_sample:101: error: ‘menuUseEvent’ was not declared in this scope
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent); // konstruktor
^
MenuBackend_sample:101: error: ‘menuChangeEvent’ was not declared in this scope
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent); // konstruktor
exit status 1
‘menuUseEvent’ was not declared in this scope
اگر راهنمایی کنید ممنون میشم.
سلام به دوستان .
ایراد کار من با جا بجا کردن تابع menuUse حل شد.
امیدوارم مفید باشه.
من هم همین مشکل رو دارم،منظورتون از جابجا کردن menuUse چی هستش؟
من menuUse رو با menuChange عوض کردن جاشونو ولی تغییری نکرد؟
؟؟؟؟!!!
منم همین مشکل رو دارم … منظورتون از جا به جا کردن تابع menoUse چیه؟
سلام
دقت کنید این تابع در کتابخانه ها تعریف شده است. باید کتابخانه را نصب کنید و در صورت نیاز و در دسترس بودن آپدیت جدید، کتابخانه را به روز رسانی کنید.
نتیجه را از همین طریق اعلام نمایید.
من هم همین مشکل رو دارم
با سلام
لینک کتابخانه و تصاویر هیچکدام سالم نیستند .
در ضمن این صفحه بصورت کامل دارای مشکل است زیرا بخشی از متون در زیر منو سمت راست سایت رفته و قابل مشاهده نیستند .
برای رفع این مشکل از بزرگ نمای خود پنچره استفاده کنید درست میشه
سلام.
خسته نباشد اقای قربانی .
خیلی خوب مطالب توضیح میدید واقعان دمتون گرم.
ببخشید ی سوال شماتیک مدارهای اردوینو از کجا باید دانلود کنم؟؟
سلام.
ببخشید ی سوال شماتیک مدارهای اردوینو از کجا باید دانلود کنم؟؟
سلام
من کتابخانه مربوط به منو رو دانلود کردم و به نرم افزار اضافه کردم تمام کدها رو هم که شما قرار داده بودین رو هم همینطور ولی موقع آپلود متاسفانه ارور میگیره ، میشه یه راهنمای بفرماید مراحل کار رو من طبق مراحلی که توضیح داده بودین پیش رفتم ولی نشد
تصاویر پست نمایش داده نمیشن. لطفا اصلاح فرمایید.
با تشکر
سلام ممنون از سایت خوبتون برای رفع تین ارور چیکار کنم؟؟؟؟؟
exit status 1
‘menuUse’ was not declared in this scope
سلام
این ارور مربوط به کلید واژه menue use است که در متن کد استفاده شده است. به این معنی که این عبارت یا تعریف نشده است و یا در صورت تعریف شدن به درستی تایپ نشده است. کد را مجددا بررسی و نتیجه را اعلام کنید.
خب این مشکل چه طور باید رفع بشه ؟ آخه واسه منم همین پیغام خطا ظاهر میشه
سلام
دقت کنید این تابع در کتابخانه تعریف شده است. باید کتابخانه را نصب کنید و در صورت نیاز و در دسترس بودن آپدیت جدید، کتابخانه را به روز رسانی کنید.
حداقل اگر کدی رو کپی و دزدی میکنید صحیح اینکار رو انجام بدین همه فکر کنن کارخودتونه!!!
با سلام و تشکر از شما
کاربر گرامی لطفا اگر ایرادی هست یا انتقادی دارید. به صورت شفاف و کامل بیان بفرمایید تا امکان رفع آن وجود داشته باشد.
سلام مجدد هر کاری کردم نشد و باید بگم از شیلد lcd استفاده می کنم و برای تعریف کلیدهاش از #include استفاده می کنم از این نیست؟؟
دقت کنید تابع include برای فراخوانی کتابخانه میباشد. جهت فراخوانی ال سی دی به آموزش راه اندازی سه مدل ال سی دی کاراکتری مراجعه کنید.
سلام
منم همین error رو دارم menuUse’ was not declared in this scope
حتی کتابخانه رو جدا دانلود کردم و از example خود کتابخانه استفاده کردم ولی بازم همین error رو میده
لطفا راهنمایی کنید
سلام
دقت کنید این تابع در کتابخانه تعریف شده است. باید کتابخانه ها به ترتیب نصب کرده و در صورت نیاز و در دسترس بودن آپدیت جدید، کتابخانه را به روز رسانی کنید.
یک سئوال داشتم خیلی سخته یکبار برنامه کامل رو کامپایل کنید و رفع خطا؟ چون هم غلط املایی داره و هم بنظر میرسه چند جاش جابجا هستو کسی هم نتونسته ازش استفاده کنید پیشنهادمن اینه یا برش دارید و یا اصلاحش کنید اینطوری بنفع همه هست
با سلام و تشکر از شما
درست میفرمایید برخی از خطوط کدنویسی شده دارای تگهای HTML هستند. موارد رفع شدند.
سلام میشه بجای این همه سیم کشی از پروتکل i2c استفاده کرد
با سلام
روش های مختلفی جهت اجرای پروژه وجود دارد، در صورت استفاده از درایور مناسب میتوانید اجرا نمایید.
سلام آیا از این می شود برای ال سی دی گرافیکی هم استفاده کرد؟
برنامه ای برای منوی نمایشگر گرافیکی هست آیا؟ممنون
با سلام
با این آموزش خیر، برای LCD گرافیکی بایستی بخش GUI طراحی شود.
menuUs = used.item.getName (); با سلام این قسمت چه کاری انجام میده چون ارور داره روی این؟
exit status 1
‘menuUs’ was not declared in this scope
با سلام
عبارت menueus تعریف نشده است. ممکن است کتابخانه های برنامه نیاز به آپدیت داشته باشد.
سلام برنامه تو پروتئوس برای دستورات منو ایراد میده کتابخانه رو هم دانلود کردم ولی جواب نمیده
با سلام
کاربر گرامی این مورد در پروتئوس تست و بررسی نشده است.
سلام من میخوام یک منو برای دستگاه جوجه کشی درست کنم که مثلا وقتی ایتم مرغ رو انتخاب کردم دما روی ۳۷.۷ برای تنظیم بشه و وقتی اردک رو انخاب کردم ۳۷.۵ بشه
ایا با این منو میشه؟
اگر میشه نحوه کار هم توضیح بدید که چجوری وقتی ایتم ها رو نوشتم بشه این مقادیر نیز انتخاب بشه
با سلام
بله اینکار امکان پذیر است. توسط این آموزش میتوانید منو را ایجاد کنید ولی اقدامات بعدی نیازمند کدنویسی است. که پیچیدگی دارد و از بخش نظرات نمیتوان به آن رسیدگی کرد. در صورت تمایل میتوانید درخواستتان را از طریق پرتال پشتیبانی ارسال کنید.
سلام وقت بخیر
برنامه مشکل داره
C:\Users\ICI\Desktop\menu\menu.ino: In function ‘void menuChange(MenuChangeEvent)’:
menu:113:31: error: no match for ‘operator==’ (operand types are ‘const char*’ and ‘MenuItem’)
if ( newMenuItem.getName () == menu.getRoot () ){
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
exit status 1
‘menuUse’ was not declared in this scope
با سلام
برنامه مشکلی ندارد. پس از گذشت چند سال کتابخانه ها آپدیت شده است.
سلام کتابخانه منو اصلا دانلود نمیشه .حتی از سایت اردوینو
با سلام
کتابخانه را بایستی از مسیر INCUDE LIBRARY نصب کنید و یا از گیت هاب دانلود و از مسیر DOCUMENT/ARDUINO/LIBRARY به صورت دستی اضافه کنید.
سلام با توجه به اینکه من اشتراک گرفتم کد کامل این پروژه را نمایش نمی دهد.چرا؟
با سلام
کش مرورگر را یکبار پاک کنید.