// Pin deklarasi untuk 7-segment display
#define SEG_A 23
#define SEG_B 22
#define SEG_C 21
#define SEG_D 4
#define SEG_E 16
#define SEG_F 2
#define SEG_G 0
#define SEG_DP 35
#define DIGIT_1 19
#define DIGIT_2 18
#define DIGIT_3 5
#define DIGIT_4 17
// Pin deklarasi untuk LED lalu lintas
// Arah 1
#define RED_1 13
#define YELLOW_1 12
#define GREEN_1 14
// Arah 2
#define RED_2 27
#define YELLOW_2 26
#define GREEN_2 25
// Arah 3
#define RED_3 33
#define YELLOW_3 32
#define GREEN_3 15
// Durasi lampu (dalam detik)
#define GREEN_TIME 15
#define YELLOW_TIME 3
#define RED_TIME 18 // Total merah = hijau+lampu kuning arah lain
// Variabel untuk countdown
int countdownTime = GREEN_TIME + YELLOW_TIME;
int currentCountdown = countdownTime;
unsigned long previousMillis = 0;
const long interval = 1000; // Interval 1 detik
// Status lampu
enum TrafficState {
STATE_GREEN,
STATE_YELLOW,
STATE_RED
};
TrafficState currentState = STATE_GREEN;
int currentDirection = 1; // Arah yang sedang hijau (1, 2, atau 3)
// Pattern untuk angka 0-9 pada 7-segment (a,b,c,d,e,f,g)
byte digitPatterns[10] = {
0b11111100, // 0
0b01100000, // 1
0b11011010, // 2
0b11110010, // 3
0b01100110, // 4
0b10110110, // 5
0b10111110, // 6
0b11100000, // 7
0b11111110, // 8
0b11110110 // 9
};
void setup() {
Serial.begin(115200);
// Inisialisasi pin 7-segment sebagai output
pinMode(SEG_A, OUTPUT);
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_DP, OUTPUT);
pinMode(DIGIT_1, OUTPUT);
pinMode(DIGIT_2, OUTPUT);
pinMode(DIGIT_3, OUTPUT);
pinMode(DIGIT_4, OUTPUT);
// Inisialisasi pin LED lalu lintas sebagai output
pinMode(RED_1, OUTPUT);
pinMode(YELLOW_1, OUTPUT);
pinMode(GREEN_1, OUTPUT);
pinMode(RED_2, OUTPUT);
pinMode(YELLOW_2, OUTPUT);
pinMode(GREEN_2, OUTPUT);
pinMode(RED_3, OUTPUT);
pinMode(YELLOW_3, OUTPUT);
pinMode(GREEN_3, OUTPUT);
// Matikan semua LED dan digit awal
allLightsOff();
turnOffAllDigits();
// Set kondisi awal: Arah 1 hijau, lainnya merah
setTrafficLight(1, STATE_GREEN);
setTrafficLight(2, STATE_RED);
setTrafficLight(3, STATE_RED);
Serial.println("Sistem Lampu Lalu Lintas ESP32 Siap!");
}
void loop() {
unsigned long currentMillis = millis();
// Update countdown setiap 1 detik
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Kurangi countdown
currentCountdown--;
// Jika countdown habis, ganti state
if (currentCountdown <= 0) {
changeTrafficState();
}
// Tampilkan countdown pada 7-segment
displayNumber(currentCountdown);
}
// Refresh display 7-segment
refreshDisplay();
}
// Fungsi untuk mengubah state lampu lalu lintas
void changeTrafficState() {
switch(currentState) {
case STATE_GREEN:
// Dari hijau ke kuning
currentState = STATE_YELLOW;
setTrafficLight(currentDirection, STATE_YELLOW);
currentCountdown = YELLOW_TIME;
break;
case STATE_YELLOW:
// Dari kuning ke merah, dan pindah ke arah berikutnya
setTrafficLight(currentDirection, STATE_RED);
currentDirection++;
if (currentDirection > 3) currentDirection = 1;
// Set arah baru ke hijau
currentState = STATE_GREEN;
setTrafficLight(currentDirection, STATE_GREEN);
currentCountdown = GREEN_TIME;
break;
case STATE_RED:
// Tidak digunakan dalam logika ini
break;
}
Serial.print("Status berubah: Arah ");
Serial.print(currentDirection);
Serial.print(" - ");
Serial.println(stateToString(currentState));
}
// Fungsi untuk mengatur lampu lalu lintas berdasarkan arah dan state
void setTrafficLight(int direction, TrafficState state) {
// Matikan semua lampu di arah tersebut terlebih dahulu
switch(direction) {
case 1:
digitalWrite(RED_1, LOW);
digitalWrite(YELLOW_1, LOW);
digitalWrite(GREEN_1, LOW);
break;
case 2:
digitalWrite(RED_2, LOW);
digitalWrite(YELLOW_2, LOW);
digitalWrite(GREEN_2, LOW);
break;
case 3:
digitalWrite(RED_3, LOW);
digitalWrite(YELLOW_3, LOW);
digitalWrite(GREEN_3, LOW);
break;
}
// Nyalakan lampu sesuai state
switch(direction) {
case 1:
if (state == STATE_RED) digitalWrite(RED_1, HIGH);
else if (state == STATE_YELLOW) digitalWrite(YELLOW_1, HIGH);
else if (state == STATE_GREEN) digitalWrite(GREEN_1, HIGH);
break;
case 2:
if (state == STATE_RED) digitalWrite(RED_2, HIGH);
else if (state == STATE_YELLOW) digitalWrite(YELLOW_2, HIGH);
else if (state == STATE_GREEN) digitalWrite(GREEN_2, HIGH);
break;
case 3:
if (state == STATE_RED) digitalWrite(RED_3, HIGH);
else if (state == STATE_YELLOW) digitalWrite(YELLOW_3, HIGH);
else if (state == STATE_GREEN) digitalWrite(GREEN_3, HIGH);
break;
}
}
// Fungsi untuk menampilkan angka pada 7-segment
void displayNumber(int number) {
// Pastikan angka dalam range 0-99
if (number < 0) number = 0;
if (number > 99) number = 99;
// Pisahkan digit puluhan dan satuan
int tens = number / 10;
int ones = number % 10;
// Tampilkan digit (akan di-refresh di fungsi refreshDisplay)
static int currentDigit = 0;
static byte digits[4] = {0, 0, tens, ones};
// Update nilai digit
digits[2] = tens;
digits[3] = ones;
// Tampilkan digit yang sesuai
turnOffAllDigits();
switch(currentDigit) {
case 0:
showDigit(digits[0], DIGIT_1);
break;
case 1:
showDigit(digits[1], DIGIT_2);
break;
case 2:
showDigit(digits[2], DIGIT_3);
break;
case 3:
showDigit(digits[3], DIGIT_4);
break;
}
currentDigit = (currentDigit + 1) % 4;
}
// Fungsi untuk menampilkan satu digit pada posisi tertentu
void showDigit(byte digit, int digitPin) {
// Aktifkan digit yang dipilih
digitalWrite(digitPin, HIGH);
// Tampilkan pattern untuk digit tersebut
byte pattern = digitPatterns[digit];
digitalWrite(SEG_A, (pattern & 0b10000000) ? HIGH : LOW);
digitalWrite(SEG_B, (pattern & 0b01000000) ? HIGH : LOW);
digitalWrite(SEG_C, (pattern & 0b00100000) ? HIGH : LOW);
digitalWrite(SEG_D, (pattern & 0b00010000) ? HIGH : LOW);
digitalWrite(SEG_E, (pattern & 0b00001000) ? HIGH : LOW);
digitalWrite(SEG_F, (pattern & 0b00000100) ? HIGH : LOW);
digitalWrite(SEG_G, (pattern & 0b00000010) ? HIGH : LOW);
// Matikan titik desimal
digitalWrite(SEG_DP, LOW);
// Tunggu sebentar untuk multiplexing
delayMicroseconds(500);
// Matikan digit
digitalWrite(digitPin, LOW);
}
// Fungsi untuk mematikan semua digit
void turnOffAllDigits() {
digitalWrite(DIGIT_1, LOW);
digitalWrite(DIGIT_2, LOW);
digitalWrite(DIGIT_3, LOW);
digitalWrite(DIGIT_4, LOW);
}
// Fungsi untuk refresh display (multiplexing)
void refreshDisplay() {
// Display sudah di-refresh di fungsi displayNumber
// Fungsi ini menjaga kompatibilitas dengan struktur loop
}
// Fungsi untuk mematikan semua lampu
void allLightsOff() {
digitalWrite(RED_1, LOW);
digitalWrite(YELLOW_1, LOW);
digitalWrite(GREEN_1, LOW);
digitalWrite(RED_2, LOW);
digitalWrite(YELLOW_2, LOW);
digitalWrite(GREEN_2, LOW);
digitalWrite(RED_3, LOW);
digitalWrite(YELLOW_3, LOW);
digitalWrite(GREEN_3, LOW);
}
// Fungsi untuk konversi state ke string
String stateToString(TrafficState state) {
switch(state) {
case STATE_GREEN: return "Hijau";
case STATE_YELLOW: return "Kuning";
case STATE_RED: return "Merah";
default: return "Unknown";
}
}