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

Bài 2 · Công nghệ · Tin học

Điều khiển LED bằng nút nhấn
máy biết chờ, và biết hỏi lại liên tục

Bài 1 dạy máy tự làm theo thời gian. Bài này dạy máy nhìn ra ngoài rồi mới quyết định. Chỉ thêm một nút nhấn, nhưng đó là bước từ điều khiển sang phản hồi.

Thời lượng
1 tiết (45 phút)
Chi phí một nhóm
≈ 5 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, chương trình chạy một mình từ đầu đến cuối, không quan tâm bên ngoài có gì. Bài này thêm đúng một thứ — một cái nút — nhưng nó đổi hẳn bản chất: lần đầu tiên máy phải hỏi trước khi làm.

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

  • Nối một nút nhấn vào chân GPIO mà không cần điện trở ngoài.
  • Giải thích được vì sao nút chưa nhấn thì đọc ra 1, nhấn rồi mới ra 0.
  • Dùng cấu trúc rẽ nhánh if … else để chọn giữa hai việc.
  • Hiểu chương trình không "nhìn thấy" nút, mà hỏi đi hỏi lại rất nhanh.
  • Đoán được điều gì xảy ra khi tăng khoảng nghỉ giữa hai lần hỏi.
Gắn với chương trình
  • Công nghệ 12 — mạch nội dung Vi điều khiển: đọc tín hiệu số đầu vào và điều khiển thiết bị đầu ra.
  • Tin học 10–11 — cấu trúc rẽ nhánh, biểu thức lôgic, biến kiểu đúng/sai.

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

Chân thả nổi

Hỏi cả lớp trước khi cắm dây: nút có hai chân, vậy khi chưa nhấn thì chân GPIO nối vào đâu? Đáp: chẳng nối vào đâu cả — mạch hở. Chân GPIO hở không phải mức 0 cũng không phải mức 1, nó lơ lửng và đọc ra số ngẫu nhiên theo nhiễu xung quanh.

Điện trở kéo lên

Nối chân GPIO lên 3,3 V qua một điện trở lớn. Chưa nhấn thì chân được kéo lên mức 1 một cách yếu ớt nhưng dứt khoát; nhấn thì nút nối thẳng chân xuống GND — nối thẳng mạnh hơn hẳn kéo qua điện trở, nên chân tụt về 0.

ESP32 có sẵn điện trở kéo lên bên trong chip, chỉ cần một chữ:

nut = Pin(4, Pin.IN, Pin.PULL_UP)
Vì sao logic bị "ngược"

Hệ quả: nhấn nút thì đọc ra 0. Đừng chữa bằng "cứ nhớ thế", hãy quay lại sơ đồ — nhấn = nối xuống GND = 0 V = mức 0.

Trong chương trình viết nut.value() == 0 rồi đặt tên biến là dang_nhan. Từ đó trở đi mọi câu lệnh đều thuận, không ai phải nhớ chuyện ngược nữa. Đặt tên biến tử tế cũng là một kỹ năng lập trình.

Máy không nhìn, máy hỏi

Chương trình không "thấy" lúc nút bị nhấn. Nó chạy vòng lặp, mỗi vòng hỏi đúng một câu — ngay lúc này nút có đang bị nhấn không? — làm theo câu trả lời, nghỉ một chút, rồi hỏi lại.

Nghỉ 50 ms tức hỏi 20 lần mỗi giây. Ngón tay người không nhanh đến thế nên ta có cảm giác đèn phản ứng tức thì. Mục Hiệu chuẩn bên dưới sẽ cho học sinh phá vỡ cảm giác ấy.

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
Nút nhấn 4 chânLoại cắm breadboard. Xem hộp cạm bẫy về cách chọn cặp chân1 · 1k
LED 5 mmDùng lại LED của Bài 11 · 500đ
Điện trở 220 ΩCho LED. Nút nhấn KHÔNG cần điện trở ngoài1 · 200đ
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
Nút nhấnGPIO4 → một chân nút · chân chéo góc → GNDKhông cần nguồn riêng
LEDGPIO23 → điện trở 220 Ω → chân dài (+) · chân ngắn (−) → GNDLấy từ chính chân GPIO
B2.1 Sơ đồ nối dây
Sơ đồ ESP32 DevKit: GPIO23 qua điện trở 220 Ω tới LED rồi về GND; GPIO4 nối một chân nút nhấn, chân chéo góc của nút về GND.

Hai nhánh tách bạch: nhánh ra là GPIO23 → điện trở 220 Ω → LED → GND, nhánh vào là GPIO4 → nút nhấn → GND. Nút không cần điện trở ngoài vì điện trở kéo lên đã nằm sẵn trong chip.

B2.2 Ảnh thực
Ảnh chụp mạch thật của Bài 2: bo ESP32 DevKit cắm cáp USB, breadboard có LED vàng, điện trở và một nút nhấn vàng cỡ lớn.

Chính mạch ấy khi đã cắm xong: LED vàng và điện trở ở nửa trên breadboard, nút nhấn cắm vắt qua rãnh giữa ở nửa dưới. Đèn nguồn đỏ trên bo đang sáng vì cáp USB đã cắm; LED vàng chưa sáng vì chưa nạp chương trình.

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ị.

Bốn thao tác

  1. Giữ nguyên mạch LED của Bài 1: GPIO23 → điện trở 220 Ω → chân dài LED, chân ngắn → GND.
  2. Cắm nút nhấn vắt ngang rãnh giữa breadboard, hai chân mỗi bên.
  3. Dây trắng: một chân nút → GPIO4.
  4. Dây đen: chân chéo góc với chân vừa nối → GND.
Nút 4 chân chỉ có hai chân thật sự

Nút nhấn cắm breadboard thường có bốn chân, nhưng bên trong chúng đã nối sẵn thành từng cặp. Hai chân cùng một cặp lúc nào cũng thông nhau, bấm hay không cũng thế. Nếu học sinh vô tình dùng đúng một cặp đó, đèn sẽ sáng liên tục và không nút nào chữa được.

Quy tắc an toàn: luôn dùng hai chân chéo góc nhau. Cặp chéo góc chắc chắn thuộc hai cặp khác nhau. Cắm nút vắt ngang rãnh giữa breadboard cũng giúp tránh nhầm, vì hai chân cùng cặp khi đó nằm khác phía.

Không cần điện trở cho nút

LED thì bắt buộc có điện trở 220 Ω. Nút nhấn thì không, vì điện trở kéo lên đã nằm sẵn trong chip và được bật bằng Pin.PULL_UP. Học sinh hay cắm thừa một con điện trở ở đây vì tưởng linh kiện nào cũng cần.

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 — nhìn thấy tín hiệu trước đã
# ------------------------------------------------------------
#  Bai 2 - Doc thu trang thai nut nhan
#  Chua dieu khien gi ca, chi in ra man hinh de nhin thay tin hieu.
# ------------------------------------------------------------
from machine import Pin
import time

nut = Pin(4, Pin.IN, Pin.PULL_UP)

while True:
    print(nut.value())
    time.sleep_ms(200)

Nạp vào rồi nhấn giữ nút, màn hình in ra:

1
1
1
0     <-- luc dang giu nut
0
1

Bước này đáng giá cả mục lí thuyết. Học sinh nhìn thấy số 1 đổi thành 0 đúng lúc ngón tay ấn xuống. Đừng bỏ qua để chạy thẳng vào chương trình chính.

Chương trình chính — nhấn thì sáng, thả thì tắt
# ------------------------------------------------------------
#  Bai 2 - Dieu khien LED bang nut nhan
#  Phan cung: GPIO4 -> mot chan nut -> chan con lai -> GND
#             GPIO23 -> dien tro 220 ohm -> chan dai LED -> GND
# ------------------------------------------------------------
from machine import Pin
import time

# ===== CẤU HÌNH =====
CHAN_NUT = 4              # nut nhan cam o GPIO4
CHAN_LED = 23             # LED cam o GPIO23
THOI_GIAN_NGHI = 50       # ms - bao lau doc lai nut mot lan
# ====================

nut = Pin(CHAN_NUT, Pin.IN, Pin.PULL_UP)
led = Pin(CHAN_LED, Pin.OUT)

while True:
    dang_nhan = nut.value() == 0

    if dang_nhan:
        led.on()
    else:
        led.off()

    time.sleep_ms(THOI_GIAN_NGHI)

Ba dòng if … else ở giữa chính là toàn bộ nội dung Tin học của bài. Trước đó chương trình chỉ biết làm tuần tự; từ đây nó biết chọn.

Biến thể — nhấn một lần bật, nhấn lần nữa tắt
# Bien the: nhan mot lan BAT, nhan lan nua TAT (nhu cong tac den)
from machine import Pin
import time

nut = Pin(4, Pin.IN, Pin.PULL_UP)
led = Pin(23, Pin.OUT)

dang_sang = False
truoc_do = False

while True:
    dang_nhan = nut.value() == 0

    # Chi doi trang thai o dung KHOANH KHAC nut vua bi nhan xuong
    if dang_nhan and not truoc_do:
        dang_sang = not dang_sang
        led.value(dang_sang)
        time.sleep_ms(200)        # bo qua nhieu doi tiep diem

    truoc_do = dang_nhan
    time.sleep_ms(20)

Bản này khó hơn hẳn và nên để dành cho nhóm nhanh. Nó cần hai ý mới: nhớ lại trạng thái vòng trước bằng biến truoc_do, và chỉ hành động ở đúng khoảnh khắc chuyển chứ không phải suốt lúc đang giữ. Đây cũng chính là cách Bài 4 đếm số lần nhấn.

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ử

Phép thử làm hỏng cảm giác "đèn phản ứng tức thì"

Chương trình chính đang nghỉ 50 ms mỗi vòng. Cho học sinh tăng dần THOI_GIAN_NGHI rồi nhấn nút thật nhanh:

Thời gian nghỉMáy hỏi mấy lần mỗi giâyCảm giác khi nhấn nhanh
50 ms20Như tức thì
300 mskhoảng 3Hơi trễ, nhận ra được
1000 ms1Nhấn nhanh thì đèn bỏ qua hẳn

Ở mức 1000 ms, học sinh sẽ bấm mà đèn không thèm phản ứng. Đó không phải lỗi — đó là bằng chứng cho thấy máy chỉ hỏi mỗi giây một lần, và ngón tay đã kịp nhấn xong rồi thả ra giữa hai lần hỏi. Không có cách nào giải thích khái niệm "tần suất lấy mẫu" rẻ và rõ hơn thế.

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

  • Bước 0 in ra 1 khi thả, 0 khi giữ nút.
  • Chương trình chính: nhấn thì đèn sáng, thả thì đèn tắt, không trễ thấy được.
  • Đổi THOI_GIAN_NGHI thành 1000 thì đèn bỏ sót cú nhấn nhanh.
  • Đảo led.on() và led.off() cho nhau thì hành vi ngược lại đúng như dự đoán.
  • Học sinh giải thích được vì sao == 0 lại nghĩa là "đang nhấn".
07

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

Cặp chân nút nhấn — chỗ mất thời gian nhất của cả tiết

Trong mọi lỗi của bài này, cắm nhầm hai chân cùng một cặp là lỗi tốn thời gian nhất, vì nó không giống lỗi. Đèn sáng ngay từ lúc cấp nguồn, chương trình chạy đúng, không thông báo gì. Học sinh sẽ đi soi chương trình trong khi mạch mới là chỗ sai.

Cách phát hiện trong mười giây: chạy Bước 0. Nếu màn hình in ra 0 liên tục ngay cả khi không ai chạm vào nút, thì hai chân đang dùng vốn đã thông nhau sẵn. Rút nút ra, xoay 90°, cắm lại.

Vì vậy Bước 0 mới đứng trước chương trình chính trong bài này. Nó không phải thủ tục thừa, nó là công cụ chẩn đoán.

Dội tiếp điểm — thứ chưa lộ ra ở bản đơn giản

Tiếp điểm kim loại trong nút không đóng dứt khoát một lần. Nó nảy vài lần trong khoảng vài mili giây đầu, nên chương trình đọc rất nhanh sẽ thấy 0-1-0-1 rồi mới yên.

Chương trình chính không gặp vấn đề này, vì nó chỉ quan tâm trạng thái hiện tại: nảy vài lần thì đèn nhấp nháy vài mili giây, mắt không thấy. Nhưng bản biến thể "nhấn một lần bật, nhấn lần nữa tắt" thì hỏng ngay — một cú bấm có thể bị đếm thành ba, đèn bật rồi tắt rồi bật.

Đó là lí do bản biến thể có dòng time.sleep_ms(200) ngay sau khi đổi trạng thái. Nếu nhóm nào gặp đèn "loạn" ở bản biến thể, hãy để các em tự tìm ra nguyên nhân trước khi chỉ dòng đó.

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 — đó mới là thứ đồng nghiệp đọc để tránh.

08

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

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

Tin học — rẽ nhánh có hậu quả nhìn thấy được

Trên giấy, if … else là hai nhánh của một sơ đồ khối. Ở đây nó là một cái đèn nghe lời ngón tay. Cho học sinh xoá hẳn nhánh else rồi chạy lại: đèn sáng lên rồi không bao giờ tắt nữa. Câu hỏi tiếp theo tự nó bật ra — vì sao bỏ else thì đèn không tắt được?

Công nghệ — vào và ra trong cùng một vòng

Bài 1 chỉ có đầu ra. Bài này đủ cả ba khối của mọi hệ thống điều khiển: đọc đầu vào, xử lí, xuất đầu ra. Toàn bộ các bài cảm biến về sau chỉ thay nút nhấn bằng cảm biến nhiệt độ, ánh sáng hay khoảng cách — còn khung chương trình thì y nguyên. Hãy nói rõ điều đó, vì nó giúp học sinh thấy mình đang học một khuôn mẫu chứ không phải học thuộc từng bài.

Bài học STEM 5 hoạt động — "Nút gọi hỗ trợ trong phòng thí nghiệm"

Hoạt động 1 — Xác định vấn đề. Khi làm thí nghiệm, nhóm cần gọi giáo viên mà không được rời chỗ và không được la lớn làm ảnh hưởng nhóm khác. Cần một nút bấm bật đèn báo ở bàn giáo viên.

Tiêu chí sản phẩm: đèn sáng ngay khi bấm; nhìn rõ từ bàn giáo viên; đèn phải giữ sáng cho tới khi được xử lí, chứ không tắt ngay khi thả tay.

Hoạt động 2 — Kiến thức nền. Điện trở kéo lên; đọc tín hiệu số; rẽ nhánh; và khái niệm nhớ trạng thái.

Hoạt động 3 — Đề xuất và chọn phương án. Tiêu chí "giữ sáng" khiến bản đơn giản không đạt. Các nhóm phải tự nhận ra và chuyển sang bản biến thể có nhớ trạng thái.

Hoạt động 4 — Chế tạo và thử. Lắp, lập trình, bấm thử nhiều kiểu: bấm nhanh, bấm giữ lâu, bấm liên tục.

Hoạt động 5 — Báo cáo và điều chỉnh. Nhóm khác thử phá: bấm thật nhanh nhiều lần xem đèn có loạn không. Nhóm nào bị phá thành công thì phân tích hiện tượng dội tiếp điểm rồi sửa.

Hướng mở rộng
  • Thêm nút thứ hai: một nút bật, một nút tắt.
  • Ghép với Bài 3 đèn giao thông: bấm nút để chuyển sang chế độ ưu tiên người đi bộ.
  • Ghép với Bài 10 buzzer: bấm nút phát ra một nốt nhạc.
  • Bài 4 sẽ đếm số lần nhấn — dùng lại đúng ý "chỉ hành động ở khoảnh khắc chuyển" của bản biến thể.
  • Hướng thi Khoa học kĩ thuật: nút gọi hỗ trợ không dây cho người cao tuổi sống một mình.