// กำหนดพิน LED (Active Low)
#define RED_LED_PIN 8 // พินสำหรับ LED แดง
#define GREEN_LED_PIN 9 // พินสำหรับ LED เขียว
#define YELLOW_LED_PIN 10 // พินสำหรับ LED เหลือง
// รูปแบบการแมพตัวเลข 0-9 สำหรับ 7-Segment แบบ Active Low
const uint8_t segment_map[] = {
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000 // 9
};
// พิน 7-Segment ที่เชื่อมต่อกับ PORTD (พิน 2-9 บน Arduino)
#define SEGMENT_PORT PORTD
volatile uint8_t countdown = 9; // ตัวแปรสำหรับการนับถอยหลัง
volatile uint8_t state = 1; // สถานะเริ่มต้นคือไฟแดง
void setup() {
// ตั้งค่า LED เป็น output
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(YELLOW_LED_PIN, OUTPUT);
// ตั้งค่าเริ่มต้น LED (Active Low: HIGH = ปิดไฟ, LOW = เปิดไฟ)
digitalWrite(RED_LED_PIN, HIGH); // เปิดไฟแดง (Active Low)
digitalWrite(GREEN_LED_PIN, HIGH); // ปิดไฟเขียว
digitalWrite(YELLOW_LED_PIN, HIGH); // ปิดไฟเหลือง
// ตั้งพิน 7-segment เป็น output
DDRD = 0xFF; // พิน 0-7 เป็น output
// แสดงผลนับถอยหลัง 9 วินาทีบน 7-Segment
display_7segment(countdown);
// ตั้งค่า Timer1
noInterrupts(); // ปิดการทำงานของ Interrupts ชั่วคราว
TCCR1A = 0; // เคลียร์บิตของ Timer1
TCCR1B = 0;
TCNT1 = 0; // เคลียร์ค่าตัวนับของ Timer1
OCR1A = 15624; // ตั้งค่าเปรียบเทียบที่ 1 วินาที (16MHz/1024/1Hz)
TCCR1B |= (1 << WGM12); // เปิดโหมด CTC
TCCR1B |= (1 << CS12) | (1 << CS10); // ตั้ง prescaler เป็น 1024
TIMSK1 |= (1 << OCIE1A); // เปิดการขัดจังหวะที่ Compare Match A
interrupts(); // เปิดการทำงานของ Interrupts
}
void loop() {
// วนลูปในฟังก์ชันหลัก ปล่อยให้การขัดจังหวะทำงานเอง
}
// ฟังก์ชันการแสดงผล 7-Segment (Active Low)
void display_7segment(uint8_t number) {
SEGMENT_PORT = segment_map[number];
}
// ตั้งสถานะไฟจราจร
void set_traffic_light(uint8_t red, uint8_t green, uint8_t yellow) {
digitalWrite(RED_LED_PIN, red ? LOW : HIGH); // Active Low: LOW = ติดไฟ
digitalWrite(GREEN_LED_PIN, green ? LOW : HIGH); // Active Low: LOW = ติดไฟ
digitalWrite(YELLOW_LED_PIN, yellow ? LOW : HIGH); // Active Low: LOW = ติดไฟ
}
// การทำงานของไฟจราจรในแต่ละสถานะ
void traffic_light_sequence() {
switch (state) {
case 0: // ไฟแดง
set_traffic_light(1, 0, 0); // เปิดไฟแดง
countdown = 9; // ตั้งค่านับถอยหลังเป็น 9 วินาที
state = 1;
break;
case 1: // นับถอยหลังไฟแดง
if (countdown == 1) {
state = 2; // ไปสถานะไฟเขียว
}
break;
case 2: // ไฟเขียว
set_traffic_light(0, 1, 0); // เปิดไฟเขียว
countdown = 4; // ตั้งค่านับถอยหลังเป็น 4 วินาที
state = 3;
break;
case 3: // นับถอยหลังไฟเขียว
if (countdown == 1) {
state = 4; // ไปสถานะไฟเหลือง
}
break;
case 4: // ไฟเหลือง
set_traffic_light(0, 0, 1); // เปิดไฟเหลือง
countdown = 2; // ตั้งค่านับถอยหลังเป็น 2 วินาที
state = 5;
break;
case 5: // นับถอยหลังไฟเหลือง
if (countdown == 1) {
state = 0; // กลับไปที่สถานะไฟแดง
}
break;
}
}
// การขัดจังหวะ Timer1 เมื่อครบ 1 วินาที
ISR(TIMER1_COMPA_vect) {
if (countdown > 0) {
countdown--; // ลดค่านับถอยหลัง
display_7segment(countdown); // แสดงค่านับถอยหลังบน 7-Segment
}
traffic_light_sequence(); // เรียกฟังก์ชันควบคุมไฟจราจร
}