Raspberry Pi Button Debounce (Chống Nhiễu Nút Nhấn)

Khi một nút nhấn được bấm hoặc thả ra, hoặc khi một công tắc được chuyển đổi, người mới bắt đầu thường cho rằng trạng thái của nó đơn giản chỉ thay đổi từ LOW sang HIGH hoặc HIGH sang LOW. Trên thực tế, điều này không phải như vậy. Do các đặc tính cơ học và vật lý, trạng thái của nút nhấn (hoặc công tắc) có thể được chuyển đổi giữa LOW HIGH nhiều lần. Hiện tượng này được gọi là chattering (nhiễu tiếp xúc). Chattering có thể khiến một lần nhấn được đọc thành nhiều lần nhấn, dẫn đến trục trặc trong một số ứng dụng.

chattering phenomenon

Phương pháp để ngăn ngừa vấn đề này được gọi là debouncing hoặc debounce (chống nhiễu). Hướng dẫn này sẽ chỉ bạn cách thực hiện khi sử dụng nút nhấn với Raspberry Pi. Chúng ta sẽ học qua các bước sau:

Linh Kiện Cần Thiết

1×Raspberry Pi 5
1×Nút Nhấn Gắn Breadboard Có Nắp
1×Bộ Kit Nút Nhấn Gắn Breadboard
1×Nút Nhấn Gắn Panel
1×mô-đun nút nhấn
1×breadboard (Bo Mạch Thí Nghiệm)
1×Dây 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ề Nút Nhấn (Button)

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

Sơ Đồ Kết Nối

Raspberry Pi nút nhấn sơ đồ đấu dây

This image is created using Fritzing. Click to enlarge image

Hãy cùng xem xét sự khác biệt giữa mã Raspberry Pi CÓ và KHÔNG CÓ debounce, cũng như hành vi tương ứng của chúng.

Đọc Button Không Có Debounce

Trước khi hiểu về debouncing, hãy xem mã không có nó và quan sát hành vi của nó.

Các Bước Thực Hiện

  • Đảm bảo bạn đã cài đặt Raspbian hoặc bất kỳ hệ điều hành tương thích Raspberry Pi nào khác trên Pi của mình.
  • Đảm bảo Raspberry Pi của bạn được kết nối với cùng mạng cục bộ như 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 tích hợp 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 nó bằng lệnh sau:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Tạo file script Python button_without_debounce.py và thêm đoạn mã 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-debounce import RPi.GPIO as GPIO import time # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Define the GPIO pin for your button BUTTON_PIN = 16 # Set the initial state and pull-up resistor for the button GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Initialize the button state button_state = GPIO.input(BUTTON_PIN) try: # Main loop while True: # Read the current button state current_state = GPIO.input(BUTTON_PIN) # Check if the button state has changed and print when it does if current_state != button_state: if current_state == GPIO.HIGH: print("Button released") else: print("Button pressed") button_state = current_state time.sleep(0.1) # Adjust the sleep time as needed except KeyboardInterrupt: # Clean up GPIO on exit GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực hiện lệnh sau trong terminal:
python3 button_without_debounce.py

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.

  • Nhấn và giữ nút nhấn trong vài giây, sau đó thả ra.
  • Kiểm tra kết quả trong Terminal.
PuTTY - Raspberry Pi
Button pressed Button pressed Button pressed Button released Button released

Đôi khi, bạn chỉ nhấn và thả nút một lần. Tuy nhiên, Raspberry Pi nhận ra nó như nhiều lần nhấn và thả. Đây là hiện tượng chattering được đề cập ở đầu hướng dẫn. Hãy xem cách khắc phục điều này trong phần tiếp theo.

Đọc Button Có Debounce

Các Bước Thực Hiện

  • Tạo file script Python button_debounce.py và thêm đoạn mã 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-debounce import RPi.GPIO as GPIO # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Define the GPIO pin for your button BUTTON_PIN = 16 # Define debounce time in milliseconds DEBOUNCE_TIME_MS = 200 # 200 milliseconds # Set the initial state and pull-up resistor for the button GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Initialize the button state and previous state button_state = GPIO.input(BUTTON_PIN) prev_button_state = button_state # Define a function to handle button presses def button_callback(channel): global button_state button_state = GPIO.input(BUTTON_PIN) # Add an event listener for the button press GPIO.add_event_detect(BUTTON_PIN, GPIO.BOTH, callback=button_callback, bouncetime=DEBOUNCE_TIME_MS) try: # Main loop while True: # Check if the button state has changed if button_state != prev_button_state: if button_state == GPIO.HIGH: print("Button released") else: print("Button pressed") prev_button_state = button_state except KeyboardInterrupt: # Clean up GPIO on exit GPIO.cleanup()
  • Lưu file và chạy script Python bằng cách thực hiện lệnh sau trong terminal:
python3 button_debounce.py
  • Nhấn và giữ nút nhấn trong vài giây, sau đó thả ra.
  • Kiểm tra kết quả trong terminal.
PuTTY - Raspberry Pi
Button pressed Button released

Như bạn có thể quan sát thấy, bạn chỉ nhấn và thả nút một lần. Raspberry Pi phát hiện nó như một lần nhấn và thả duy nhất, do đó loại bỏ mọi nhiễu không cần thiết.

Raspberry Pi Button Debounce Cho Nhiều Nút Nhấn

# 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-debounce import RPi.GPIO as GPIO # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Define the GPIO pins for your buttons BUTTON_PIN_1 = 14 BUTTON_PIN_2 = 15 BUTTON_PIN_3 = 18 # Define debounce time in milliseconds DEBOUNCE_TIME_MS = 200 # 200 milliseconds # Set the initial state and pull-up resistor for the buttons GPIO.setup(BUTTON_PIN_1, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUTTON_PIN_2, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUTTON_PIN_3, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Initialize the button states and previous states for all buttons button_state_1 = GPIO.input(BUTTON_PIN_1) button_state_2 = GPIO.input(BUTTON_PIN_2) button_state_3 = GPIO.input(BUTTON_PIN_3) prev_button_state_1 = button_state_1 prev_button_state_2 = button_state_2 prev_button_state_3 = button_state_3 # Define a function to handle button presses def button_callback_1(channel): global button_state_1 button_state_1 = GPIO.input(BUTTON_PIN_1) def button_callback_2(channel): global button_state_2 button_state_2 = GPIO.input(BUTTON_PIN_2) def button_callback_3(channel): global button_state_3 button_state_3 = GPIO.input(BUTTON_PIN_3) # Add event listeners for the buttons GPIO.add_event_detect(BUTTON_PIN_1, GPIO.BOTH, callback=button_callback_1, bouncetime=DEBOUNCE_TIME_MS) GPIO.add_event_detect(BUTTON_PIN_2, GPIO.BOTH, callback=button_callback_2, bouncetime=DEBOUNCE_TIME_MS) GPIO.add_event_detect(BUTTON_PIN_3, GPIO.BOTH, callback=button_callback_3, bouncetime=DEBOUNCE_TIME_MS) try: # Main loop while True: # Check if the button states have changed and print when they do if button_state_1 != prev_button_state_1: if button_state_1 == GPIO.HIGH: print("Button 1 released") else: print("Button 1 pressed") prev_button_state_1 = button_state_1 if button_state_2 != prev_button_state_2: if button_state_2 == GPIO.HIGH: print("Button 2 released") else: print("Button 2 pressed") prev_button_state_2 = button_state_2 if button_state_3 != prev_button_state_3: if button_state_3 == GPIO.HIGH: print("Button 3 released") else: print("Button 3 pressed") prev_button_state_3 = button_state_3 except KeyboardInterrupt: # Clean up GPIO on exit GPIO.cleanup()

Sơ đồ minh họa kết nối dây cho đoạn mã được đề cập:

Raspberry Pi nút nhấn thư viện sơ đồ đấu dây

This image is created using Fritzing. Click to enlarge image

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.