Menu
CoddyTech

Đặt tên trạng thái bằng enum

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 9 trên 18.

Chế độ được đánh số 0, 1 và 2 vẫn hoạt động, nhưng if (mode == 2) không cho biết số 2 có nghĩa là gì. enum đặt tên cho từng số:

enum State { READY, RUNNING, DONE };
State state = READY;

Dòng đầu tiên tạo một kiểu mới, State, chỉ có các giá trị READY, RUNNING và DONE. Bên dưới, chúng vẫn là 0, 1 và 2, nhưng tên gọi cho biết ý nghĩa của từng giá trị. Dòng thứ hai tạo một biến thuộc kiểu đó.

enum và switch kết hợp với nhau rất phù hợp: mỗi trạng thái có một case.

switch (state) {
  case READY:
    // READY làm gì và khi nào chuyển sang trạng thái tiếp theo
    break;
  case RUNNING:
    // ...
    break;
}

Để chuyển sang trạng thái mới, hãy đặt state và ghi nhớ thời điểm trạng thái bắt đầu: state = DONE; stateStart = millis();. Sau đó, mỗi trạng thái tự tính thời gian bằng millis() - stateStart. Cách viết sketch này được gọi là máy trạng thái.

challenge icon

Thử thách

Trung bình

Máy có ba trạng thái. Phần READY đã được viết sẵn cho bạn: đèn LED xanh lá bật và khi nhấn nút, máy sẽ khởi động. Hãy thêm hai trường hợp còn lại:

  • RUNNING: đèn LED vàng bật. Sau 2000 ms, tắt đèn và chuyển sang DONE.
  • DONE: đèn LED đỏ bật. Sau 1000 ms, tắt đèn và quay lại READY.

Lưu stateStart sau mỗi lần thay đổi. Nhấn Chạy, nhấn nút, rồi nhấn Kiểm tra.

Tự làm thử

const int buttonPin = 2;
const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;

enum State { READY, RUNNING, DONE };
State state = READY;

unsigned long stateStart = 0;   // thời điểm trạng thái hiện tại bắt đầu

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
}

void loop() {
  unsigned long now = millis();

  switch (state) {
    case READY:
      digitalWrite(greenLed, HIGH);
      if (digitalRead(buttonPin) == LOW) {
        digitalWrite(greenLed, LOW);
        state = RUNNING;
        stateStart = now;
      }
      break;

    // thêm case RUNNING: bật đèn vàng; sau 2000 ms, tắt đèn vàng và chuyển sang DONE

    // thêm case DONE: bật đèn đỏ; sau 1000 ms, tắt đèn đỏ và quay lại READY
  }
}
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