สอนใช้ Arduino เช็คสถานะปุ่มกด (Push Button) หรือสวิตซ์ (Switch)

ปุ่มกด (Push Button) หรือสวิตซ์ (Switch) เป็นอุปกรณ์พื้นฐานที่ใช้กันทั่วไปในหลายๆ โปรเจค เพื่อเชื่อมจุด 2 จุดในวงจรให้ถึงกัน มักใช้เพื่อรับข้อมูลจากผู้ใช้ เช่น เมื่อผู้ใช้กดปุ่มให้อุปกรณ์ที่ต่อพ่วงเริ่มทำงาน หรืออาจจะรับสัญญาณจากกลไกต่างๆ เช่น เมื่อวัตถุเคลื่อนที่มาถึงลิมิตสวิตซ์ (Limit Switch) ให้เครื่องจักรหยุดทำงาน เป็นต้น นอกจากนี้ยังสามารถใช้ความรู้นี้ไปประยุกต์ต่อกับเซ็นเซอร์ (Sensor) บางประเภทได้อีกด้วย แต่อย่างไรก็ตามในบทความนี้จะเน้นไปที่การใช้สวิตซ์กดแบบธรรมดาครับ

อุปกรณ์ที่ต้องใช้

  • x1 บอร์ด Arduino (หรือบอร์ดอื่นๆ ที่คล้ายกัน)
  • x1 สวิตซ์ (Switch)
  • x1 ตัวต้านทาน (Resistor) 4.7 – 10K kΩ (ค่าใดก็ได้)
  • x1 สายไฟจั๊มเปอร์
  • x1 บอร์ดทดลอง (Breadboard)

วิธีต่อวงจร

เราจะต่อสวิตซ์เพื่อใช้งานกับ Arduino โดยใช้การต่อวงจรที่เรียกว่า Pull-Up Resistor หรือ Pull-Down Resistor อย่างใดก็ได้ เพื่อป้องกันไม่ให้ขา Input อยู่ในสถานะ Floating จนอ่านค่าจากขา Input มาใช้งานไม่ได้

*** Floating เป็นสถานะที่ขา Input ของ MCU ไม่ได้ต่ออยู่กับ VCC หรือ GND อย่างใดอย่างหนึ่งเลย ทำให้เมื่ออ่านค่าจากขา Input นั้น จะได้ค่าออกมาในลักษณะสุ่มระหว่าง LOW และ HIGH แบบไม่สามารถคาดเดาได้ ***

โดยความแตกต่างในด้านการใช้งานของทั้ง 2 วงจรนี้ คือ

  • Pull-Up Resistor
    • ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น HIGH
    • กดปุ่ม จะอ่านค่าได้เป็น LOW
  • Pull-Down Resistor
    • ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น LOW
    • กดปุ่ม จะอ่านค่าได้เป็น HIGH

ตรงจุดนี้สามารถเลือกใช้ได้ตามความเหมาะสมนะครับ ว่าอยากได้สถานะตอนกดปุ่มเป็น HIGH หรือเป็น LOW ส่วนการต่อวงจรก็ตามภาพด้านล่างเลยครับ

Internal Pull-Up Resistor

นอกเหนือจากการต่อวงจร 2 แบบที่ได้อธิบายไว้ด้านบนแล้ว บอร์ด Arduino หรือบอร์ดอื่นๆ ที่คล้ายกันบางบอร์ด เขาก็ได้ติดตั้งวงจร Pull-Up Resistor มาให้เราในตัวบอร์ดแล้ว (เรียกว่า Internal Pull-Up Resistor) โดยที่เราไม่ต้องหาตัวต้านทานจากภายนอกมาต่อเพิ่ม มีแค่สวิตซ์อย่างเดียวเราก็สามารถต่อวงจรใช้งานได้แล้ว วิธีการต่อวงจรทำได้โดยต่อขาด้านหนึ่งของสวิตซ์เข้ากับขา Input ส่วนขาอีกด้านหนึ่งต่อเข้ากับ GND ซึ่งคล้ายกับการต่อ Pull-Up Resistor แบบปกติ แต่ต่างกันตรงที่ Resistor ถูกต่อแบบ Pull-Up มาให้ในตัวบอร์ดเรียบร้อยแล้ว

โค้ดโปรแกรมอย่างง่าย (เพื่อความเข้าใจ)

ตัวอย่างนี้จะเป็นโค้ดโปรแกรมอย่างง่ายที่สุด สำหรับอ่านค่าจากขา Input (ในที่นี้เป็นขา 2) และเมื่ออ่านค่าจากขา Input ได้เป็น HIGH ไฟที่ LED ติด แต่ถ้าอ่านค่าได้เป็น LOW ไฟที่ LED ดับ (ในที่นี้ใช้ built-in LED ของ Arduino UNO ซึ่งอยู่ที่ขา 13)

โดยโค้ดนี้ใช้ได้กับทั้งวงจร Pull-Up Resistor และ Pull-Down Resistor ซึ่งให้ผลลัพธ์การทำงานที่แตกต่างกันดังนี้

  • Pull-Up Resistor หรือ Internal Pull-Up Resistor
    • ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น HIGH (ไฟที่ LED ติด)
    • กดปุ่ม จะอ่านค่าได้เป็น LOW (ไฟที่ LED ดับ)
  • Pull-Down Resistor
    • ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น LOW (ไฟที่ LED ดับ)
    • กดปุ่ม จะอ่านค่าได้เป็น HIGH (ไฟที่ LED ติด)

หมายเหตุ : หากต้องการใช้งาน Internal Pull-Up Resistor ให้แทนที่คำสั่ง pinMode(buttonPin, INPUT) ด้วย pinMode(buttonPin, INPUT_PULLUP)

/* 
 * code from : http://www.arduino.cc/en/Tutorial/Button
 * description : button example with comment removed (easier to read)
 */

const int buttonPin = 2;
const int ledPin =  13;
int buttonState = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

โค้ดโปรแกรมแบบใช้ไลบรารี Bounce2 (เพื่อใช้งานจริง)

โค้ดโปรแกรมก่อนหน้าเป็นเพียงการใช้งานฟังก์ชั่น digitalRead() อ่านค่าแบบธรรมดาๆ ไม่ได้ป้องกันการ bounce ของสวิตซ์เอาไว้เลย ซึ่งอาจก่อให้เกิดปัญหาขณะใช้งานจริงได้

วิธีแก้ไขคือ เราต้องเขียนโค้ดโปรแกรมเพื่อ debounce โดยผมแนะนำให้ใช้ไลบรารีชื่อ Bounce2 เพื่อให้โค้ดโปรแกรมของเราบำรุงรักษาได้ง่าย และง่ายต่อการนำกลับมาใช้ซ้ำในโปรเจคอื่นๆ (สามารถศึกษาวิธีติดตั้งไลบรารีได้ที่นี่)

***  การ bounce ของสวิตซ์ คือการสั่นของสวิตซ์ ทำให้เกิดสัญญาณดิจิตอลไปที่ขา Input หลายครั้งในการกดสวิตซ์เพียงครั้งเดียว จนส่งผลให้ระบบทำงานผิดพลาดเนื่องจากระบบจะเข้าใจว่าสวิตซ์ถูกกดหลายครั้งนั่นเอง ส่วนการป้องกันการ bounce เราจะถูกเรียกว่าการ debounce ***

ตัวอย่างโค้ดโปรแกรมเมื่อใช้งานไลบรารี Bounce2

/*
 * code from : https://github.com/thomasfredericks/Bounce2
 * description : Translate comment to thai.
 */

#include <Bounce2.h>

#define BUTTON_PIN 2
#define LED_PIN 13

int ledState = LOW;

Bounce debouncer = Bounce(); // สร้าง debouncer object

void setup() {
   // กำหนดให้ debouncer object ใช้ BUTTON_PIN ในโหมด INPUT_PULLUP (จะแก้เป็น INPUT, INPUT_PULLUP หรือ OUTPUT ก็ได้ขึ้นอยู่กับการต่อวงจร)
   debouncer.attach(BUTTON_PIN, INPUT_PULLUP);
   debouncer.interval(25); // กำหนดเวลาการเปลี่ยนสถานะให้กับ debouncer object ที่ 25 มิลลิวินาที
  
   pinMode(LED_PIN, OUTPUT);
   digitalWrite(LED_PIN, ledState);
}

void loop() {
   debouncer.update(); // อัปเดตสถานะให้กับ debouncer object
   
   // กำหนดเงื่อนไขให้โค้ดโปรแกรมในวงเล็บปีกกาทำงานเมื่อสถานะปุ่มกดเปลี่ยนจาก HIGH เป็น LOW โดยเช็คจากฟังก์ชั่น fell()
   // หากต้องการเช็คสถานะจาก LOW เป็น HIGH ให้แทนที่ฟังก์ชั่น fell() ด้วยฟังก์ชั่น rose()
   if ( debouncer.fell() ) { 
      ledState = !ledState; // สลับสถานะติด/ดับของ LED
      digitalWrite(LED_PIN, ledState); // สั่งให้ LED ติด หรือดับ
   }
}

สรุป

  • การต่อสวิตซ์เพื่อใช้งานกับ Arduino หรือไมโครคอนโทรลเลอร์ (MCU) จำเป็นต้องต่อวงจรแบบ Pull-Up Resistor หรือ Pull-Down Resistor เพื่อป้องกันไม่ให้ขา Input อยู่ในสถานะ Floating จนอ่านค่ามาใช้งานไม่ได้
  • บอร์ดบางตัวจะติดตั้ง Pull-Up Resistor มาให้แล้วในตัวบอร์ดเรียบร้อยแล้ว (เรียกว่า Internal Pull-Up Resistor) แปลว่าเราสามารถใช้งานวงจรแบบ Pull-Up Resistor ได้ทันทีโดยที่ไม่ต้องต่อ Resistor เพิ่มจากภายนอก
  • การเขียนโค้ดโปรแกรมเพื่อ debounce แนะนำให้ใช้ไลบรารีแทนการเขียนด้วยตัวเอง เพราะบำรุงรักษาง่ายกว่า และนำไปใช้ซ้ำในโปรเจคอื่นได้ง่ายกว่า
  • การ debounce ด้วยการต่อวงจรก็สามารถทำได้ เพียงแต่ไม่ได้ถูกพูดถึงในบทความนี้ครับ

ข้อมูลเพิ่มเติม

แบ่งปันสิ่งนี้บน

Leave a Comment