آموزش آردوینو نمایشگر LCD پروژه های آردوینو

آموزش برنامه نویسی ساخت منو در آردوینو با نمایشگر LCD Arduino – بخش اول

آموزش منو در آردوینو arduino
نوشته شده توسط علیرضا قربانی

طراحی واسط کاربری حرفه‌ای در نرم اقزار‌ها از نقات قوت یک سیستم می‌باشد.در این پست به آموزش ساخت منو در آردوینو می‌پردازیم. منو ساختاری سلسله مراتبی و تودرتوست که برای طبقه بندی و دسته بندی منطقی فرامین و یا اطلاعات در نرم افزارهای گوناگون استفاده می شود تا افراد بتوانند آنچه را می خواهند به راحتی پیدا کنند. معمولا در کار روزمره با نرم افزارهای مختلف با انواع منو سروکار داشته ایم . منوی Start ویندوز نمونه ای آشناست , منویی آبشاری که با حرکت  اشاره گر روی هر کدام از گزینه هایش , در صورت وجود , مجموعه ای از گزینه های زیر مجموعه را نمایش میدهد و بدینصورت افراد می توانند گزینه نهایی مورد نظر خود را به راحتی پیدا کنند.در ادامه آموزش با مرجع تخصصی آردوینو ، دیجی اسپارک همراه باشید.

شیوه‌های مختلفی به منظور ساخت منو وجود دارد ولی از آنجایی که آردوینو پلتفرمی دارای کتابخانه‌های فراوانی می‌باشد ، به جای برنامه ‌نویسی‌های پیچیده  از کتابخانه MenuBackend استفاده می‌کنیم که لینک دانلود آن در قسمت زیر قرار داده  شده است.پس از دانلود کتابخانه ، آن را به نرم افزار آردوینو اضافه نمایید. دانلود کتابخانهMenuBackend در این آموزش از کتابخانه دیبانسینگ و همچنین LCD کاراکتری استفاده شده است که قبل از مطالعه این پست پیشنهاد می‌کنیم دو پست زیر را مطالعه کنید.

آموزش 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 رو با menuChange عوض کردن جاشونو ولی تغییری نکرد؟
        ؟؟؟؟!!!

        • سلام
          دقت کنید این تابع در کتابخانه ها تعریف شده است. باید کتابخانه را نصب کنید و در صورت نیاز و در دسترس بودن آپدیت جدید، کتابخانه را به روز رسانی کنید.
          نتیجه را از همین طریق اعلام نمایید.

  • با سلام
    لینک کتابخانه و تصاویر هیچکدام سالم نیستند .
    در ضمن این صفحه بصورت کامل دارای مشکل است زیرا بخشی از متون در زیر منو سمت راست سایت رفته و قابل مشاهده نیستند .

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

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

  • سلام ممنون از سایت خوبتون برای رفع تین ارور چیکار کنم؟؟؟؟؟

    exit status 1
    ‘menuUse’ was not declared in this scope

    • سلام
      این ارور مربوط به کلید واژه menue use است که در متن کد استفاده شده است. به این معنی که این عبارت یا تعریف نشده است و یا در صورت تعریف شدن به درستی تایپ نشده است. کد را مجددا بررسی و نتیجه را اعلام کنید.

  • سلام
    منم همین error رو دارم menuUse’ was not declared in this scope
    حتی کتابخانه رو جدا دانلود کردم و از example خود کتابخانه استفاده کردم ولی بازم همین error رو میده
    لطفا راهنمایی کنید

    • سلام
      دقت کنید این تابع در کتابخانه تعریف شده است. باید کتابخانه ها به ترتیب نصب کرده و در صورت نیاز و در دسترس بودن آپدیت جدید، کتابخانه را به روز رسانی کنید.

  • یک سئوال داشتم خیلی سخته یکبار برنامه کامل رو کامپایل کنید و رفع خطا؟ چون هم غلط املایی داره و هم بنظر میرسه چند جاش جابجا هستو کسی هم نتونسته ازش استفاده کنید پیشنهادمن اینه یا برش دارید و یا اصلاحش کنید اینطوری بنفع همه هست

    • با سلام
      روش های مختلفی جهت اجرای پروژه وجود دارد، در صورت استفاده از درایور مناسب میتوانید اجرا نمایید.

  • سلام آیا از این می شود برای ال سی دی گرافیکی هم استفاده کرد؟
    برنامه ای برای منوی نمایشگر گرافیکی هست آیا؟ممنون

  • 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 به صورت دستی اضافه کنید.