کار کردن با دکمه ها در آردوینو

Ratings
(0)

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

یک دکمه ی فشاری در الکترونیک

 تصویر زیر یک مدار ساده را نشان می دهد که از یک دکمه ی فشاری استفاده می کند. پین 7(که کاملا اختیاری انتخاب شده است) را به دکمه ی فشاری متصل کنید و این دکمه را از طریق یک مقاومت  10kΩ به اتصال به زمین(ground) متصل کنید. سپس منبع برق 5 ولت را به دیگر پین دکمه متصل کنید. مطمئن شوید که جهت دکمه ی فشاری درست باشد. پین های اتصال دکمه ی فشاری باید روی شکاف بردبرد پل بزنند. 

 در مجموع، این روش سر-راست به نظر می رسد اما سوال اینجاست که چرا ما دوباره به یک مقاومت احتیاج داریم؟ مسئله این است که ما از دکمه ی فشاری انتظار داریم تا یک مقدار پیش فرض یعنی LOW را در صورت فشار داده نشدن دکمه، به ما برگرداند. اما وقتی که دکمه فشار داده شده نیست، مستقیماً به زمین(ground ) وصل خواهد شد، و به دلیل استاتیک و تداخلات(interferences)  سوسو(flicker ) می زند. اما اگر از مقاومت استفاده کنیم، تنها، جریان بسیار کمی از مقاومت عبور می کند، و این کمک می کند تا از نوسانات تصادفی ولتاژ در پین ورودی جلوگیری شود. وقتی که دکمه فشار داده می شود، مقدار 5 ولت در پین دیجیتال آردوینو ایجاد می شود اما وقتی که دکمه فشار داده می شود، به درستی اتصال به زمین(ground) را وصل می کند. ما به این مقاومت، مقاومت کاهنده(pull-down resistor)، می گوییم. اما یک مقاومت افزاینده(pull-up resistor) دقیقاً برعکس عمل می کند.

 این است که ما باید پین سیگنال آردوینو را از طریق دکمه ی فشاری به برق(power ) متصل کنیم و پین دیگر دکمه را با استفاده از مقاومت به زمین(ground ) متصل کنیم. اکنون که ما از شر رفتار بی ثبات جهان واقعی، خلاص شدیم، می توانیم به حالت  پایدار توسعه ی نرم افزار برگردیم. برنامه ی زیر، بررسی می کند که آیا یک دکمه ی فشاری(pushbutton ) فشار داده شده است یا نه  و بر این اساس یک ال ای دی روشن شود یا نه:

const unsigned int BUTTON_PIN = 7;
const unsigned int LED_PIN    = 13;

void setup() {
  pinMode(LED_PIN, OUTPUT);      
  pinMode(BUTTON_PIN, INPUT);     
}
void loop() {
  const int BUTTON_STATE = digitalRead(BUTTON_PIN);
  
  if (BUTTON_STATE == HIGH)
    digitalWrite(LED_PIN, HIGH);  
  else
    digitalWrite(LED_PIN, LOW); 
}

 ما دکمه را به پین 7 متصل می کنیم و ال ای دی را به پین 13 متصل می کنیم و در تابع setup این پین ها را مقداردهی اولیه(initialize ) می کنیم. در حلقه(loop)، ما حالت فعلی  پین متصل شده به دکمه را قرائت می کنیم. اگر این حالت برابر با HIGH باشد، ما ال ای دی را روشن می کنیم. در غیر این صورت، ال ای دی را خاموش می کنیم. اکنون برنامه را در آردوینو آپلود کنید و خواهید دید که تا زمانی که دکمه را فشار داده ایم، ال ای دی روشن می ماند. به محض اینکه ما دکمه را رها می کنیم، ال ای دی خاموش می شود. این بسیار جالب است، زیرا اکنون ما تقریباً همه ی کارهای مورد نیاز را انجام دادیم تا بتوانیم با استفاده از یک دکمه، تاس خود را کنترل کنیم. اما قبل از اینکه جلوتر برویم،  می خواهیم اندکی مثال خود را بهبود ببخشیم و دکمه را به یک کلید برق واقعی متصل کنیم.  برای ایجاد یک کلید برق، ما از ساده ترین راه حل استفاده می کنیم. مدار فعلی را تغییر ندهید و برنامه ی زیر را در آردوینو، به جای قبلی آپلود کنید:

const unsigned int BUTTON_PIN = 7;
const unsigned int LED_PIN    = 13;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
}
int led_state = LOW; 
void loop() {
  const int CURRENT_BUTTON_STATE = digitalRead(BUTTON_PIN);
  if (CURRENT_BUTTON_STATE == HIGH) {
    if (led_state == LOW)
      led_state = HIGH;
    else
      led_state = LOW;
    digitalWrite(LED_PIN, led_state);
  }
}

 در کدهای بالا، ما با تعریف ثابت های پین ها شروع می کنیم، و در تابع setup، ما حالت پین های که استفاده می کنیم را مشخص می کنیم. در خط 8، ما یک متغیر سراسری(global ) به نام led_state تعریف کرده ایم، تا حالت فعلی ال ای دی ما را در خود ذخیره کند. وقتی که ال ای دی خاموش است، led_state برابر با LOW است و در غیر این صورت HIGH است. در حلقه(loop)، ما حالت فعلی دکمه را بررسی می کنیم. وقتی که ما دکمه را فشار می دهیم، حالت دکمه به HIGH عوض می شود و ما مقدار led_state را بر این اساس عوض می کنیم. به این معنا که، اگر led_state برابر با HIGH بود، ما آن را به LOW تنظیم می کنیم و برعکس. در انتها، ما بر این اساس، حالت فیزیکی ال ای دی را با حالت فعلی نرم افزار تنظیم می کنیم. راه حل ما واقعا ساده است اما متاسفانه این راه حل کار نمی کند. کمی با آن کار کنید و شما به سرعت متوجه یک رفتار آزار دهنده خواهید شد. اگر ما دکمه را فشار دهیم، ال ای دی گاهی اوقات روشن می شود و سپس بلافاصله خاموش می شود. همچنین اگر دکمه را رها کنیم، ال ای دی اغلب  خودسرانه عمل می کند، به این معنی که گاهی اوقات روشن می شود و گاهی اوقات خاموش می شود. مشکل این است که آردوینو متد حلقه را بارها و بارها تکرار می کند. با اینکه CPU آردوینو نسبتاً کند است، اما این موضوع اغلب اوقات اتفاق می افتد؛ صرف نظر از اینکه آیا ما در حال حاضر دکمه را فشار داده ایم یا نه. اما اگر ما دکمه را فشار دهیم و به فشار دادن آن ادامه دهیم، حالت آن به طور مداوم HIGH می ماند و انگار ما مرتباً حالت ال ای دی را تغییر داده ایم(چون این کار بسیار سریع انجام می شود، به نظر می رسد که ال ای دی دائم روشن است). وقتی که ما دکمه را فشار دهیم، ال ای دی کم و زیاد در یک حالت خودسرانه عمل می کند. برای بهبود بخشیدن به این وضعیت، ما باید نه تنها حالت فعلی ال ای دی را ذخیره کنیم، بلکه باید حالت قبلی دکمه را نیز ذخیره کنیم:

const unsigned int BUTTON_PIN = 7;
const unsigned int LED_PIN    = 13;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
}
int old_button_state = LOW;
int led_state = LOW;

void loop() {
  const int CURRENT_BUTTON_STATE = digitalRead(BUTTON_PIN);
  if (CURRENT_BUTTON_STATE != old_button_state && CURRENT_BUTTON_STATE == HIGH)  {
    if (led_state == LOW)
      led_state = HIGH;
    else
      led_state = LOW;
    digitalWrite(LED_PIN, led_state);
  }
  old_button_state = CURRENT_BUTTON_STATE;
}

 پس از مقدار دهی اولیه ی(initializing ) دکمه و پین های ال ای دی، ما دو متغیر را تعریف می کنیم؛ متغیر old_button_state حالت قبلی دکمه را در خود ذخیره می کند، و متغیر led_state حالت فعلی ال ای دی را در خود ذخیره می کند. هر دوی این متغیرها، می توانند HIGH یا LOW باشند. در تابع loop، ما هنوز مجبوریم حالت فعلی دکمه را قرائت کنیم، اما اکنون ما نه تنها بررسی می کنیم که این حالت HIGH باشد، بلکه بررسی می کنیم که آیا این حالت از آخرین زمانی که آن را قرائت کرده ایم، تغییر کرده است یا نه.  تنها وقتی که هر دوی این شرایط برقرار باشند، ما حالت ال ای دی را تغییر می دهیم. بنابراین، ما دیگر بارها و بارها ال ای دی را روشن و خاموش نمی کنیم تا زمانی که دکمه فشار داده شود. در انتهای برنامه، ما باید حالت فعلی دکمه را در متغیر old_button_state ذخیره کنیم. اکنون نسخه ی جدید کدها را آپلود کنید و مشاهده خواهید کرد که این راه حل نسبت به قبل بسیار بهتر کار می کند. اما ما هنوز مواردی را مشاهده می کنیم که دکمه کاملا طبق انتظار رفتارنمی کند. این مشکلات عمدتاً وقتی اتفاق می افتند که ما دکمه را رها می کنیم. این مشکلات روی می دهند زیرا دکمه های مکانیکی برای چند میلی ثانیه وقتی که آنها را فشار می دهیم، پرش می کنند. در تصویر زیر، می توانید یک سیگنال معمولی را که توسط یک دکمه ی مکانیکی ایجاد شده است را مشاهده کنید.

 درست پس از اینکه ما دکمه را فشار می دهیم،این دکمه یک سیگنال واضح را منتشر نمی کند. برای غلبه کردن بر این تاثیر، ما باید دکمه را پرش زدایی کنیم.  این معمولاً موثر است که برای مدت کوتاهی صبر کنیم تا سیگنال دکمه پایدار شود. پرش زدایی تضمین می کند که پین ورودی در فشار دادن دکمه، تنها یک بار واکنش نشان دهد.

 

const unsigned int BUTTON_PIN = 7;
const unsigned int LED_PIN    = 13;
void setup() {
  pinMode(LED_PIN, OUTPUT);      
  pinMode(BUTTON_PIN, INPUT);
}

int old_button_state = LOW;
int led_state = LOW;

void loop() {
  const int CURRENT_BUTTON_STATE = digitalRead(BUTTON_PIN);
  if (CURRENT_BUTTON_STATE != old_button_state && 
      CURRENT_BUTTON_STATE == HIGH)
  {
    if (led_state == LOW) 
      led_state = HIGH;
     else
      led_state = LOW;
    digitalWrite(LED_PIN, led_state);
    delay(50); 
  }
  old_button_state = CURRENT_BUTTON_STATE;
}

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

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

 {module کمک نقدی به نویسنده}

  • بازدید: 1425

نوشتن دیدگاه

لطفا نظرات خود را بیان کنید. به سوالات در سریع ترین زمان پاسخ داده خواهد شد.اما به نکات زیر توجه کنید:
1. سعی کنید نظرات شما مرتبط با مقاله ی مورد نظر باشد، در غیر این صورت پاسخ داده نخواهد شد.
2. سوالات خود را به صورت کوتاه بیان کنید و از پرسیدن چند سوال به طور همزمان خودداری کنید.
3. سوال خود را به طور واضح بیان کنید و از کلمات مبهم استفاده نکنید.

ارسال