Lab.Vatli365
← Cấp độ 1 · Điều khiển và tín hiệu số

Bài 3 · Công nghệ · STEM

Đèn giao thông ba màu
ba đèn, một thứ tự, và khái niệm trạng thái

Bài đầu tiên mà chương trình phải nhớ mình đang ở đâu trong một chuỗi việc. Ba con LED biến vòng lặp thành một chu trình có trước có sau — đúng thứ mọi hệ điều khiển tự động đều làm.

Thời lượng
1 tiết (45 phút)
Chi phí một nhóm
≈ 4 nghìn đồng (chưa tính bo)
Cấp độ
1 / 12
Trạng thái
Đã có phần cứng, đang hoàn thiện
01

Mục tiêu và yêu cầu cần đạt

Bài 1 có một đèn. Bài 2 có một đèn nghe lời ngón tay. Bài này có ba đèn phải thay phiên nhau theo đúng một thứ tự, và không bao giờ được sáng cùng lúc. Nghe thì đơn giản, nhưng nó là bài đầu tiên học sinh phải thiết kế một chu trình chứ không chỉ viết vài dòng lệnh.

Sau bài này học sinh làm được

  • Nối ba LED vào ba chân GPIO khác nhau, mỗi LED một điện trở riêng.
  • Viết được chuỗi lệnh tuần tự thể hiện đúng một chu trình đèn giao thông.
  • Giải thích vì sao phải tắt đèn cũ trước khi bật đèn mới.
  • Tính được chu kỳ tổng của cột đèn từ ba khoảng thời gian thành phần.
  • Đề xuất được thời lượng hợp lí cho một ngã tư có người đi bộ.
Gắn với chương trình
  • Công nghệ 12 — mạch nội dung Vi điều khiển: điều khiển nhiều thiết bị đầu ra theo một trình tự.
  • Tin học 10 — thuật toán tuần tự, cấu trúc lặp, và cách mô tả thuật toán trước khi viết chương trình.

Trích nguyên văn yêu cầu cần đạt từ Phụ lục Thông tư 32/2018 trước khi đưa vào kế hoạch bài dạy.

02

Lí thuyết

Ba chân độc lập, ba lệnh độc lập

Hỏi cả lớp trước khi cắm dây: một cột đèn giao thông có mấy trạng thái? Ba — và chương trình lúc nào cũng phải ở đúng một trong ba, không được lơ lửng ở giữa.

Mỗi chân GPIO bật tắt hoàn toàn độc lập. Không có gì ràng buộc chúng với nhau: chương trình bật cả ba thì cả ba cùng sáng, và cột đèn thành vô nghĩa.

Nghĩa là ràng buộc "mỗi lúc chỉ một đèn" không nằm ở phần cứng, mà do chương trình tự đặt ra và tự giữ. Ý này lặp lại ở mọi hệ điều khiển về sau: máy không tự biết cái gì hợp lí, người lập trình phải viết ra điều đó.

Vì sao mỗi LED cần một điện trở riêng

Ba LED đều về chung GND, vậy cắm một điện trở ở dây GND chung cho gọn được không?

Được về mạch, sai về dòng. Một đèn sáng thì dòng qua điện trở là dòng của một đèn; hai đèn cùng sáng thì hai dòng cộng lại, điện áp rơi trên điện trở tăng, cả hai đèn tối đi. Độ sáng phụ thuộc có mấy đèn đang sáng — hành vi khó hiểu và khó gỡ. Mỗi LED một điện trở mới giữ được các đèn độc lập thật sự.

Chu kỳ và cách tính

Ba khoảng cộng lại thành chu kỳ: 5 giây đỏ + 4 giây lục + 2 giây vàng = 11 giây. Toán bước vào rất tự nhiên — ngã tư hai hướng thì đèn đỏ hướng này phải dài bằng đèn lục cộng đèn vàng của hướng kia, bằng không thì hai hướng cùng được đi.

03

Linh kiện

Linh kiệnMô tả, lưu ý khi muaSố lượng · giá
ESP32 DevKit V1Bo 30 chân, cổng micro-USB hoặc Type-C1 · 90–150k
LED 5 mm đỏ, vàng, lụcMua đúng ba màu để giống đèn thật3 · 1,5k
Điện trở 220 ΩMỗi LED một con, không dùng chung3 · 600đ
Breadboard và dây cắmLoại 400 lỗ là đủ1 bộ · 30k
04

Lắp mạch và sơ đồ nối dây

Đỏ · nguồn dương Đen · GND Vàng · SCL Xanh dương · SDA Trắng · tín hiệu Xanh lá · 1-Wire
KhốiNối dâyNguồn
LED đỏGPIO23 → điện trở 220 Ω → chân dài · chân ngắn → GNDLấy từ chính chân GPIO
LED vàngGPIO18 → điện trở 220 Ω → chân dài · chân ngắn → GNDLấy từ chính chân GPIO
LED lụcGPIO19 → điện trở 220 Ω → chân dài · chân ngắn → GNDLấy từ chính chân GPIO
B3.1 Sơ đồ nối dây
Sơ đồ ESP32 DevKit: GPIO23 qua điện trở 220 Ω tới LED đỏ, GPIO18 tới LED vàng, GPIO19 tới LED lục, cả ba chân ngắn về chung GND.

Ba nhánh giống hệt nhau, chỉ khác chân điều khiển: GPIO23 → đỏ, GPIO18 → vàng, GPIO19 → lục. Mỗi LED một điện trở riêng, ba chân ngắn về chung một đường GND.

B3.2 Ảnh thực
Ảnh chụp mạch thật của Bài 3: ba LED đỏ, vàng, lục xếp dọc trên breadboard, mỗi LED một điện trở, bốn dây nối sang bo ESP32.

Mạch đang chạy thật — đèn đỏ sáng còn vàng và lục tắt, đúng một pha của chu trình. Ba LED xếp dọc theo thứ tự đèn giao thông, mỗi LED một điện trở riêng, và dây đen trên cùng gom cả ba chân ngắn về GND.

Mở sơ đồ này trên Wokwi Mô phỏng ngay trên trình duyệt, chưa cần bo mạch — hợp cho lúc chuẩn bị bài hoặc khi lớp thiếu thiết bị.

Ba lần lặp lại một thao tác

Mạch của bài này chỉ là mạch Bài 1 nhân ba. Làm xong một đèn thì hai đèn còn lại chỉ là chép lại.

  1. Cắm ba LED thành một cột dọc trên breadboard, theo đúng thứ tự thật: đỏ trên, vàng giữa, lục dưới.
  2. Mỗi LED nối chân dài qua một điện trở 220 Ω riêng.
  3. Ba dây trắng từ ba điện trở về GPIO23, GPIO18, GPIO19.
  4. Ba chân ngắn cắm chung một hàng, rồi một dây đen duy nhất về GND.
Cắm đúng thứ tự vật lí, đỡ nhầm về sau

Chuyện hay xảy ra: học sinh cắm ba LED lộn xộn, rồi trong chương trình lại gán do = Pin(23). Khi chạy, "đèn đỏ" theo chương trình lại là con LED màu lục ngoài đời. Nhóm sẽ mất mười phút cãi nhau xem lỗi ở đâu.

Cách phòng: cắm LED đúng thứ tự vật lí đỏ – vàng – lục từ trên xuống, rồi chạy Bước 0 để đối chiếu. Bước 0 bật lần lượt từng đèn và in tên ra màn hình, nên chỉ mất ba giây là biết chân nào ứng với đèn nào.

Đừng bỏ điện trở, kể cả khi vội

Ba đèn thì ba con điện trở. Bỏ bớt một con để tiết kiệm thời gian là cách nhanh nhất làm chết đúng một chân GPIO — bo vẫn chạy, chỉ chân đó không điều khiển được gì nữa, và vài buổi sau mới lộ ra.

05

Mã nguồn

Toàn bộ mã trong bài chạy trên MicroPython 1.28 cho ESP32. Chép vào bo rồi đổi tên thành main.py là chạy mỗi lần cấp nguồn.

Bước 0 — đối chiếu chân với đèn
# ------------------------------------------------------------
#  Bai 3 - Kiem tra ca ba den truoc khi lam gi khac
#  Bat lan luot tung den de biet chan nao dieu khien den nao.
# ------------------------------------------------------------
from machine import Pin
import time

do   = Pin(23, Pin.OUT)
vang = Pin(18, Pin.OUT)
luc  = Pin(19, Pin.OUT)

for den, ten in ((do, "DO"), (vang, "VANG"), (luc, "LUC")):
    print("Dang bat den", ten)
    den.on()
    time.sleep(1)
    den.off()

Ba đèn sáng lần lượt, mỗi đèn một giây, kèm dòng chữ in ra. Nếu thứ tự sáng không phải đỏ – vàng – lục thì mạch cắm nhầm chân chứ chương trình không sai. Sửa dây, đừng sửa mã.

Chương trình chính — một chu trình đèn giao thông
# ------------------------------------------------------------
#  Bai 3 - Den giao thong ba mau
#  Phan cung: GPIO23 -> den do, GPIO18 -> den vang, GPIO19 -> den luc
#             moi den qua mot dien tro 220 ohm roi ve GND
# ------------------------------------------------------------
from machine import Pin
import time

# ===== CẤU HÌNH =====
CHAN_DO   = 23            # den do
CHAN_VANG = 18            # den vang
CHAN_LUC  = 19            # den luc
THOI_GIAN_DO   = 5000     # ms
THOI_GIAN_LUC  = 4000     # ms
THOI_GIAN_VANG = 2000     # ms
# ====================

do   = Pin(CHAN_DO, Pin.OUT)
vang = Pin(CHAN_VANG, Pin.OUT)
luc  = Pin(CHAN_LUC, Pin.OUT)

while True:
    # Luon tat het truoc, roi moi bat den can sang
    vang.off()
    luc.off()
    do.on()
    time.sleep_ms(THOI_GIAN_DO)

    do.off()
    luc.on()
    time.sleep_ms(THOI_GIAN_LUC)

    luc.off()
    vang.on()
    time.sleep_ms(THOI_GIAN_VANG)

Chú ý cách viết: mỗi lần chuyển trạng thái đều tắt đèn cũ trước, bật đèn mới sau. Viết như vậy dài hơn vài dòng, nhưng nó bảo đảm không bao giờ có hai đèn cùng sáng, kể cả khi sau này ai đó chèn thêm lệnh vào giữa.

Biến thể — chế độ ban đêm
# Bien the ban dem: chi den vang nhay, hai den kia tat han
from machine import Pin
import time

do   = Pin(23, Pin.OUT)
vang = Pin(18, Pin.OUT)
luc  = Pin(19, Pin.OUT)

do.off()
luc.off()

while True:
    vang.on()
    time.sleep_ms(700)
    vang.off()
    time.sleep_ms(700)

Nhiều ngã tư ban đêm chỉ cho đèn vàng nháy. Bản này ngắn hơn hẳn và là ví dụ tốt để hỏi: hai đèn kia đâu rồi? Chúng bị tắt một lần duy nhất ở ngoài vòng lặp, vì đã tắt thì không cần tắt lại mỗi vòng.

Em mô tả bằng tiếng Việt, hệ thống dựng thuật toán và chương trình, rồi nạp thẳng xuống ESP32 qua Wi-Fi.

06

Hiệu chuẩn và kiểm thử

Đo chu kỳ bằng đồng hồ bấm giờ

  1. Bấm giờ đúng lúc đèn đỏ vừa bật.
  2. Dừng đúng lúc đèn đỏ bật lần kế tiếp.
  3. So với tổng ba khoảng thời gian trong khối cấu hình.

Với 5000 + 4000 + 2000 ms thì kết quả phải rất gần 11 giây. Chênh dưới 1% là bình thường — phần chênh đến từ thời gian máy chạy các lệnh bật tắt, rất nhỏ so với vài giây nhưng có thật. Ý này sẽ quay lại đầy đủ ở Bài 5.

Danh sách kiểm trước khi coi là xong

  • Bước 0 cho ba đèn sáng đúng thứ tự đỏ – vàng – lục.
  • Chương trình chính không bao giờ có hai đèn cùng sáng.
  • Chu kỳ đo được khớp với tổng ba con số trong khối cấu hình.
  • Đổi THOI_GIAN_DO thành 10000 thì chu kỳ dài thêm đúng 5 giây.
  • Học sinh chỉ ra được dòng nào bảo đảm "mỗi lúc chỉ một đèn sáng".
07

Kinh nghiệm và cạm bẫy

Câu hỏi làm lộ ra hiểu nhầm sâu nhất

Sau khi cả lớp chạy được, hãy hỏi: "Nếu thầy xoá hết các dòng off() đi thì chuyện gì xảy ra?"

Rất nhiều em trả lời "đèn vẫn nháy nhưng nhanh hơn" hoặc "chỉ đèn cuối sáng". Cho chạy thử: ba đèn lần lượt bật rồi không đèn nào tắt nữa, cuối chu kỳ cả ba cùng sáng, và từ vòng thứ hai trở đi cột đèn sáng trắng liên tục.

Khoảnh khắc đó dạy được một ý mà giảng suông rất khó vào: lệnh bật không kèm theo lệnh tắt. Máy không tự dọn dẹp giúp ai cả.

Ba lỗi hay gặp
  • Một đèn không bao giờ sáng. Chạy Bước 0. Nếu Bước 0 cũng không sáng thì lỗi ở mạch: cắm ngược LED, hoặc chân ngắn chưa vào hàng GND chung.
  • Hai đèn cùng sáng mờ mờ. Gần như chắc chắn là dùng chung một điện trở cho nhiều LED. Xem lại hộp kĩ thuật ở mục Lí thuyết.
  • Đèn nhấp nháy loạn xạ không theo thứ tự nào. Kiểm tra dây GND chung đã cắm chắc chưa. Hàng GND lỏng làm cả ba đèn hoạt động chập chờn theo cách rất khó đoán.
Chỗ này cần một chuyện thật của chính thầy cô

Hai hộp trên viết từ quá trình dựng và chạy thử bài. Sau buổi dạy đầu tiên, xin thầy cô thay bằng tình huống đã thực sự xảy ra ở lớp mình.

08

Ứng dụng trong dạy học

Công nghệ 12Tin học 10Toán 10STEM

Tin học — thuật toán vẽ ra được trước khi gõ

Đây là bài đầu tiên đáng để bắt học sinh vẽ sơ đồ khối trước khi lập trình. Chu trình ba trạng thái vẽ ra rất gọn, và khi đã có sơ đồ thì việc gõ chương trình chỉ còn là dịch từng ô sang lệnh. Em nào nhảy thẳng vào gõ mã thường quên mất các lệnh tắt.

Toán — bài toán chia thời gian có ràng buộc

Cho học sinh thiết kế thời lượng cho một ngã tư hai hướng, biết rằng người đi bộ cần ít nhất 8 giây để sang đường và đèn vàng phải đúng 3 giây. Bài toán có ràng buộc thật, nhiều lời giải đúng, và các nhóm sẽ ra kết quả khác nhau — đúng tinh thần một bài toán mở.

Công nghệ — điều khiển nhiều đầu ra theo trình tự

Từ ba đèn ở đây sang băng chuyền ba giai đoạn, máy giặt ba công đoạn hay đèn báo ba mức trong nhà máy đều cùng một khung chương trình. Hãy chỉ rõ điều đó để học sinh thấy mình đang học một mẫu chứ không phải học một bài lẻ.

Bài học STEM 5 hoạt động — "Cột đèn cho ngã tư trước cổng trường"

Hoạt động 1 — Xác định vấn đề. Ngã tư trước cổng trường đông vào giờ tan học. Lớp được giao thiết kế thử một cột đèn với thời lượng hợp lí cho học sinh đi bộ.

Tiêu chí sản phẩm: mô hình cột đèn đứng vững, nhìn rõ từ 5 m; chu kỳ dưới 60 giây; đèn đỏ đủ dài để một bạn đi bộ sang hết đường; và không bao giờ có hai đèn cùng sáng.

Hoạt động 2 — Kiến thức nền. Chân ra số; điện trở hạn dòng; thuật toán tuần tự; cách tính chu kỳ.

Hoạt động 3 — Đề xuất và chọn phương án. Mỗi nhóm đo thử thời gian thật để một bạn đi bộ sang chiều rộng tương ứng, rồi mới chọn con số cho đèn đỏ. Đây là chỗ số liệu thật bước vào thiết kế.

Hoạt động 4 — Chế tạo và thử. Dựng cột bằng bìa, lập trình, đứng cách 5 m nhìn lại.

Hoạt động 5 — Báo cáo và điều chỉnh. Nhóm khác đóng vai người đi bộ và bấm giờ. Nhóm nào để người đi bộ mắc kẹt giữa đường thì tính lại.

Hướng mở rộng
  • Thêm nút nhấn của Bài 2 làm nút xin đường cho người đi bộ.
  • Thêm buzzer của Bài 10 kêu tích tắc khi đèn cho người đi bộ sắp hết.
  • Làm hai cột cho hai hướng, ràng buộc nhau đúng như ngã tư thật.
  • Hướng thi Khoa học kĩ thuật: cột đèn có âm báo cho người khiếm thị.