Raspberry Pi + Relay: Điều khiển thiết bị điện qua GPIO
Cơ bản1/8/2026- Tác giả: IoTlabs Maker

Raspberry Pi + Relay: Điều khiển thiết bị điện qua GPIO

Dùng relay 1 kênh 5V điều khiển đóng/ngắt thiết bị điện (đèn, quạt) qua GPIO Raspberry Pi, kèm cơ chế watchdog an toàn tự ngắt khi bật quá lâu.

Raspberry PiGPIORelayPythonRPi.GPIODieu khien thiet bi dien

Dự án nhập môn GPIO thứ ba: dùng module relay 1 kênh để đóng/ngắt một thiết bị điện (đèn, quạt, ổ cắm) bằng tín hiệu digital từ Raspberry Pi.

Bạn sẽ học nguyên lý relay active-low, cách điều khiển an toàn, và xây dựng một dịch vụ điều khiển có lịch bật/tắt tự động cùng cơ chế watchdog tự ngắt để tránh thiết bị bị bật "quên" quá lâu, một yêu cầu an toàn bắt buộc khi điều khiển tải điện thực tế.

Hướng dẫn chi tiết

Hướng dẫn dùng relay 1 kênh 5V để đóng/ngắt tải DC 5V/12V (đèn LED, quạt DC) qua GPIO Raspberry Pi, an toàn tuyệt đối cho người mới, kèm 3 mẫu code Python và cơ chế watchdog tự ngắt.

1. Giới thiệu

Module relay là cách phổ biến nhất để một vi điều khiển tín hiệu thấp (3.3V/5V, vài mA) điều khiển đóng/ngắt một tải công suất lớn hơn — nhờ cơ chế đóng/ngắt bằng cơ khí (cuộn dây nam châm điện hút tiếp điểm) và cách ly quang (opto-isolator) bảo vệ GPIO.

Relay module phổ biến trên thị trường thường là loại active-low: chân IN ở mức LOW (0V) thì relay đóng (kích hoạt), mức HIGH (3.3V/5V) thì relay mở (ngắt) — ngược với trực giác "HIGH = bật" thông thường, nên rất dễ nhầm khi mới học.

Bài này dùng tải DC 5V/12V (đèn LED 12V, quạt DC nhỏ, bơm mini 5V) làm chuẩn để bạn thực hành an toàn tuyệt đối, không rủi ro điện giật khi mới học GPIO/relay.

2. Linh kiện cần có

Linh kiệnSố lượngGiá tham khảo
Raspberry Pi 4 Model B (đã cài Raspberry Pi OS) hoặc các phiên bản khác1~1.500.000đ
Relay Module 1 kênh 5V (có opto-isolator)1~20.000đ
Dây jumper (male-female)3 sợi~5.000đ
Tải DC để test: đèn LED 12V/dải LED 12V, hoặc quạt DC nhỏ (kèm nguồn 12V/5V riêng cho tải)1~30.000–50.000đ

3. Sơ đồ kết nối

Relay ModuleRaspberry Pi 4
VCC5V (Pin 2)
GNDGND
INGPIO18 (Pin 12) — active-low: LOW = relay đóng (BẬT)
COM / NOMắc nối tiếp trên dây dương (+) của tải DC 12V/5V, nguồn tải lấy từ adapter riêng — không lấy từ RPi

An toàn: tải DC 12V/5V không gây nguy hiểm điện giật, có thể chạm tay vào dây khi đang test. Vẫn nên tắt nguồn tải khi đấu/tháo dây để tránh phát sinh tia lửa nhỏ hoặc chập chân relay.

4. Code ví dụ #1 — Bật/tắt relay cơ bản

Đóng/mở relay theo chu kỳ 3 giây để kiểm tra kết nối hoạt động đúng, đồng thời minh hoạ hàm tiện ích relay_on()/relay_off() đóng gói logic active-low.

#!/usr/bin/env python3
"""
Raspberry Pi + Relay 1 kenh - Dieu khien tai DC (den LED 12V, quat DC...) qua GPIO

Wiring:
  Relay VCC -> RPi 5V
  Relay GND -> RPi GND
  Relay IN  -> RPi GPIO18 (active-low: LOW = dong relay = BAT)
  Relay COM/NO -> day duong (+) cua tai DC, nguon tai lay tu adapter rieng
"""
import RPi.GPIO as GPIO
import time

RELAY_PIN = 18
ACTIVE_LOW = True  # module relay pho bien la active-low


def relay_on():
    GPIO.output(RELAY_PIN, GPIO.LOW if ACTIVE_LOW else GPIO.HIGH)


def relay_off():
    GPIO.output(RELAY_PIN, GPIO.HIGH if ACTIVE_LOW else GPIO.LOW)


def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(RELAY_PIN, GPIO.OUT)
    relay_off()
    print("[BOOT] Relay controller ready. GPIO18 active-low.")


def main():
    setup()
    try:
        while True:
            print("Relay: BAT")
            relay_on()
            time.sleep(3)
            print("Relay: TAT")
            relay_off()
            time.sleep(3)
    except KeyboardInterrupt:
        print("\n[EXIT] Dung boi nguoi dung")
    finally:
        relay_off()
        GPIO.cleanup()


if __name__ == "__main__":
    main()

5. Code ví dụ #2 — Điều khiển đèn theo lịch giờ tự động

Ứng dụng thực tế phổ biến: tự động bật đèn LED 12V vào buổi tối (18h) và tắt vào sáng sớm (6h) mà không cần can thiệp thủ công.

#!/usr/bin/env python3
"""
Raspberry Pi + Relay - Dieu khien den LED 12V theo lich gio tu dong
"""
import RPi.GPIO as GPIO
import time
from datetime import datetime

RELAY_PIN = 18
ON_HOUR = 18   # 18:00 bat den
OFF_HOUR = 6   # 06:00 tat den
CHECK_INTERVAL_S = 30


def relay_on():
    GPIO.output(RELAY_PIN, GPIO.LOW)


def relay_off():
    GPIO.output(RELAY_PIN, GPIO.HIGH)


def should_be_on(now=None):
    now = now or datetime.now()
    h = now.hour
    if ON_HOUR > OFF_HOUR:
        return h >= ON_HOUR or h < OFF_HOUR
    return ON_HOUR <= h < OFF_HOUR


def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(RELAY_PIN, GPIO.OUT)
    relay_off()
    print(f"[BOOT] Lich chieu sang tu dong: BAT {ON_HOUR}:00 -> TAT {OFF_HOUR}:00")


def main():
    setup()
    current_state = None
    try:
        while True:
            want_on = should_be_on()
            if want_on != current_state:
                if want_on:
                    relay_on()
                    print(f"[{datetime.now():%H:%M:%S}] Den: BAT (theo lich)")
                else:
                    relay_off()
                    print(f"[{datetime.now():%H:%M:%S}] Den: TAT (theo lich)")
                current_state = want_on
            time.sleep(CHECK_INTERVAL_S)
    except KeyboardInterrupt:
        print("\n[EXIT] Dung boi nguoi dung")
    finally:
        relay_off()
        GPIO.cleanup()


if __name__ == "__main__":
    main()

6. Code ví dụ #3 — Ứng dụng thực tế: dịch vụ điều khiển có watchdog an toàn

Phiên bản gần với triển khai thực tế nhất: tích hợp watchdog tự động ngắt nếu tải bị bật quá lâu (ví dụ 30 phút) — bảo vệ khỏi tình huống quên tắt gây quá nhiệt/lãng phí điện.

#!/usr/bin/env python3
"""
Raspberry Pi + Relay - Dich vu dieu khien an toan: watchdog tu ngat sau
thoi gian toi da, tranh tai DC bi bat "quen" gay qua nhiet.
"""
import RPi.GPIO as GPIO
import time
import json

RELAY_PIN = 18
MAX_ON_DURATION_S = 60 * 30  # 30 phut - tu dong tat neu bat qua lau
TELEMETRY_INTERVAL_S = 5.0

state = {"on": False, "on_since": None}


def relay_on():
    GPIO.output(RELAY_PIN, GPIO.LOW)
    state["on"] = True
    state["on_since"] = time.time()


def relay_off():
    GPIO.output(RELAY_PIN, GPIO.HIGH)
    state["on"] = False
    state["on_since"] = None


def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(RELAY_PIN, GPIO.OUT)
    relay_off()
    print(f"[BOOT] Relay safety service ready. Watchdog max-on = {MAX_ON_DURATION_S}s")


def toggle():
    if state["on"]:
        relay_off()
        print("Relay: TAT (toggle)")
    else:
        relay_on()
        print("Relay: BAT (toggle)")


def main():
    setup()
    last_telemetry = 0.0
    last_toggle_demo = time.time()

    try:
        while True:
            now = time.time()

            if state["on"] and state["on_since"] is not None:
                if now - state["on_since"] > MAX_ON_DURATION_S:
                    print("[WARN] Watchdog: qua thoi gian BAT toi da -> tu dong TAT")
                    relay_off()

            if now - last_toggle_demo > 10:
                toggle()
                last_toggle_demo = now

            if now - last_telemetry >= TELEMETRY_INTERVAL_S:
                telemetry = {
                    "actuator": "relay_1ch",
                    "on": state["on"],
                    "on_duration_s": round(now - state["on_since"], 1) if state["on_since"] else 0,
                }
                print(json.dumps(telemetry))
                last_telemetry = now

            time.sleep(0.5)
    except KeyboardInterrupt:
        print("\n[EXIT] Dung boi nguoi dung")
    finally:
        relay_off()
        GPIO.cleanup()


if __name__ == "__main__":
    main()

7. Lỗi thường gặp

LỗiNguyên nhânCách sửa
Relay kêu "tách" nhưng đèn không sáng dù đã nối đúng NO/COMĐấu nhầm dây tải vào NC (Normally Closed) thay vì NO (Normally Open)Kiểm tra lại: dùng NO nếu muốn "tắt mặc định, bật khi kích hoạt"
Relay tự kích hoạt (kêu tách) ngay khi Raspberry Pi vừa khởi độngChân GPIO mặc định ở trạng thái floating trong lúc boot LinuxKhông có cách khắc phục hoàn toàn bằng phần mềm; cân nhắc relay module có chốt cơ hoặc mạch trễ khởi động phần cứng
Code gọi relay_on() nhưng relay không đóngNhầm active-low: nghĩ HIGH = bật nhưng module là active-lowKiểm tra thông số module (đa số ghi "Low Level Trigger" trên board)
Chương trình dừng đột ngột nhưng relay vẫn đang đóngCrash/kill process không qua try/finallyLuôn dùng cấu trúc try/finally như code mẫu

8. Tổng kết

Qua dự án này, bạn đã nắm được cách dùng relay để điều khiển tải DC an toàn từ GPIO điện áp thấp, hiểu logic active-low thường gặp trên relay module giá rẻ, và các nguyên tắc an toàn: mặc định tắt khi khởi động, watchdog tự ngắt.

Ba mẫu code từ điều khiển cơ bản → lịch giờ tự động → dịch vụ có watchdog cho thấy lộ trình nâng cấp từ demo học tập lên một thành phần điều khiển đáng tin cậy hơn. Hướng mở rộng tiếp theo: ghép relay với cảm biến (ánh sáng, nhiệt độ) để tự động hoá theo điều kiện thực tế, hoặc điều khiển qua web/MQTT từ xa.