Điều khiển đèn thông minh bằng cử chỉ với Arduino Uno và cảm biến PAJ7620U2

Công nghệ nhận diện cử chỉ mang lại trải nghiệm tương tác không chạm hiện đại và tiện lợi cho các hệ thống nhà thông minh. Bằng cách kết hợp Arduino Uno với cảm biến PAJ7620U2, bạn có thể tạo ra một hệ thống điều khiển đèn chỉ bằng các động tác tay như gạt trái, gạt phải hoặc xoay vòng. Dưới đây là hướng dẫn chi tiết từ khâu kết nối phần cứng đến tối ưu hóa mã nguồn để đạt độ ổn định cao nhất.

1. Chuẩn bị linh kiện và sơ đồ đấu nối

Cảm biến PAJ7620U2 sử dụng giao tiếp I2C và có khả năng nhận diện 9 loại cử chỉ khác nhau. Một lưu ý cực kỳ quan trọng là cảm biến này hoạt động ở điện áp 3.3V. Việc cấp nguồn 5V trực tiếp từ Arduino có thể gây hỏng chip cảm biến.

  • Arduino Uno R3 (hoặc các dòng tương đương).
  • Cảm biến cử chỉ PAJ7620U2.
  • Đèn LED (2 chiếc trở lên) kèm điện trở hạn dòng 220Ω.
  • Breadboard và dây nhảy.

Sơ đồ kết nối chi tiết:

Chân Arduino Uno Chân PAJ7620U2 Ghi chú
3.3V VCC Bắt buộc 3.3V để tránh hỏng thiết bị
GND GND Nối đất chung
A4 (SDA) SDA Dữ liệu I2C
A5 (SCL) SCL Xung đồng hồ I2C

Đối với đèn LED, bạn kết nối cực dương (Anode) vào các chân Digital (ví dụ D2, D3) thông qua điện trở, và cực âm (Cathode) nối vào GND.

2. Cấu hình thư viện và môi trường lập trình

Để bắt đầu, bạn cần cài đặt thư viện hỗ trợ cho cảm biến. Trong Arduino IDE, vào Sketch > Include Library > Manage Libraries, sau đó tìm kiếm từ khóa "PAJ7620" và cài đặt phiên bản từ nhà sản xuất (thường là Grove - Gesture Sensor).

Nếu hệ thống sử dụng nhiều thiết bị I2C cùng lúc, hãy đảm bảo địa chỉ của cảm biến (mặc định thường là 0x73) không bị xung đột với các module khác như màn hình OLED hay cảm biến nhiệt độ.

3. Xây dựng mã nguồn điều khiển

Dưới đây là cấu trúc mã nguồn được tối ưu hóa để điều khiển hai cụm đèn LED độc lập bằng cử chỉ gạt tay trái/phải và tắt/mở toàn bộ bằng cử chỉ đưa tay lên/xuống.


#include <Wire.h>
#include "paj7620.h"

const int PIN_LED_1 = 2;
const int PIN_LED_2 = 3;

void setup() {
  Serial.begin(115200);
  pinMode(PIN_LED_1, OUTPUT);
  pinMode(PIN_LED_2, OUTPUT);

  // Khởi tạo cảm biến
  uint8_t status = paj7620Init();
  if (status) {
    Serial.print("Lỗi khởi tạo cảm biến, mã lỗi: ");
    Serial.println(status);
    while(1); 
  }
  Serial.println("Hệ thống đã sẵn sàng!");
}

void loop() {
  uint8_t gesture_data = 0;
  paj7620ReadReg(0x43, 1, &gesture_data);

  if (gesture_data) {
    processGesture(gesture_data);
  }
  delay(50); // Tần số lấy mẫu phù hợp
}

void processGesture(uint8_t gesture) {
  switch (gesture) {
    case GES_LEFT_FLAG:
      Serial.println("Gạt trái: Bật/Tắt Đèn 1");
      digitalWrite(PIN_LED_1, !digitalRead(PIN_LED_1));
      break;
    
    case GES_RIGHT_FLAG:
      Serial.println("Gạt phải: Bật/Tắt Đèn 2");
      digitalWrite(PIN_LED_2, !digitalRead(PIN_LED_2));
      break;

    case GES_UP_FLAG:
      Serial.println("Đưa tay lên: Bật tất cả");
      digitalWrite(PIN_LED_1, HIGH);
      digitalWrite(PIN_LED_2, HIGH);
      break;

    case GES_DOWN_FLAG:
      Serial.println("Hạ tay xuống: Tắt tất cả");
      digitalWrite(PIN_LED_1, LOW);
      digitalWrite(PIN_LED_2, LOW);
      break;

    default:
      break;
  }
}

4. Kỹ thuật chống nhiễu và tinh chỉnh độ nhạy

Trong môi trường thực tế, cảm biến có thể bị nhiễu do ánh sáng mạnh hoặc các chuyển động vô ý. Để khắc phục, chúng ta cần bổ sung cơ chế kiểm soát thời gian phản hồi (debounce).


unsigned long lastActionTime = 0;
const int ACTION_DELAY = 500; // Khoảng cách tối thiểu giữa 2 lần nhận diện (ms)

void loop() {
  uint8_t gesture_val = 0;
  paj7620ReadReg(0x43, 1, &gesture_val);

  if (gesture_val && (millis() - lastActionTime > ACTION_DELAY)) {
    processGesture(gesture_val);
    lastActionTime = millis();
  }
}

Ngoài ra, bạn có thể điều chỉnh độ nhạy của cảm biến bằng cách thay đổi giá trị trong các thanh ghi nội bộ. Cảm biến PAJ7620U2 chia làm hai "Bank" bộ nhớ. Bank 1 chứa các thông số về ngưỡng nhận diện (threshold). Việc giảm ngưỡng này sẽ giúp cảm biến nhạy hơn nhưng dễ bị nhận diện sai.

5. Mở rộng tính năng: Điều chỉnh độ sáng (Dimming)

Thay vì chỉ bật/tắt, chúng ta có thể sử dụng cử chỉ xoay (Clockwise/Counter-Clockwise) để điều chỉnh cường độ sáng của đèn LED thông qua PWM (Pulse Width Modulation).


int currentBrightness = 128;

void adjustBrightness(bool increase) {
  if (increase) {
    currentBrightness = min(currentBrightness + 25, 255);
  } else {
    currentBrightness = max(currentBrightness - 25, 0);
  }
  analogWrite(PIN_LED_1, currentBrightness);
  Serial.print("Độ sáng hiện tại: ");
  Serial.println(currentBrightness);
}

// Trong hàm processGesture:
// case GES_CLOCKWISE_FLAG: adjustBrightness(true); break;
// case GES_COUNT_CLOCKWISE_FLAG: adjustBrightness(false); break;

6. Những vấn đề thường gặp và cách xử lý

  • Cảm biến không phản hồi: Kiểm tra lại dây SDA/SCL, đảm bảo đã kết nối đúng chân A4/A5 trên Uno. Thử sử dụng các điện trở kéo lên (pull-up resistors) 4.7kΩ nếu dây dẫn dài.
  • Nhận diện sai cử chỉ: Đảm bảo tay cách cảm biến từ 5cm đến 15cm. Tốc độ di chuyển tay cần đều đặn, không quá nhanh hoặc quá chậm.
  • Đèn LED bị nhấp nháy: Kiểm tra lại nguồn cấp cho Arduino, đảm bảo dòng điện ổn định khi bật nhiều LED cùng lúc.

Thẻ: Arduino PAJ7620U2 gesture-recognition I2C embedded-systems

Đăng vào ngày 1 tháng 9 lúc 05:49