Menu
CoddyTech

Đèn giao thông dùng millis()

Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 2 trên 24.

Trong mỗi lần chạy delay(3000), bo mạch không làm gì khác, nên không thể phát hiện nút bấm dành cho người đi bộ mà bước tiếp theo sẽ thêm vào. Ta chuyển sang dùng millis() để tính thời gian.

Đèn hoạt động như một máy trạng thái: luôn ở một trạng thái (xanh lá, vàng hoặc đỏ) và chuyển sang trạng thái tiếp theo khi đã ở trạng thái hiện tại đủ lâu. Một enum đặt tên cho các trạng thái, một biến lưu trạng thái hiện tại, còn biến kia lưu thời điểm trạng thái bắt đầu:

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;

Trạng thái đầu tiên là xanh lá, vì vậy hãy bật đèn xanh lá trong setup(). Mỗi khi loop() chạy một lượt, một câu lệnh switch kiểm tra xem trạng thái hiện tại đã kéo dài đủ lâu chưa, rồi mới chuyển sang trạng thái tiếp theo và thay đổi đèn:

case GREEN:
  if (millis() - lightStart >= 3000) {
    light = YELLOW;
    lightStart = millis();
    showLight(yellowPin);
  }
  break;

Không có gì phải chờ, nên loop() vẫn có thể xử lý việc khác. Hãy chứng minh điều đó bằng đèn báo trạng thái: cho đèn LED tích hợp trên bo mạch ở chân 13 nhấp nháy sau mỗi 500 ms.

challenge icon

Thử thách

Trung bình

Viết lại cách tính thời gian mà không dùng delay():

  • giữ đèn xanh trong 3000 ms, đèn vàng trong 1000 ms, đèn đỏ trong 3000 ms
  • dùng enum cho ba trạng thái, một câu lệnh switch và millis()
  • bật đèn xanh trong setup() và chỉ gọi showLight() khi trạng thái thay đổi
  • làm chân 13 nhấp nháy liên tục, mỗi 500 ms (bật trong 500 ms, tắt trong 500 ms)

Nhấn Chạy, sau đó nhấn Kiểm tra.

Tự làm thử

// Đèn xe ô tô
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;

// Bật một đèn và tắt hai đèn còn lại.
void showLight(int pin) {
  digitalWrite(redPin, LOW);
  digitalWrite(yellowPin, LOW);
  digitalWrite(greenPin, LOW);
  digitalWrite(pin, HIGH);
}

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
}

void loop() {
  showLight(greenPin);
  delay(3000);
  showLight(yellowPin);
  delay(1000);
  showLight(redPin);
  delay(3000);
}
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 Dự án

Tự luyện tập: Playground Arduino