Menu
CoddyTech

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.

challenge icon

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);
}
quiz iconTự kiểm tra

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

Tự luyện tập: Playground Arduino