3.14. Làm mờ LED bằng PWM

Trang Tạo tín hiệu analog bằng PWM và bộ lọc RC đã sử dụng bộ lọc thông thấp RC để trích xuất điện áp DC từ tín hiệu PWM. Với LED, bộ lọc không cần thiết -- chính mắt người đã thực hiện việc lấy trung bình.

Khi một LED được bật và tắt nhanh hơn khoảng 60 Hz, hệ thống thị giác ngừng phân biệt các xung riêng lẻ và cảm nhận một độ sáng ổn định bằng với ánh sáng trung bình. Duty cycle 50% cho cảm giác khoảng nửa độ sáng; 25% là một phần tư; 10% thì tối.

Cách đấu dây giống như LED ngoài tĩnh trên Đầu ra GPIO -- một điện trở giới hạn dòng nối tiếp với LED, được tính toán theo quy tắc từ Kiến thức cơ bản về điện tử. Thay đổi chỉ nằm ở phần mềm: chân chạy như ngõ ra PWM thay vì Pin.OUT thông thường.

3.14.1. Chọn tần số

Đối với làm mờ LED, tần số PWM chỉ cần vượt qua ngưỡng nhấp nháy của mắt:

  • Dưới ~60 Hz, mắt người thấy trực tiếp các xung.

  • Dưới ~200 Hz, thị giác ngoại vi và chuyển động mắt nhanh vẫn có thể phát hiện nhấp nháy.

  • 1 kHz vượt thoải mái tất cả các mức đó và là giá trị mặc định thông thường.

Không có giới hạn trên quan trọng nào đối với LED nhỏ trên GPIO; từ 1 kHz đến 10 kHz đều giống nhau với mắt người.

3.14.2. Fading

Vòng lặp mờ dần / sáng dần quét duty cycle từ tắt đến bật hoàn toàn và trở lại, dừng ngắn ở mỗi bước:

import time
from machine import PWM, Pin

led = PWM(Pin("P7"), freq=1000, duty_u16=0)

while True:
    for d in range(0, 65535, 256):
        led.duty_u16(d)
        time.sleep_ms(5)
    for d in range(65535, 0, -256):
        led.duty_u16(d)
        time.sleep_ms(5)

Ở PWM 1 kHz và bước 5 ms, mắt người thấy hiệu ứng mờ mượt mà theo cả hai hướng, với độ sáng biểu kiến theo sát giá trị duty.

Độ sáng cảm nhận không hoàn toàn tuyến tính theo duty cycle -- phản ứng của mắt xấp xỉ theo luật bậc hai hoặc bậc ba -- vì vậy quét tuyến tính duty_u16 không trông như quét tuyến tính độ sáng. Để fade cảm giác mượt hơn, hãy tăng duty theo đường cong.

Một mẹo tiện lợi chỉ dùng số nguyên là tăng bộ đếm 8-bit và dùng bình phương của nó làm duty cycle. 255 × 255 = 65025 gần với toàn thang, nên việc quét bao phủ toàn bộ phạm vi:

import time
from machine import PWM, Pin

led = PWM(Pin("P7"), freq=1000, duty_u16=0)

while True:
    for step in range(256):
        led.duty_u16(step * step)   # 0..65025, roughly quadratic
        time.sleep_ms(5)
    for step in range(255, -1, -1):
        led.duty_u16(step * step)
        time.sleep_ms(5)

Hiệu ứng fade giờ cảm giác tương đối đều đặn về độ sáng biểu kiến từ tắt đến bật hoàn toàn.