Giả lập điều khiển đèn tín hiệu giao thông có nút bấm với Arduino

1. Đèn tín hiệu giao thông có nút bấm

Ở các ngã tư, loại đèn có 3 màu thường được sử dụng để điều khiển giao thông. Loại này dành cho xe cộ với 3 màu: đỏ, xanh, vàng. Các màu này có ý nghĩa:

  • Đỏ: Không được phép qua đường.
  • Xanh: Được phép qua đường.
  • Vàng: Sắp hết thời gian được phép qua đường.
Đèn giao thông 3 màu: xanh, vàng, đỏ
Đèn giao thông 3 màu: xanh, vàng, đỏ

Loại đèn giao thông 3 màu có thể có thêm nút bấm. Nút bấm này được người điều khiển giao thông (cảnh sát giao thông) sử dụng để điều khiển trực tiếp khi có lưu lượng giao thông bất thường. Cảnh sát giao thông có thể dễ dàng đổi tín hiệu đèn xanh hay đèn đỏ ngay lập tức để điều tiết giao thông.

2. Giả lập điều khiển đèn tín hiệu giao thông có nút bấm với Arduino

Bên dưới là sơ đồ mạch điều khiển loại 3 đèn có nút bấm ở ngã tư với Arduino.

Sơ đồ mạch điều khiển đèn tín hiệu giao thông có nút bấm với Arduino
Sơ đồ mạch điều khiển đèn tín hiệu giao thông có nút bấm với Arduino

Ở ngã tư, người tham gia giao thông sẽ nhìn vào cụm đèn tín hiệu ở bên phải theo hướng di chuyển của mình. Tuy là ngã tư nhưng thật chất chúng ta chỉ cần xử lý các cụm đèn tín hiệu theo 2 hướng: chiều ngang chiều dọc. Cụm đèn D1, D2, D3 sẽ tương tự cụm đèn D10, D11, D12. Cụm đèn D4, D5, D6 sẽ tương tự cụm đèn D7, D8, D9.

Chúng ta xét cụm đèn D1, D2, D3 và cụm đèn D4, D5, D6. Chúng ta qui ước mặc định là đèn xanh D3 sẽ sáng trước. Lúc này, có 4 lượt đèn giao thông sáng và lặp đi lặp lại như sau:

Lượt 1 – Đèn đỏ D4 và đèn xanh D3 sáng, các đèn D1, D2, D5, D6 tắt.

Lượt 2 – Đèn đỏ D4 và đèn vàng D2 sáng, các đèn D1, D3, D5, D6 tắt.

Lượt 3 – Đèn đỏ D1 và đèn xanh D6 sáng, các đèn D2, D3, D4, D5 tắt.

Lượt 4 – Đèn đỏ D1 và đèn vàng D5 sáng, các đèn D2, D3, D4, D6 tắt.

Khi nhấn nút bấm lần 1 (lần lẻ), đèn xanh D6 sẽ sáng. Lúc này, có 4 lượt đèn giao thông sáng và lặp đi lặp lại như sau:

Lượt 1 – Đèn đỏ D1 và đèn xanh D6 sáng, các đèn D2, D3, D4, D5 tắt.

Lượt 2 – Đèn đỏ D1 và đèn vàng D5 sáng, các đèn D2, D3, D4, D6 tắt.

Lượt 3 – Đèn đỏ D4 và đèn xanh D3 sáng, các đèn D1, D2, D5, D6 tắt.

Lượt 4 – Đèn đỏ D4 và đèn vàng D2 sáng, các đèn D1, D3, D5, D6 tắt.

Trường hợp nhấn nút bấm lần 2 (lần chẵn) thì sẽ quay về lượt đèn xanh D3 sẽ sáng trước. Cứ như thế lặp lại với nhấn lần 3, lần 4,… của nút bấm.

Dưới đây là code Arduino điều khiển đèn giao thông với sơ đồ mạch đã cho.

//led-red
int d1=7, d4=4, d7=10, d10=13;
//led-yellow
int d2=6, d5=3, d8=9, d11=12;
//led-green
int d3=5, d6=2, d9=8, d12=11;
//sử dụng hàm millis() thay delay()
unsigned long previousMillis = 0;
//button
int btn=1;
int preState=LOW;
int dem=0;
void setup() {
  for(int i=2;i<14;i++){
    pinMode(i, OUTPUT);
  }
  pinMode(btn, INPUT);
}

void loop() {
  int curState=digitalRead(btn);
  if(curState==HIGH && preState==LOW){
    dem++;
    if(dem==2){
      dem=0;
    }
    previousMillis = millis();
  }
  if(dem==1){
    denxanhD6sangtruoc();
  }else{
    denxanhD3sangtruoc();
  }
  preState=curState;
}

void denxanhD3sangtruoc(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis <= 12000) {
    /*----------Lượt đèn sáng 1----------*/
    //d4, d3 sáng; d1, d2 tắt; d5, d6 tắt
    digitalWrite(d4, HIGH);
    digitalWrite(d3, HIGH);
    digitalWrite(d1, LOW);
    digitalWrite(d2, LOW);
    digitalWrite(d5, LOW);
    digitalWrite(d6, LOW);
    //d7, d12 sáng; d10, d11 tắt; d8, d9 tắt
    digitalWrite(d7, HIGH);
    digitalWrite(d12, HIGH);
    digitalWrite(d10, LOW);
    digitalWrite(d11, LOW);
    digitalWrite(d8, LOW);
    digitalWrite(d9, LOW);
  }else if(currentMillis - previousMillis <= 15000){
    /*----------Lượt đèn sáng 2----------*/
    //d4, d2 sáng; d1, d3 tắt; d5, d6 tắt
    digitalWrite(d4, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(d1, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d5, LOW);
    digitalWrite(d6, LOW);
    //d7, d11 sáng; d10, d12 tắt; d8, d9 tắt
    digitalWrite(d7, HIGH);
    digitalWrite(d11, HIGH);
    digitalWrite(d10, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d8, LOW);
    digitalWrite(d9, LOW);
  }else if(currentMillis - previousMillis <= 27000){
    /*----------Lượt đèn sáng 3----------*/
    //d1, d6 sáng; d2, d3 tắt; d4, d5 tắt
    digitalWrite(d1, HIGH);
    digitalWrite(d6, HIGH);
    digitalWrite(d2, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d4, LOW);
    digitalWrite(d5, LOW);
    //d10, d9 sáng; d11, d12 tắt; d7, d8 tắt
    digitalWrite(d10, HIGH);
    digitalWrite(d9, HIGH);
    digitalWrite(d11, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d7, LOW);
    digitalWrite(d8, LOW);
  }else if(currentMillis - previousMillis <= 30000){
    /*----------Lượt đèn sáng 4----------*/
    //d1, d5 sáng; d2, d3 tắt; d4, d6 tắt
    digitalWrite(d1, HIGH);
    digitalWrite(d5, HIGH);
    digitalWrite(d2, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d4, LOW);
    digitalWrite(d6, LOW);
    //d10, d8 sáng; d11, d12 tắt; d7, d9 tắt
    digitalWrite(d10, HIGH);
    digitalWrite(d8, HIGH);
    digitalWrite(d11, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d7, LOW);
    digitalWrite(d9, LOW);
  }else{
    previousMillis=currentMillis;
  }
}
void denxanhD6sangtruoc(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis <= 12000) {
    /*----------Lượt đèn sáng 1----------*/
    //d1, d6 sáng; d2, d3 tắt; d4, d5 tắt
    digitalWrite(d1, HIGH);
    digitalWrite(d6, HIGH);
    digitalWrite(d2, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d4, LOW);
    digitalWrite(d5, LOW);
    //d10, d9 sáng; d11, d12 tắt; d7, d8 tắt
    digitalWrite(d10, HIGH);
    digitalWrite(d9, HIGH);
    digitalWrite(d11, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d7, LOW);
    digitalWrite(d8, LOW);
  }else if(currentMillis - previousMillis <= 15000){
    /*----------Lượt đèn sáng 2----------*/
    //d5, d1 sáng; d2, d3 tắt; d4, d6 tắt
    digitalWrite(d5, HIGH);
    digitalWrite(d1, HIGH);
    digitalWrite(d2, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d4, LOW);
    digitalWrite(d6, LOW);
    //d8, d10 sáng; d11, d12 tắt; d7, d9 tắt
    digitalWrite(d8, HIGH);
    digitalWrite(d10, HIGH);
    digitalWrite(d11, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d7, LOW);
    digitalWrite(d9, LOW);
  }else if(currentMillis - previousMillis <= 27000){
    /*----------Lượt đèn sáng 3----------*/
    //d3, d4 sáng; d1, d2 tắt; d5, d6 tắt
    digitalWrite(d3, HIGH);
    digitalWrite(d4, HIGH);
    digitalWrite(d1, LOW);
    digitalWrite(d2, LOW);
    digitalWrite(d5, LOW);
    digitalWrite(d6, LOW);
    //d12, d7 sáng; d10, d11 tắt; d8, d9 tắt
    digitalWrite(d12, HIGH);
    digitalWrite(d7, HIGH);
    digitalWrite(d10, LOW);
    digitalWrite(d11, LOW);
    digitalWrite(d8, LOW);
    digitalWrite(d9, LOW);
  }else if(currentMillis - previousMillis <= 30000){
    /*----------Lượt đèn sáng 4----------*/
    //d4, d2 sáng; d1, d3 tắt; d5, d6 tắt
    digitalWrite(d4, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(d1, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d5, LOW);
    digitalWrite(d6, LOW);
    //d7, d11 sáng; d10, d12 tắt; d8, d9 tắt
    digitalWrite(d7, HIGH);
    digitalWrite(d11, HIGH);
    digitalWrite(d10, LOW);
    digitalWrite(d12, LOW);
    digitalWrite(d8, LOW);
    digitalWrite(d9, LOW);
  }else{
    previousMillis=currentMillis;
  }
}

Trong chương trình trên, chúng ta sử dụng định thời với hàm millis() để điều khiển khoảng thời gian led giao thông sáng hay tắt. Chúng ta không sử dụng hàm delay() bởi vì có nút bấm. Khi chương trình chạy hàm delay() thì toàn bộ chương trình sẽ bị dừng lại. Lúc này, nhấn nút bấm sẽ không có tác dụng.

Bên dưới là video demo điều khiển đèn giao thông với Arduino.

5/5 - (1 bình chọn)
Chia sẻ trên mạng xã hội:

Trả lời

Lưu ý:

1) Vui lòng bình luận bằng tiếng Việt có dấu.

2) Khuyến khích sử dụng tên thật và địa chỉ email chính xác.

3) Mọi bình luận trái quy định sẽ bị xóa bỏ.