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


# Load model
model = YOLO("best.pt")


# Camera
cap = cv2.VideoCapture(0)


# Serial
ser = serial.Serial('COM3', 115200, timeout=1)
time.sleep(2)


# Variables
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


    # Detect
    results = model(frame, conf=0.3)
    annotated = results[0].plot()


    cv2.imshow("Hand Detection", annotated)


    # Check detection
    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


    # ---- TURN ON LED ----
    if hand_count >= THRESHOLD and led_state == 0:
        ser.write(b'1')
        led_state = 1
        print("LED ON")


    # ---- TURN OFF LED ----
    if nohand_count >= THRESHOLD and led_state == 1:
        ser.write(b'0')
        led_state = 0
        print("LED OFF")


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


# Cleanup
cap.release()
cv2.destroyAllWindows()
ser.close()


Tiếp theo, chạy mã ở terminal

python detect_hand.py 


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 vào ESP32


2.4 Kết quả


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