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.
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.
Ở 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 và 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.