// ---------- 북쪽 신호등 ----------
#define N_RED 8
#define N_YELLOW 9
#define N_GREEN 10
// ---------- 동쪽 신호등 ----------
#define E_RED 2
#define E_YELLOW 3
#define E_GREEN 4
// ---------- 차량 감지 센서(버튼) ----------
#define SENSOR_N 28
#define SENSOR_E 27
// ---------- 신호 유지 시간 ----------
// 시연용
const unsigned long TIME_GO = 3000; // 초록불 3초
const unsigned long TIME_WAIT = 1000; // 노란불 1초
// 메인
// const unsigned long TIME_GO = 30000;
// const unsigned long TIME_WAIT = 5000;
// FSM 상태 정의
enum State {
GO_N, // 북쪽 초록불
WAIT_N, // 북쪽 노란불
GO_E, // 동쪽 초록불
WAIT_E // 동쪽 노란불
};
State state = GO_N;
// 상태 시작 시간 저장
unsigned long stateStartTime = 0;
// LED 상태 설정 함수
void setLights(int nr, int ny, int ng,
int er, int ey, int eg) {
// 북쪽 신호등
digitalWrite(N_RED, nr);
digitalWrite(N_YELLOW, ny);
digitalWrite(N_GREEN, ng);
// 동쪽 신호등
digitalWrite(E_RED, er);
digitalWrite(E_YELLOW, ey);
digitalWrite(E_GREEN, eg);
}
// 초기 설정
void setup() {
// 북쪽 신호등 LED 출력 설정
pinMode(N_RED, OUTPUT);
pinMode(N_YELLOW, OUTPUT);
pinMode(N_GREEN, OUTPUT);
// 동쪽 신호등 LED 출력 설정
pinMode(E_RED, OUTPUT);
pinMode(E_YELLOW, OUTPUT);
pinMode(E_GREEN, OUTPUT);
// 센서 입력 설정
// 버튼을 누르면 HIGH가 입력됨
pinMode(SENSOR_N, INPUT_PULLDOWN);
pinMode(SENSOR_E, INPUT_PULLDOWN);
// FSM 시작 시간 기록
stateStartTime = millis();
}
// 메인 반복문
void loop() {
// 현재 시간
unsigned long currentTime = millis();
// 현재 상태에서 경과한 시간
unsigned long elapsedTime = currentTime - stateStartTime;
// 센서 입력 읽기
int carN = digitalRead(SENSOR_N);
int carE = digitalRead(SENSOR_E);
switch (state) {
// GO_N : 북쪽 초록불, 동쪽 빨간불
case GO_N:
setLights(
LOW, LOW, HIGH, // North : Red, Yellow, Green
HIGH, LOW, LOW // East : Red, Yellow, Green
);
// 30초(시연시 3초) 후 동쪽 차량이 감지되면
// WAIT_N 상태로 전환
if (elapsedTime >= TIME_GO && carE == HIGH) {
state = WAIT_N;
stateStartTime = currentTime;
}
break;
// WAIT_N : 북쪽 노란불, 동쪽 빨간불
case WAIT_N:
setLights(
LOW, HIGH, LOW,
HIGH, LOW, LOW
);
// 노란불 유지 시간 후
// 동쪽 초록불 상태로 전환
if (elapsedTime >= TIME_WAIT) {
state = GO_E;
stateStartTime = currentTime;
}
break;
// GO_E : 동쪽 초록불, 북쪽 빨간불
case GO_E:
setLights(
HIGH, LOW, LOW,
LOW, LOW, HIGH
);
// 30초(시연시 3초) 후 북쪽 차량이 감지되면
// WAIT_E 상태로 전환
if (elapsedTime >= TIME_GO && carN == HIGH) {
state = WAIT_E;
stateStartTime = currentTime;
}
break;
// WAIT_E : 동쪽 노란불, 북쪽 빨간불
case WAIT_E:
setLights(
HIGH, LOW, LOW,
LOW, HIGH, LOW
);
// 노란불 유지 시간 후
// 다시 북쪽 초록불 상태로 전환
if (elapsedTime >= TIME_WAIT) {
state = GO_N;
stateStartTime = currentTime;
}
break;
}
}