Nhấp nháy không trì hoãn
Thuộc phần Định thời không dùng delay trong hành trình Arduino của Coddy. Bài học 3 trên 18.
delay() dừng toàn bộ sketch. Trong khi đèn LED nhấp nháy chờ 500 ms, không có gì khác trong loop() chạy: nếu bạn nhấn nút trong lúc đó, chương trình sẽ không nhận ra cho đến khi hết thời gian chờ.
Cách khắc phục là không chờ. Để loop() chạy đi chạy lại thật nhanh, mỗi lần so sánh thời gian hiện tại với thời điểm đèn LED đổi trạng thái lần cuối. Cho đến khi đủ 500 ms, không làm gì cả. Sau đó đổi trạng thái đèn LED và lưu thời điểm mới:
const unsigned long interval = 500;
unsigned long previousMillis = 0; // thời điểm LED thay đổi lần gần nhất
void loop() {
unsigned long now = millis();
if (now - previousMillis >= interval) {
previousMillis = now; // ghi nhớ thời điểm này
// chuyển trạng thái LED tại đây
}
// mọi đoạn code khác ở đây chạy hàng nghìn lần mỗi giây
}now - previousMillis là khoảng thời gian kể từ lần đổi trạng thái gần nhất. Để đổi trạng thái đèn LED, hãy lưu trạng thái của đèn trong một biến, int redState = LOW;, đảo trạng thái bằng if/else rồi ghi trạng thái bằng digitalWrite(redLed, redState);.
Nếu quên cập nhật previousMillis, điều kiện sẽ luôn đúng sau 500 ms đầu tiên, khiến đèn LED đổi trạng thái sau mỗi vòng lặp và trông như chỉ sáng một nửa.
Thử thách
Trung bìnhĐèn LED vàng cần bật tắt theo nút bấm, nhưng phản hồi chậm vì các lệnh gọi delay() của đèn LED đỏ làm vòng lặp dừng lại. Viết lại phần nhấp nháy của đèn LED đỏ bằng millis():
- giữ nguyên phần xử lý nút bấm
- cứ mỗi 500 ms, bật hoặc tắt đèn LED đỏ ở chân 13
- không dùng
delay()ở bất kỳ đâu
Nhấn Chạy, giữ nút bấm và quan sát cả hai đèn LED, rồi nhấn Kiểm tra.
Tự làm thử
const int redLed = 13;
const int yellowLed = 12;
const int buttonPin = 2;
void setup() {
pinMode(redLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// Đèn LED vàng sáng hoặc tắt theo nút bấm. Giữ nguyên phần này.
if (digitalRead(buttonPin) == LOW) {
digitalWrite(yellowLed, HIGH);
} else {
digitalWrite(yellowLed, LOW);
}
// Đèn LED đỏ nhấp nháy, nhưng mỗi lần gọi delay() đều dừng các dòng code phía trên
// trong nửa giây. Bạn hãy viết lại phần này bằng millis().
digitalWrite(redLed, HIGH);
delay(500);
digitalWrite(redLed, LOW);
delay(500);
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Định thời không dùng delay
1millis()
Đồng hồ millis()Thời gian trong unsigned longNhấp nháy không trì hoãnHai đèn LED, hai tốc độNhấp nháy khi nút bấm chuyển trạng tháiĐèn hẹn giờTự luyện tập: Playground Arduino