فهرست مطالب:

منویی در آردوینو و نحوه استفاده از دکمه ها: 10 مرحله (همراه با تصاویر)
منویی در آردوینو و نحوه استفاده از دکمه ها: 10 مرحله (همراه با تصاویر)

تصویری: منویی در آردوینو و نحوه استفاده از دکمه ها: 10 مرحله (همراه با تصاویر)

تصویری: منویی در آردوینو و نحوه استفاده از دکمه ها: 10 مرحله (همراه با تصاویر)
تصویری: نحوه پروگرام کردن اردوینو با موبایل | How to program Arduino with mobile 2024, نوامبر
Anonim
منویی در آردوینو و نحوه استفاده از دکمه ها
منویی در آردوینو و نحوه استفاده از دکمه ها

در آموزش Arduino 101 من ، نحوه تنظیم محیط خود در Tinkercad آموزش داده می شود. من از Tinkercad استفاده می کنم زیرا یک پلت فرم آنلاین بسیار قدرتمند است که به من امکان می دهد طیف وسیعی از مهارت ها را برای ایجاد مدارها به دانش آموزان نشان دهم. با خیال راحت می توانید تمام آموزش های من را با استفاده از Arduino IDE و Arduino واقعی بسازید!

در این آموزش ، ما قصد داریم با دکمه ها آشنا شویم! لازم است بدانیم:

  • نحوه اتصال آنها به سیم
  • خواندن ارزش آنها
  • انکار کنید ، و چرا مهم است
  • یک برنامه کاربردی (ایجاد منو)

اکثر مردم فکر می کنند عملی ترین کار با یک دکمه روشن و خاموش کردن یک چراغ است. ما ، اینجا نیستیم! ما قصد داریم از برنامه خود برای ایجاد منو و تنظیم برخی گزینه ها در آردوینو استفاده کنیم.

آماده؟ بیایید شروع کنیم!

مرحله 1: برد را تنظیم کنید

برد را راه اندازی کنید
برد را راه اندازی کنید
برد را راه اندازی کنید
برد را راه اندازی کنید

اولین قدم این است که یک Arduino و Breadboard Small را روی ناحیه نمونه سازی قرار دهید. برای مشاهده نحوه سیم کشی ریل های برق ، تصاویر بالا را بررسی کنید.

Breadboard Mini دارای دو ریل قدرت بالا و پایین است. ما اینها را به آردوینو متصل می کنیم تا بتوانیم قدرت بیشتری را برای اجزای دیگر فراهم کنیم. بعداً در این آموزش ما از 3 دکمه استفاده می کنیم بنابراین به قدرت بیشتری نیاز داریم. نکته ای که باید به آن توجه شود این است که در یک تخته کوچک ، ریل های برق از سطح زمین به صورت افقی عبور می کنند. این تفاوت با ستونهای منطقه اصلی نمونه سازی در وسط دارد. اینها به صورت عمودی اجرا می شوند می توانید از هر یک از پین های برق برای تأمین برق هر ستون در ناحیه اصلی در وسط استفاده کنید.

وقتی برق را اضافه می کنید ، از سیم های سیاه و قرمز به ترتیب منفی و مثبت استفاده کنید. سیم هایی را در انتها اضافه کنید که برق را به طرف دیگر برد برسانید. ما از آن طرف استفاده نخواهیم کرد ، اما این تمرین خوبی است.

مرحله 2: دکمه و مقاومت را اضافه کنید

دکمه و مقاومت را اضافه کنید
دکمه و مقاومت را اضافه کنید
دکمه و مقاومت را اضافه کنید
دکمه و مقاومت را اضافه کنید
دکمه و مقاومت را اضافه کنید
دکمه و مقاومت را اضافه کنید

یک دکمه کوچک فشار از سینی قطعات اضافه کنید. باید شبیه تصویر موجود در تصویر باشد. مطمئن شوید که سوئیچ نیست! یک مقاومت نیز اضافه کنید. روی آن کلیک کنید و مقدار آن را روی 10kΩ تنظیم کنید. این به اندازه کافی است که پین را هنگامی که وصل نیست پایین بیاورید ، که بعداً در کد بسیار مهم است.

جزء را در وسط تخته نان قرار دهید. نحوه عملکرد یک دکمه به شرح زیر است:

  • گوشه به گوشه ، دکمه متصل نیست. با فشار دادن دکمه ، مخاطبین بسته می شوند و گوشه ها متصل می شوند.
  • کناره های دکمه به هم متصل شده اند. اگر سیم را به بالا سمت چپ و پایین چپ وصل کنید ، مدار بسته می شود.

به همین دلیل است که ما جزء را در سراسر فضا در وسط قرار می دهیم. این اطمینان می دهد که گوشه ها زیر پین های روی برد متصل نیستند.

مرحله بعدی چند تصویر ارائه می دهد که این نکات را نشان می دهد.

مقاومت را از پین پایین سمت راست روی ستون ها قرار دهید ، بنابراین به صورت افقی قرار می گیرد.

مرحله 3: اتصالات دکمه

اتصالات دکمه
اتصالات دکمه
اتصالات دکمه
اتصالات دکمه

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

حالا بیایید سیم ها را اضافه کنیم.

  • یک سرب قرمز از یک پین قدرت مثبت به همان ستون با پین پایین سمت راست روی دکمه قرار دهید
  • یک سیم سیاه از پین قدرت منفی به همان ستون مقاومت قرار دهید.
  • یک سیم رنگی (نه قرمز/مشکی) از پین بالا سمت چپ تا پین دیجیتال 2 روی آردوینو قرار دهید

برای اطمینان از صحت سیم کشی ، تصاویر بالا را بررسی کنید.

مرحله 4: کد…

کد…
کد…
کد…
کد…

اجازه دهید کد یک دکمه اصلی را بررسی کنیم.

ویرایشگر کد را باز کرده و از Blocks به Text تغییر دهید. اخطار پیش آمده را پاک کنید. از نوشتار راضی هستیم!

شما تنظیمات اولیه را می دانید ، بنابراین اجازه دهید دکمه را تعریف کرده و یک خواندن اساسی انجام دهیم. ما خروجی را به Serial چاپ می کنیم.

من چند نظر اضافی به کد زیر وارد کردم تا خواندن آن راحت تر از تصویر باشد.

// ثابت ها را تعریف کنید

#تعریف دکمه 2 void setup () {pinMode (دکمه ، ورودی) ؛ Serial.begin (9600)؛ } void loop () {// پین دیجیتال را بخوانید تا وضعیت دکمه int pressed = digitalRead (دکمه) را بررسی کنید ؛ // دکمه در صورت فشردن HIGH ، در صورت نبود LOW اگر (فشرده == HIGH) {Serial.println ("فشار داده شده!") ؛ }}

خوب ، خوب کار می کند!

در اصل ، تمام کاری که ما انجام می دهیم بررسی وضعیت پین دیجیتال در هر بار کد حلقه است. اگر روی Start Simulation کلیک کرده و دکمه را فشار دهید ، نمایشگر Serial Monitor (روی دکمه زیر کد کلیک کنید) نمایش داده می شود "Pressed!" بارها و بارها

یکی از ویژگی هایی که در کد بالا مشاهده خواهید کرد ، ارزیابی وضعیت if () است. تمام کاری که کد انجام می دهد این است که در این مورد یک سوال بپرسید و درستی آن را ارزیابی کنید. برای بررسی اینکه آیا مقدار متغیر با مقدار معینی برابر است یا خیر ، از علامت برابر (دو علامت مساوی ، مانند: ==) استفاده می کنیم. () digitalRead HIGH یا LOW را برمی گرداند.

با استفاده از if () else if / else ما می توانیم بسیاری از شرایط یا همه شرایط را بررسی کنیم ، و اگر به مبانی آردوینو برگردید ، برخی از مقایسه هایی که می توانید انجام دهید را مشاهده خواهید کرد.

اکنون … ممکن است کد ما کامل به نظر برسد … اما ما مشکلی داریم.

ببینید ، وقتی در شبیه ساز هستید واقعاً خوب کار می کند. اما الکتریسیته واقعی دارای سر و صدا است ، به ویژه لوازم الکترونیکی DC. بنابراین دکمه ما ممکن است گاهی اوقات یک خواندن اشتباه را بازگرداند. و این یک مشکل است ، زیرا ممکن است پروژه شما به درستی برای کاربر پاسخ ندهد.

درستش کنیم!

مرحله پنجم: کمی انحراف

یک انحراف کوچک
یک انحراف کوچک

ما از رویه ای به نام debounce برای غلبه بر مشکل دکمه خود استفاده می کنیم. این اساساً مدت زمان مشخصی بین فشار دادن دکمه و پاسخ دادن به فشار را منتظر می ماند. هنوز برای کاربر طبیعی به نظر می رسد (مگر اینکه زمان را بیش از حد طولانی کنید). همچنین می توانید از آن برای بررسی طول پرس استفاده کنید ، بنابراین می توانید هر بار متفاوت پاسخ دهید. نیازی به تغییر سیم کشی ندارید!

بیایید کد را بررسی کنیم:

#تعریف دکمه 2#تعریف debounceTimeout 100

اولین تغییر در حوزه جهانی است. به خاطر خواهید داشت که در آنجا ما متغیرهایی را تعریف می کنیم که بسیاری از توابع ما ممکن است از آنها استفاده کنند یا آنهایی که در هر بار روشن شدن حلقه قابل بازنشانی نیستند. بنابراین ، debounceTimeout را به ثابت های تعریف شده اضافه کردیم. ما این 100 را (که بعداً به 100 میلی متر ترجمه می شود) ساختیم ، اما می تواند کوتاه تر باشد. دیگر هیچ و غیر طبیعی به نظر می رسد

long int lastDebounceTime؛

این متغیر در زیر ثابت ها اعلام شده است. این یک نوع int طولانی است که اساساً به ما اجازه می دهد اعداد طولانی را در حافظه ذخیره کنیم. ما آن را lastDebounceTime نامیدیم.

ما نیازی به تغییر چیزی در تابع void setup () نداریم. بگذارید آن یکی را رها کنیم.

void loop () {// پین دیجیتال را بخوانید تا وضعیت دکمه int pressed = digitalRead (دکمه) را بررسی کنید ؛ long int currentTime = millis ()؛ // کد دکمه}

اولین تغییری که در تابع حلقه () ایجاد می کنیم ، زیر فراخوانی دکمه است. ما باید زمان فعلی را پیگیری کنیم. تابع millis () زمان فعلی ساعت را از زمان بوت شدن آردوینو در میلی ثانیه باز می گرداند. ما باید این را در یک متغیر نوع int طولانی ذخیره کنیم.

اکنون ، ما باید مطمئن شویم که از زمان فشردن دکمه مطلع هستیم ، بنابراین زمانی که تایمر فشرده نشده است ، آن را تنظیم مجدد می کنیم. نگاهی بیاندازید:

void loop () {// پین دیجیتال را بخوانید تا وضعیت دکمه int pressed = digitalRead (دکمه) را بررسی کنید ؛ long int currentTime = millis ()؛ if (فشرده == LOW) {// بازنشانی زمان شمارش در حالی که دکمه فشرده نشده است lastDebounceTime = currentTime؛ } // کد دکمه}

الگوریتم if (pressed == LOW) بررسی می کند که آیا دکمه فشرده نشده است. اگر اینطور نیست ، کد زمان فعلی را از آخرین بازخوانی ذخیره می کند. به این ترتیب ، هر بار که دکمه فشرده می شود ، ما یک نقطه زمانی داریم که می توانیم زمان فشار دادن دکمه را بررسی کنیم. سپس می توانیم یک محاسبه سریع ریاضی انجام دهیم تا ببینیم دکمه چقدر فشار داده شده است و به درستی پاسخ دهیم. بیایید به بقیه کد نگاه کنیم:

void loop () {// پین دیجیتال را بخوانید تا وضعیت دکمه int pressed = digitalRead (دکمه) را بررسی کنید ؛ long int currentTime = millis ()؛ if (فشرده == LOW) {// بازنشانی زمان شمارش در حالی که دکمه فشرده نشده است lastDebounceTime = currentTime؛ } // دکمه برای مدت معینی فشرده شده است اگر ((((currentTime - lastDebounceTime)> debounceTimeout)) {// در صورت رسیدن به زمان پایان ، دکمه را فشار دهید! Serial.println ("فشار داده شده!") ؛ }}

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

کد خود را اجرا کرده و بررسی کنید که آیا کار می کند. اگر خطایی دارید ، کد خود را بررسی کنید!

اکنون ، بیایید به یک مثال عملی نگاه کنیم.

مرحله ششم: تهیه منو

تهیه منو
تهیه منو

دکمه ها جالب هستند ، زیرا امکانات زیادی با آنها وجود دارد! در این مثال ، ما قصد داریم یک منو بسازیم. فرض کنید شما این دستگاه واقعاً عالی را ایجاد کرده اید و به کاربران نیاز دارید تا بتوانند گزینه ها را برای روشن یا خاموش کردن برخی موارد تغییر دهند یا مقدار خاصی را برای یک تنظیم تعیین کنند. این طراحی سه دکمه می تواند این کار را انجام دهد!

بنابراین ، برای این پروژه ما نیاز داریم:

  • سه دکمه
  • سه مقاومت روی 10kΩ تنظیم شده است

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

سه دکمه عبارتند از منوی باز/گزینه بعدی ، گزینه تغییر (مانند تصویر ، تغییر تنظیمات) و دکمه ذخیره/بستن منو.

سیم کشی کنید ، بیایید کد را بررسی کنیم!

مرحله 7: تجزیه کد - جهانی

خوب ، این یک مرحله طولانی است ، اما من قصد دارم هر بخش از کد را مرور کنم.

ابتدا اجازه دهید متغیرهای جهانی مورد نیاز را بررسی کنیم.

// تعریف ثابتها #تعریف منو دکمه 2 #تعریف منو انتخاب 3 #تعریف منو ذخیره 4 #تعریف debounceTimeout 50 // تعریف متغیرها در menuButtonPreviousState = LOW؛ int menuSelectPreviousState = LOW؛ int menuSavePreviousState = LOW؛ long int lastDebounceTime؛ // گزینه های منو char * menuOptions = {"Check Temp"، "Check Light"}؛ bool featureSetting = {نادرست ، غلط}؛ bool menuMode = false؛ bool menuNeedsPrint = false؛ int optionSelected = 0؛

این سه بلوک تقریباً مشابه آنچه قبلاً دیده ایم است. در اولین مورد ، من سه دکمه و زمان پایان را تعریف کرده ام. برای این بخش از پروژه ، آن را روی 50ms تنظیم کرده ام ، بنابراین برای کار کردن به یک پرس عمدی نیاز است.

بلوک دوم همه متغیرها است. ما باید پیغام buttonPreviousState را داشته باشیم و آخرین lastBebounceTime را پیگیری کنیم. اینها همه متغیرهای نوع int هستند ، اما آخرین نوع طولانی است زیرا فرض می کنم ما به فضای در حافظه نیاز داریم.

بلوک گزینه های منو دارای چند ویژگی جدید است. اول ، char * (بله ، این یک ستاره عمدی است) ، که یک متغیر تحت اللفظی کاراکتر/رشته است. این یک اشاره گر برای ذخیره سازی استاتیک در حافظه است. شما نمی توانید آن را تغییر دهید (مانند مثال در پایتون). این خط char *menuOptions مجموعه ای از رشته های تحت اللفظی را ایجاد می کند. شما می توانید هر تعداد مورد منو را که دوست دارید اضافه کنید.

متغیر bool featureSetting فقط آرایه ای از مقادیر است که هر آیتم منو را نشان می دهد. بله ، می توانید هر چیزی را که دوست دارید ذخیره کنید ، فقط نوع متغیر را تغییر دهید (همه آنها باید یک نوع باشند). در حال حاضر ، ممکن است راههای بهتری برای مدیریت این مورد وجود داشته باشد ، مانند فرهنگ لغت یا چندتایی ، اما این برای این برنامه ساده است. من احتمالاً یکی از دومی را در یک برنامه کاربردی ایجاد می کنم.

من menuMode را پیگیری کرده ام ، بنابراین اگر می خواستم چیزهای دیگری در صفحه نمایش من وجود داشته باشد ، می توانم این کار را انجام دهم. همچنین ، اگر منطق سنسور را داشتم ، ممکن است در حین کار منو آن را متوقف کنم ، فقط در صورت مغایرت چیزی. من متغیر menuNeedsPrint دارم زیرا می خواهم منو را در زمانهای خاص چاپ کنم ، نه فقط تمام وقت. در نهایت ، من یک متغیر optionSelected دارم ، بنابراین می توانم گزینه ای را انتخاب کنم که در جاهایی به آن دسترسی دارم.

بیایید مجموعه بعدی توابع را بررسی کنیم.

مرحله 8: خرابی کد - راه اندازی و عملکردهای سفارشی

عملکرد setup () به اندازه کافی آسان است ، فقط سه اعلان ورودی:

void setup () {pinMode (menuSelect، INPUT)؛ pinMode (menuSave ، INPUT) ؛ pinMode (منو انتخاب ، ورودی) ؛ Serial.begin (9600)؛ }

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

ما به دو تابع نیاز داریم که برخی اطلاعات را برگرداند. دلیلش این است که ما می خواهیم مطمئن شویم که این مطلب به نوعی برای انسان قابل خواندن است. در صورت بروز مشکل ، اشکال زدایی کد نیز کمک می کند. کد:

// تابع بازگشت گزینه منتخب فعلی charchar *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected] ؛ // گزینه بازگشت بازگشت منتخب menuOption؛ } // عملکرد بازگشت وضعیت فعلی گزینه انتخاب شده char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]؛ char *optionSettingVal؛ if (optionSetting == false) {optionSettingVal = "False"؛ } else {optionSettingVal = "درست"؛ } // Return optionSetting return optionSettingVal؛ }

تابع char *ReturnOptionSelected () گزینه انتخاب شده را بررسی می کند (اگر در بالا مشاهده کردید ، ما یک متغیر را برای پیگیری آن تنظیم می کنیم) و رشته تحت اللفظی را از آرایه ای که قبلاً ایجاد کرده ایم بیرون می آورد. سپس آن را به عنوان یک نوع کاراکتر برمی گرداند. ما این را می دانیم زیرا تابع نوع بازگشت را نشان می دهد.

تابع دوم ، char *ReturnOptionStatus () وضعیت گزینه ذخیره شده در آرایه را می خواند و یک رشته تحت الفظی را نشان می دهد که مقدار را نشان می دهد. به عنوان مثال ، اگر تنظیماتی که ذخیره کرده ایم نادرست باشد ، "False" را برمی گردانم. این به این دلیل است که ما این متغیر را به کاربر نشان می دهیم و بهتر است تمام این منطق را در کنار هم نگه داریم. من می توانم بعداً این کار را انجام دهم ، اما انجام آن در اینجا منطقی تر است.

// تابع برای تغییر حالت فعلی optionbool ToggleOptionSelected () {featureSetting [optionSelected] =! featureSetting [optionSelected] بازگشت واقعی ؛ }

تابع bool ToggleOptionSelected () یک تابع راحتی برای تغییر مقدار تنظیماتی است که در منو انتخاب کرده ایم. فقط ارزش را برمی گرداند اگر مجموعه پیچیده تری از گزینه ها را داشتید ، این ممکن است کاملاً متفاوت باشد. من در این تابع true را برمی گردانم ، زیرا callback من (تماس بعداً در کدی که این تابع را فعال می کند) انتظار پاسخ درست/غلط را دارد. من 100 sure مطمئن هستم که این کار می کند ، بنابراین من کار نکردن آن را حساب نکردم ، اما در یک برنامه کاربردی (در هر صورت) کار می کردم.

مرحله 9: حلقه…

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

حلقه خالی () {

// اینجا کار کنید <-----}

خوب ، ما قبلاً این موارد را دیدیم:

// دکمه های int menuButtonPressed = digitalRead (menuButton) را بخوانید ؛ int menuSelectPressed = digitalRead (menuSelect) ؛ int menuSavePressed = digitalRead (menuSave) ؛ // زمان فعلی طولانی را دریافت کنید int currentTime = millis ()؛ if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// زمان شمارش مجدد را تنظیم کنید در حالی که دکمه lastDebounceTime = currentTime فشار داده نشده است ؛ menuButtonPreviousState = LOW؛ menuSelectPreviousState = LOW؛ menuSavePreviousState = LOW؛ }

تنها کاری که باید در اینجا انجام می دادم این بود که سه فراخوان digitalRead () را اضافه می کردم و مطمئن می شدم که اگر همه دکمه ها کم باشند ، باید زمان سنج (lastDebounceTime = currentTime) را بازنشانی کرده و همه حالت های قبلی را روی کم تنظیم کنیم. من همچنین millis () را در currentTime ذخیره می کنم.

قسمت بعدی داخل خط قرار می گیرد

if (((currentTime - lastDebounceTime)> debounceTimeout)) {

// اینجا کار کنید <----}

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

if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true؛ // به کاربر اطلاع دهید Serial.println ("منو فعال است") ؛ } else if (menuMode == true && optionSelected = 1) {// Reset option optionSelected = 0؛ } // چاپ منوی menuNeedsPrint = true؛ // تغییر دکمه قبلی. فقط برای نمایش منو // در صورت آزاد شدن دکمه و فشار مجدد حالت menuButtonPreviousState = menuButtonPressed؛ // بالا خواهد بود}

این اولین مورد زمانی کار می کند که menuButtonPressed بالا باشد یا دکمه منو فشار داده شود. همچنین بررسی می کند که آیا حالت قبلی LOW بوده است ، بنابراین قبل از فشار دادن مجدد دکمه باید آزاد شود ، که باعث می شود برنامه مدام یک رویداد را بارها و بارها شلیک نکند.

سپس بررسی می کند که اگر منو فعال نیست ، آن را فعال می کند. این اولین گزینه انتخاب شده را چاپ می کند (که اولین مورد در منو است آرایه گزینه ها به طور پیش فرض. اگر دکمه را برای بار دوم یا سوم (و غیره) فشار دهید ، گزینه بعدی را در لیست دریافت خواهید کرد. چیزی که می توانم رفع کنم این است که هنگامی که به پایان می رسد ، با چرخه به ابتدا باز می گردد. این می تواند طول آرایه را بخواند و اگر تعداد گزینه ها را تغییر دهید ، دوچرخه سواری آسان تر می شود ، اما این در حال حاضر ساده بود.

آخرین قسمت کوچک (// منو را چاپ می کند) بدیهی است که منو را چاپ می کند ، اما وضعیت قبلی را نیز بر روی HIGH تنظیم می کند ، بنابراین همان عملکرد حلقه نمی شود (در مورد بررسی اینکه آیا دکمه قبلاً LOW بوده است به یادداشت من در بالا مراجعه کنید).

// menuSelect فشار داده شده است ، logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// تغییر گزینه انتخاب شده // در حال حاضر ، این فقط درست/غلط است // اما could be something bool toggle = ToggleOptionSelected ()؛ if (ضامن) {menuNeedsPrint = true؛ } else {Serial.println ("مشکلی پیش آمد. لطفاً دوباره امتحان کنید")؛ }} // حالت را تغییر دهید تا فقط در صورت آزاد شدن تغییر وضعیت داده و دوباره فشار دهید menuSelectPreviousState = menuSelectPressed؛ }

این کمی از کد دکمه menuSelectPressed را به همان شکل مدیریت می کند ، به جز این زمان ما فقط تابع () ToggleOptionSelected را روشن می کنیم. همانطور که قبلاً گفتم ، می توانید این عملکرد را تغییر دهید تا بیشتر کار کند ، اما این تنها چیزی است که من برای انجام آن نیاز دارم.

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

if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// از منو خارج شوید // در اینجا می توانید هرگونه مرتب سازی را انجام دهید // یا در EEPROM menuMode = false ذخیره کنید؛ Serial.println ("از منو خارج شد") ؛ // حالت را تغییر دهید تا منو فقط یکبار خارج شود menuSavePreviousState = menuSavePressed؛ }}

این عملکرد دکمه menuSave را که فقط از منو خارج می شود ، کنترل می کند. در اینجا می توانید گزینه لغو یا ذخیره را داشته باشید ، شاید کمی تمیز کنید یا در EEPROM ذخیره کنید. من فقط "Menu exited" را چاپ می کنم و حالت دکمه را روی HIGH تنظیم می کنم تا حلقه نشود.

if (menuMode && menuNeedsPrint) {// منو را چاپ کرده ایم ، بنابراین اگر اتفاقی // نیفتد ، نیازی به چاپ مجدد آن نیست menuNeedsPrint = false؛ char *optionActive = ReturnOptionSelected ()؛ char *optionStatus = ReturnOptionStatus ()؛ Serial.print ("منتخب:") ؛ Serial.print (optionActive) ؛ Serial.print (":")؛ Serial.print (optionStatus) ؛ Serial.println ()؛ }

این الگوریتم menuPrint است که فقط زمانی فعال می شود که منو فعال باشد و وقتی متغیر menuNeedsPrint روی true تنظیم شده باشد.

این قطعاً می تواند به عملکرد خود منتقل شود ، اما به خاطر سادگی..!

خوب ، همین! مرحله بعدی را برای کل بلوک کد مشاهده کنید.

مرحله 10: بلوک کد نهایی

// ثابت ها را تعریف کنید

#تعریف منو دکمه 2 #تعریف منو انتخاب 3 #تعریف منو ذخیره 4 #تعریف بازخوانی Timeout 50 int menuButtonPreviousState = LOW؛ int menuSelectPreviousState = LOW؛ int menuSavePreviousState = LOW؛ // تعریف متغیرهای long int lastDebounceTime؛ bool lightSensor = true؛ bool tempSensor = true؛ // گزینه های منو char * menuOptions = {"Check Temp"، "Check Light"}؛ bool featureSetting = {نادرست ، غلط}؛ bool menuMode = false؛ bool menuNeedsPrint = false؛ int optionSelected = 0؛ // تابع راه اندازی

void setup () {pinMode (menuSelect، INPUT)؛ pinMode (menuSave ، INPUT) ؛ pinMode (منو انتخاب ، ورودی) ؛ Serial.begin (9600)؛ }

// تابع بازگشت گزینه انتخاب شده فعلی char *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]؛ // گزینه بازگشت بازگشت منتخب menuOption؛ } // عملکرد بازگشت وضعیت فعلی گزینه انتخاب شده char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]؛ char *optionSettingVal؛ if (optionSetting == false) {optionSettingVal = "False"؛ } else {optionSettingVal = "درست"؛ } // Return optionSetting return optionSettingVal؛ } // عملکرد تغییر حالت فعلی bool ToggleOptionSelected () {featureSetting [optionSelected] =! featureSetting [optionSelected]؛ بازگشت واقعی ؛ } // حلقه اصلی

void loop () {// دکمه های int menuButtonPressed = digitalRead (menuButton) را بخوانید ؛ int menuSelectPressed = digitalRead (menuSelect) ؛ int menuSavePressed = digitalRead (menuSave) ؛ // زمان فعلی طولانی را دریافت کنید int currentTime = millis ()؛ if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// زمان شمارش مجدد را تنظیم کنید در حالی که دکمه lastDebounceTime = currentTime فشار داده نشده است ؛ menuButtonPreviousState = LOW؛ menuSelectPreviousState = LOW؛ menuSavePreviousState = LOW؛ } if ((((currentTime - lastDebounceTime)> debounceTimeout)) {// در صورت رسیدن مهلت زمانی ، دکمه را فشار دهید!

// menuButton فشار داده شده است ، منطق را ارائه دهید

// فقط زمانی فعال می شود که دکمه اگر ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true؛ // به کاربر اطلاع دهید Serial.println ("منو فعال است") ؛ } else if (menuMode == true && optionSelected = 1) {// Reset option optionSelected = 0؛ } // چاپ منوی menuNeedsPrint = true؛ // تغییر دکمه قبلی. فقط برای نمایش منو // در صورت آزاد شدن دکمه و فشار مجدد حالت menuButtonPreviousState = menuButtonPressed؛ // خواهد بود HIGH} // menuSelect فشار داده شده است ، منطق را ارائه دهید اگر ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// تغییر گزینه انتخاب شده // در حال حاضر ، این فقط true/false // اما می تواند هر چیزی باشد bool toggle = ToggleOptionSelected ()؛ if (ضامن) {menuNeedsPrint = true؛ } else {Serial.print ("مشکلی پیش آمد. لطفاً دوباره امتحان کنید")؛ }} // حالت را تغییر دهید تا فقط در صورت آزاد شدن تغییر وضعیت داده و دوباره فشار دهید menuSelectPreviousState = menuSelectPressed؛ } if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// از منو خارج شوید // در اینجا می توانید هرگونه مرتب سازی را انجام دهید // یا در EEPROM menuMode = false ذخیره کنید؛ Serial.println ("از منو خارج شد") ؛ // حالت را تغییر دهید تا منو فقط یکبار خارج شود menuSavePreviousState = menuSavePressed؛ }} // گزینه منوی فعلی را فعال کنید ، اما فقط یک بار آن را چاپ کنید (menuMode && menuNeedsPrint) {// منو را چاپ کرده ایم ، بنابراین مگر اینکه اتفاقی // رخ دهد ، نیازی به چاپ مجدد آن نیست menuNeedsPrint = false؛ char *optionActive = ReturnOptionSelected ()؛ char *optionStatus = ReturnOptionStatus ()؛ Serial.print ("منتخب:") ؛ Serial.print (optionActive) ؛ Serial.print (":")؛ Serial.print (optionStatus) ؛ Serial.println ()؛ }}}

این مدار در سایت Tinkercad موجود است. من مدار زیر را برای شما نیز جاسازی کرده ام!

مثل همیشه ، اگر س questionsال یا مشکلی دارید ، لطفاً به من اطلاع دهید!

توصیه شده: