Xây dựng hệ thống AIoT điều khiển LED bằng YOLOv8 và ESP32 



1. Ý tưởng chính


Nếu bạn từng nghĩ đến việc bật đèn mà không cần chạm vào công tắc thì đề tài này sinh ra là dành cho bạn đó. Mình xây dựng một hệ thống AIoT cho phép điều khiển LED chỉ bằng cử chỉ bàn tay trước camera. Không cần nút bấm, không cần chạm, chỉ cần giơ tay lên là đèn hiểu ý bạn.

Ý tưởng nghe có vẻ “tương lai” nhưng cách làm lại khá rõ ràng. Phần thông minh của hệ thống nằm ở AI – mình sử dụng mô hình YOLOv8 để nhận diện bàn tay và phân loại cử chỉ theo thời gian thực. Camera sẽ liên tục ghi lại hình ảnh, sau đó mô hình xử lý từng khung hình để xem bạn đang ra dấu gì. Ví dụ, một cử chỉ có thể tương ứng với bật đèn, cử chỉ khác thì tắt đèn. Mọi thứ diễn ra gần như ngay lập tức nên cảm giác rất “đã”.

Sau khi AI hiểu được cử chỉ của bạn, nhiệm vụ còn lại thuộc về phần IoT. Máy tính sẽ gửi lệnh xuống ESP32 thông qua giao tiếp Serial, và ESP32 sẽ điều khiển LED bật hoặc tắt theo đúng lệnh nhận được. Nhìn thì đơn giản, nhưng khi kết hợp lại, bạn sẽ có một hệ thống điều khiển không chạm cực kỳ thú vị.

Đây là một ví dụ rất hay về việc kết hợp AI và IoT trong thực tế. Từ một chiếc LED nhỏ, bạn hoàn toàn có thể mở rộng thành điều khiển quạt, cửa tự động hay cả hệ thống nhà thông minh. Nếu bạn đang học về AI, Computer Vision hay IoT, mình tin đây là một project vừa vui vừa học được rất nhiều thứ.



2. Các giai đoạn xử lý 

Hệ thống chia thành 3 giai đoạn chính: 

Giai đoạn 1: Thu thập dữ liệu, gán nhãn và xử lý tập dataset trên trên phần mềm roboflow

Giai đoạn 2: Sử dung google colab để train mô hình AI YOLOv8

Giai đoạn 3: Nhận diện realtime & gửi lệnh (sử dụng VS code để viết mã)

Giai đoạn 4: Viết mã cho ESP32 để nhận dữ liệu qua serial và điều khiển LED


2.1 Thu thập dữ liệu, gán nhãn và xử lý tập datashet trên trên phần mềm roboflow

- Đầu tiên ta thu thập dữ liệu bằng cách chụp ảnh qua webcam qua laptop nhé (Tầm > 200 ảnh là ta có thể nhận diện được rồi).

- Tiếp ta vào trang chủ roboflow như hình dưới đây



Các bạn nhớ đăng kí và đăng nhập tài khoản để sử dụng nhé

- Sau khi đã đăng nhập ta nhấn vào thư mục “project” để tạo project nhé, sau đó chọn new project ở góc phải màn hình:



Chọn các option như sau:

Điền project Name, anotion group đặc biệt ở phần tool nhớ chọn Traditonal nhé

Phần Project Type mình sẽ chọn Object Detection 

Sau đó nhấn Create Public Project



  • Tiếp ta vào phần upload data để upload các ảnh ta đã chụp qua webcam sau đó nhấn Save and continue



  • Sau đó sẽ chuyển qua annotate chon Label Myself

Sau đó ta sẽ chuyển đến phần gán nhãn 



Góc bên phải là các Tool để chúng ta có thể gán nhãn mình khuyên nên dùng Polygon Tool vì nó sẽ gán nhãn chuẩn nhất không bị thừa các khoảng trắng khác

Chọn label rồi ấn save


  • Sau khi đã gán nhãn xong tất cả các ảnh thì ta sẽ nhấn dấu tích (Add Images to Dataset) trên cùng



  • Tiếp ở phần Method ta sẽ chọn Split Images Between Train/Valid/Test



Chọn phần trăm các tập train/valid/test sau đó nhấn Add images



  • Sau đó ở phần Versions ta chọn Download dataset (trên cùng góc bên phải


Chọn tiếp theo mình nhé

Bấm continue là sẽ có file .zip tới máy bạn



2.2 Sử dung google colab để train mô hình AI YOLOv8



Tương tự bạn có thể đăng nhập bằng gmail của bạn

Chọn open colab rồi nhấn sổ tay mới




Chọn thời gian chạy và nhấn Thay đổi loại thời gian chạy


Chọn GPU T4 và bấm lưu



  • Rồi giờ ta đến phần code train AI nhé

Bước 1: Tải thư viện YOLOv8

Mã: !pip install ultralytics



Sau đó test nhanh:

Mã: from ultralytics import YOLO

        YOLO("yolov8n.pt")

Đoan code trên dùng để 

from ultralytics import YOLO → gọi YOLO vào chương trình

YOLO("yolov8n.pt") → nạp mô hình YOLOv8 đã train sẵn



Bước 2: Upload dataset zip và giải nén

Mã: from google.colab import files

        files.upload()




Nhấn chọn tệp và upload file .zip vừa tải ở bước 2.1, tiếp ta giải nén

Mã: !unzip AI_train.zip -d hand_dataset


Kiểm tra lại:

Mã: !cat hand_dataset/data.yaml



Bước 3: Train YOLO

Mã: from ultralytics import YOLO


model = YOLO("yolov8n.pt")


model.train(

    data="/content/hand_dataset/data.yaml",

    epochs=50,

    imgsz=640,

    batch=16,

    name="hand_yolo"

)

Rồi đợi nó chạy xong nhé, sau đó chạy mã còn lại để nhận kết quả train

Mã: !ls runs/detect



Mã: model = YOLO("runs/detect/train/weights/best.pt")

        model.predict(source="hand_dataset/valid/images", conf=0.25,  save=True)

Sau đó ta tải file best.pt về máy nhé.




2.3 Nhận diện realtime & gửi lệnh (sử dụng VS code để viết mã)

Đầu tiên, bạn cần cài tạo thư mục mới trong VS code mình đặt tên là “AI_hand”

Sau đó nhớ cài python nhé bạn có thể lên youtube xem cách cài python

Sau khi cài xong, mở VS Code → Terminal (Ctrl + ). Nếu bạn có dùng **venv** thì nhớ kích hoạt trước (.\venv\Scripts\activatetrên Windows). 



Tiếp theo, cập nhật pip bằng lệnh python -m pip install --upgrade pip. 



Sau đó cài các thư viện cần thiết cho project nhận diện tay + kết nối ESP32 bằng cách chạy: pip install ultralytics opencv-python pyserial numpy (Trong đó: “ultralytics” dùng cho YOLOv8, “opencv-python” để đọc camera và hiển thị ảnh, “pyserial” để giao tiếp ESP32 qua Serial , “numpy” là thư viện nền YOLO cần). 



Sau khi cài xong, bạn kiểm tra nhanh bằng cách mở Python và chạy from ultralytics import YOLO` xem có lỗi không. 

Cuối cùng, đảm bảo VS Code đang dùng đúng Python interpreter (Ctrl + Shift + P → “Python: Select Interpreter” → chọn đúng Python hoặc venv bạn vừa cài). 



  • Tiếp theo chúng ta sẽ viết code chạy chương trình:

Đầu tiên, ta thêm file best.pt vào thư mục của mình tạo và thêm file detech_hand.py



Tiếp, ta viết code cho detech_hand.py

Mã: 

from ultralytics import YOLO

import cv2

import serial

import time


model = YOLO("best.pt")

cap = cv2.VideoCapture(0)


ser = serial.Serial('COM3', 115200, timeout=1)

time.sleep(2)


hand_count = 0

nohand_count = 0


THRESHOLD = 5

led_state = 0 # 0 = OFF, 1 = ON


while True:

    ret, frame = cap.read()

    if not ret:

        break


    results = model(frame, conf=0.3)

    annotated = results[0].plot()

    cv2.imshow("Hand Detection", annotated)


    # Có tay?

    detected = results[0].boxes is not None and len(results[0].boxes) > 0


    if detected:

        hand_count += 1

        nohand_count = 0

    else:

        nohand_count += 1

        hand_count = 0


    # ---- BẬT LED ----

    if hand_count >= THRESHOLD and led_state == 0:

        ser.write(b'1')

        led_state = 1

        print("LED ON")


    # ---- TẮT LED ----

    if nohand_count >= THRESHOLD and led_state == 1:

        ser.write(b'0')

        led_state = 0

        print("LED OFF")


    if cv2.waitKey(1) & 0xFF == 27:

        break


cap.release()

cv2.destroyAllWindows()

ser.close()


Tiếp theo, chạy mã  python detect_hand.py ở terminal


Bước 4: Viết code cho esp32

Cách chạy và tạo chương trình bạn có thể xem ở các bài hướng dẫn trước đó ở seri arduino

Mã: 

#define LED_PIN 2


void setup() {

  Serial.begin(115200);

  pinMode(LED_PIN, OUTPUT);

}


void loop() {

  if (Serial.available()) {

    char c = Serial.read();

    if (c == '1') digitalWrite(LED_PIN, HIGH);

    if (c == '0') digitalWrite(LED_PIN, LOW);

  }

}



Nạp code và chạy chương trình





2.5 Kết quả


Nếu nhận diện được tay đèn sẽ sáng không thì đèn không sáng