Raspberry Pi Button Nhấn Giữ và Nhấn Nhanh

Hướng dẫn này sẽ chỉ bạn cách sử dụng Raspberry Pi để phát hiện việc nhấn giữ và nhấn nhanh của button. Để đơn giản hóa, chúng ta sẽ chia thành các ví dụ sau:

Trong phần cuối, chúng ta sẽ khám phá cách sử dụng debounce trong môi trường thực tế. Để biết thêm thông tin về lý do tại sao cần debounce cho button, hãy tham khảo bài viết này. Nếu không có debounce, có thể xảy ra hiện tượng phát hiện sai việc nhấn nhanh button.

Linh Kiện Cần Thiết

1×Raspberry Pi 5
1×Button gắn Breadboard có nắp
1×Bộ Kit Button gắn Breadboard
1×Nút nhấn gắn Panel
1×mô-đun nút nhấn
1×breadboard
1×Dây nối Jumper
1×(Khuyến nghị) Screw Terminal Block Shield for Raspberry Pi
1×(Khuyến nghị) Raspberry Pi Prototyping Base Plate & Breadboard Kit
1×(Khuyến nghị) HDMI Touch Screen Monitor for Raspberry Pi

Or you can buy the following kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Về Button

Nếu bạn chưa quen thuộc với button (bao gồm sơ đồ chân, cách hoạt động và cách lập trình), các hướng dẫn sau có thể cung cấp thông tin hữu ích:

Sơ Đồ Đấu Nối

sơ đồ đấu nối Raspberry Pi nút nhấn

This image is created using Fritzing. Click to enlarge image

Trong hướng dẫn này, chúng ta sẽ sử dụng điện trở pull-up nội bộ. Do đó, khi button không được nhấn, trạng thái của nó là HIGH, và khi được nhấn, trạng thái là LOW.

Cách Phát Hiện Nhấn Nhanh

Chúng ta tính toán khoảng thời gian giữa sự kiện nhấn và thả. Nếu khoảng thời gian này nhỏ hơn thời gian đã định trước, chúng ta sẽ phát hiện sự kiện nhấn nhanh.

Xác định thời lượng của việc nhấn nhanh.

SHORT_PRESS_TIME = 0.5 # 500 milliseconds
  • Phát hiện nếu button được nhấn và ghi lại thời điểm nhấn.
if prev_button_state == GPIO.HIGH and button_state == GPIO.LOW: # Button is pressed press_time_start = time.time()
  • Xác định khi button được thả và ghi lại thời điểm thả.
if prev_button_state == GPIO.LOW and button_state == GPIO.HIGH: # Button is released press_time_end = time.time()
  • Xác định thời lượng nhấn.
press_duration = press_time_end - press_time_start
  • So sánh thời lượng nhấn với thời gian nhấn nhanh đã định để nhận diện nhấn nhanh.
if press_duration < SHORT_PRESS_TIME: print("A short press is detected")

Code Raspberry Pi để phát hiện nhấn nhanh

Các Bước Nhanh

  • Đảm bảo bạn đã cài đặt Raspbian hoặc hệ điều hành tương thích khác với Raspberry Pi trên Pi của bạn.
  • Đảm bảo Raspberry Pi của bạn được kết nối cùng mạng cục bộ với PC của bạn.
  • Đảm bảo Raspberry Pi của bạn được kết nối internet nếu bạn cần cài đặt một số thư viện.
  • Nếu đây là lần đầu tiên bạn sử dụng Raspberry Pi, hãy xem Raspberry Pi - Cài Đặt Phần Mềm
  • Kết nối PC của bạn với Raspberry Pi qua SSH bằng SSH client có sẵn trên Linux và macOS hoặc PuTTY trên Windows. Xem cách kết nối PC với Raspberry Pi qua SSH.
  • Đảm bảo bạn đã cài đặt thư viện RPi.GPIO. Nếu chưa, hãy cài đặt bằng lệnh sau:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Tạo file script Python short_press.py và thêm code sau:
# Mã Raspberry Pi này được phát triển bởi newbiely.vn # Mã Raspberry Pi này được cung cấp để sử dụng công khai, không có ràng buộc. # Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: # https://newbiely.vn/tutorials/raspberry-pi/raspberry-pi-button-long-press-short-press import RPi.GPIO as GPIO import time BUTTON_PIN = 16 SHORT_PRESS_TIME = 0.5 # 500 milliseconds DEBOUNCE_TIME = 0.1 # 100 milliseconds # Variables will change: prev_button_state = GPIO.LOW # the previous state from the input pin button_state = None # the current reading from the input pin press_time_start = 0 press_time_end = 0 # Set up GPIO and configure the pull-up resistor GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: # Read the state of the switch/button button_state = GPIO.input(BUTTON_PIN) # Perform debounce by waiting for DEBOUNCE_TIME time.sleep(DEBOUNCE_TIME) if prev_button_state == GPIO.HIGH and button_state == GPIO.LOW: # Button is pressed press_time_start = time.time() elif prev_button_state == GPIO.LOW and button_state == GPIO.HIGH: # Button is released press_time_end = time.time() press_duration = press_time_end - press_time_start if press_duration < SHORT_PRESS_TIME: print("A short press is detected") # Save the last state prev_button_state = button_state except KeyboardInterrupt: print("\nExiting the program.") GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực thi lệnh sau trong terminal:
python3 short_press.py
  • Nhấn button ngắn nhiều lần.
  • Kiểm tra kết quả trong Terminal.
PuTTY - Raspberry Pi
A short press is detected A short press is detected A short press is detected

Script chạy trong vòng lặp vô hạn liên tục cho đến khi bạn nhấn Ctrl + C trong terminal.

Cách Phát Hiện Nhấn Giữ

Có hai tình huống để nhận diện nhấn giữ:

  • Sự kiện nhấn giữ được nhận diện ngay sau khi button được thả
  • Sự kiện nhấn giữ được nhận diện trong khi button đang được giữ, thậm chí trước khi nó được thả.

Trong tình huống đầu tiên, thời lượng giữa sự kiện nhấn và thả được tính toán. Nếu thời lượng này vượt quá khoảng thời gian định trước, thì sự kiện nhấn giữ được nhận diện.

Trong tình huống thứ hai, khi button được nhấn, thời lượng nhấn được kiểm tra liên tục cho đến khi button được thả. Khi button được giữ, nếu thời lượng vượt quá thời gian định trước, sự kiện nhấn giữ được phát hiện.

Code Raspberry Pi để phát hiện nhấn giữ khi thả

Các Bước Nhanh

  • Tạo file script Python long_press_1.py và thêm code sau:
# Mã Raspberry Pi này được phát triển bởi newbiely.vn # Mã Raspberry Pi này được cung cấp để sử dụng công khai, không có ràng buộc. # Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: # https://newbiely.vn/tutorials/raspberry-pi/raspberry-pi-button-long-press-short-press import RPi.GPIO as GPIO import time BUTTON_PIN = 16 LONG_PRESS_TIME = 1.0 # 1 seconds DEBOUNCE_TIME = 0.1 # 100 milliseconds # Variables will change: prev_button_state = GPIO.LOW # the previous state from the input pin button_state = None # the current reading from the input pin press_time_start = 0 press_time_end = 0 # Set up GPIO and configure the pull-up resistor GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: # Read the state of the switch/button button_state = GPIO.input(BUTTON_PIN) # Perform debounce by waiting for DEBOUNCE_TIME time.sleep(DEBOUNCE_TIME) if prev_button_state == GPIO.HIGH and button_state == GPIO.LOW: # Button is pressed press_time_start = time.time() elif prev_button_state == GPIO.LOW and button_state == GPIO.HIGH: # Button is released press_time_end = time.time() press_duration = press_time_end - press_time_start if press_duration >= LONG_PRESS_TIME: print("A long press is detected") # Save the last state prev_button_state = button_state except KeyboardInterrupt: print("\nExiting the program.") GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực thi lệnh sau trong terminal:
python3 long_press_1.py
  • Nhấn button trong 2 giây rồi thả button.
  • Kiểm tra kết quả trên Terminal.
PuTTY - Raspberry Pi
A long press is detected

Sự kiện nhấn giữ chỉ được nhận diện khi button được thả.

Code Raspberry Pi để phát hiện nhấn giữ trong khi đang nhấn

Các Bước Nhanh

  • Tạo file script Python long_press_2.py và thêm code sau:
# Mã Raspberry Pi này được phát triển bởi newbiely.vn # Mã Raspberry Pi này được cung cấp để sử dụng công khai, không có ràng buộc. # Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: # https://newbiely.vn/tutorials/raspberry-pi/raspberry-pi-button-long-press-short-press import RPi.GPIO as GPIO import time BUTTON_PIN = 16 LONG_PRESS_TIME = 1.0 # 1000 milliseconds (1 second) # Variables will change: prev_button_state = GPIO.LOW # the previous state from the input pin button_state = None # the current reading from the input pin press_time_start = 0 is_pressing = False is_long_detected = False # Set up GPIO and configure the pull-up resistor GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: # Read the state of the switch/button button_state = GPIO.input(BUTTON_PIN) if prev_button_state == GPIO.HIGH and button_state == GPIO.LOW: # Button is pressed press_time_start = time.time() is_pressing = True is_long_detected = False elif prev_button_state == GPIO.LOW and button_state == GPIO.HIGH: # Button is released is_pressing = False if is_pressing and not is_long_detected: press_duration = time.time() - press_time_start if press_duration > LONG_PRESS_TIME: print("A long press is detected") is_long_detected = True # Save the last state prev_button_state = button_state except KeyboardInterrupt: print("\nExiting the program.") GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực thi lệnh sau trong terminal:
python3 long_press_2.py
  • Nhấn button và giữ trong vài giây rồi thả button.
  • Kiểm tra kết quả trên Serial Monitor.
PuTTY - Raspberry Pi
A long press is detected

Sự kiện nhấn giữ được phát hiện ngay cả khi button chưa được thả.

Cách Phát Hiện Cả Nhấn Giữ và Nhấn Nhanh

Các Bước Nhanh

  • Tạo file script Python long_short_press.py và thêm code sau:
# Mã Raspberry Pi này được phát triển bởi newbiely.vn # Mã Raspberry Pi này được cung cấp để sử dụng công khai, không có ràng buộc. # Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: # https://newbiely.vn/tutorials/raspberry-pi/raspberry-pi-button-long-press-short-press import RPi.GPIO as GPIO import time BUTTON_PIN = 16 SHORT_PRESS_TIME = 0.5 # 500 milliseconds LONG_PRESS_TIME = 1.0 # 1 seconds DEBOUNCE_TIME = 0.1 # 100 milliseconds # Variables will change: prev_button_state = GPIO.LOW # the previous state from the input pin button_state = None # the current reading from the input pin press_time_start = 0 press_time_end = 0 # Set up GPIO and configure the pull-up resistor GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: # Read the state of the switch/button button_state = GPIO.input(BUTTON_PIN) # Perform debounce by waiting for DEBOUNCE_TIME time.sleep(DEBOUNCE_TIME) if prev_button_state == GPIO.HIGH and button_state == GPIO.LOW: # Button is pressed press_time_start = time.time() elif prev_button_state == GPIO.LOW and button_state == GPIO.HIGH: # Button is released press_time_end = time.time() press_duration = press_time_end - press_time_start if press_duration < SHORT_PRESS_TIME: print("A short press is detected") elif press_duration >= LONG_PRESS_TIME: print("A long press is detected") # Save the last state prev_button_state = button_state except KeyboardInterrupt: print("\nExiting the program.") GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực thi lệnh sau trong terminal:
python3 long_short_press.py
  • Nhấn button, cả thời gian ngắn và dài.
  • Kiểm tra kết quả trên Terminal.

Video Tutorial

Việc sản xuất video tốn rất nhiều thời gian. Nếu video hướng dẫn hữu ích cho việc học của bạn, hãy đăng ký kênh YouTube để ủng hộ. Nếu nhu cầu đủ cao, chúng tôi sẽ cố gắng làm thêm nhiều video.

Tại Sao Cần Nhấn Giữ và Nhấn Nhanh

  • Để giảm thiểu số lượng button, một button có thể được sử dụng để thực hiện nhiều chức năng. Ví dụ, nhấn nhanh có thể được dùng để chuyển chế độ hoạt động, trong khi nhấn giữ có thể được dùng để tắt thiết bị.
  • Sử dụng nhấn giữ giúp ngăn chặn việc nhấn nhanh do vô tình. Ví dụ, một số thiết bị sử dụng button để khởi tạo reset về cài đặt gốc. Nếu button được nhấn không có ý định, nó có thể nguy hiểm. Để tránh điều này, thiết bị được thiết kế chỉ khởi tạo reset khi button được giữ trong một khoảng thời gian nhất định (ví dụ: 5 giây).