Lampu Lalu Lintas Arduino: Rangkaian, Kode, Tombol Pejalan Kaki, dan Persimpangan
Buat lampu lalu lintas Arduino: pengkabelan 3 LED dan 220 Ω, kode delay dan millis, tombol pejalan kaki, persimpangan dua arah, Tinkercad, serta versi ESP32 dan Pico.
Lampu lalu lintas Arduino adalah proyek pertama klasik di elektronika: tiga LED, merah, kuning, dan hijau, menyala dan padam bergantian persis seperti lampu lalu lintas sungguhan. Yang kamu butuhkan hanya Arduino Uno, tiga LED, tiga resistor 220 Ω, dan beberapa kabel jumper, dan versi pertamamu yang berfungsi selesai dalam setengah jam. Namun proyek sederhana ini mengajarkan banyak hal: output digital, hitungan LED dan resistor, pengaturan waktu, membaca tombol, dan state machine, cara paling rapi untuk menyusun kodemu, semuanya muat dalam beberapa LED ini.
Di panduan ini kamu akan melihat dulu dalam urutan apa dan berapa lama lampu lalu lintas sungguhan berganti, lalu merakit rangkaian dan menulis kode paling sederhana dengan delay(). Setelah itu kamu akan menambahkan push button pejalan kaki, menulis ulang logika yang sama dengan millis() dan state machine agar tidak pernah memblokir, dan mengendalikan persimpangan dua arah. Bagian terakhir menunjukkan cara mencoba proyek ini di Tinkercad tanpa menginstal apa pun, versi ESP32 dan Raspberry Pi Pico (MicroPython), serta tips menulis laporan sekolah tentang proyek ini.

Bagaimana cara kerja lampu lalu lintas sungguhan?
Lampu lalu lintas adalah timer yang memberi giliran pada setiap arus lalu lintas. Di Inggris, Jerman, dan Turki siklusnya merah → merah + kuning (amber) → hijau → kuning → merah. Merah dan kuning bersamaan berarti “hijau segera menyala, bersiaplah, tapi jangan jalan dulu”, sedangkan kuning sendirian berarti “lampu akan menjadi merah, bersiaplah berhenti”. Di Amerika Serikat, Prancis, Italia, dan Spanyol tidak ada fase merah + kuning: lampu langsung berpindah dari merah ke hijau. Lama lampu kuning juga tidak asal: aturan Jerman menetapkan kuning 3 detik di jalan dengan batas 50 km/jam, 4 detik di 60 km/jam, dan 5 detik di 70 km/jam, karena pengemudi yang sudah terlalu dekat untuk berhenti ketika kuning menyala harus tetap bisa keluar dari persimpangan dengan aman.
| Fase | Lampu yang menyala | Arti | Lama di panduan ini |
|---|---|---|---|
| 1 | Merah | Berhenti | 5 dtk |
| 2 | Merah + kuning | Hijau segera menyala, bersiaplah | 1 dtk |
| 3 | Hijau | Jalan | 5 dtk |
| 4 | Kuning | Merah segera menyala, berhenti | 3 dtk |
| Di persimpangan | Semua arah merah | Jeda aman untuk mengosongkan persimpangan | 1 dtk |
Daftar komponen dan perhitungan resistor 220 Ω
| Komponen | Jml | Catatan |
|---|---|---|
| Arduino Uno (atau Nano) | 1 | ESP32 atau Raspberry Pi Pico juga bisa |
| LED 5 mm: merah, kuning, hijau | Masing-masing 1 | +1 merah dan +1 hijau untuk lampu pejalan kaki, +1 set untuk persimpangan |
| Resistor 220 Ω | 3 | Satu per LED; 8 untuk semua versi |
| Push button (6×6 mm) | 1 | Hanya untuk versi pejalan kaki |
| Breadboard | 1 | Ukuran setengah (400 lubang) sudah cukup |
| Kabel jumper | 10–20 | Male ke male |
| Kabel USB | 1 | Untuk meng-upload kode dan memberi daya board |
LED tidak membatasi arusnya sendiri; LED yang disambungkan langsung ke 5 V menarik arus lebih besar daripada yang sanggup ditahan LED dan pin. Karena itu setiap LED diberi resistor seri. Nilainya kamu cari dengan hukum Ohm: R = (tegangan catu − tegangan maju LED) / arus. Untuk LED merah, (5 V − 2,0 V) / 0,015 A ≈ 200 Ω; dengan nilai standar terdekat, 220 Ω, arusnya sekitar 13,6 mA. Itu cukup untuk menyalakan LED dengan terang dan tetap di bawah 20 mA yang dianjurkan untuk pin Arduino. Resistor 220 Ω ditandai merah-merah-cokelat-emas pada komponen empat gelang dan merah-merah-hitam-hitam-cokelat pada komponen lima gelang; supaya yakin, pakai alat kode warna resistor, dan untuk warna serta tegangan lain pakai kalkulator resistor LED.
| Warna LED | Tegangan maju (perkiraan) | Arus di 5 V (220 Ω) | Arus di 3,3 V (220 Ω) |
|---|---|---|---|
| Merah | 1,8–2,2 V | ≈ 13,6 mA | ≈ 5,9 mA |
| Kuning | 1,9–2,2 V | ≈ 13,2 mA | ≈ 5,5 mA |
| Hijau (hijau kekuningan) | 2,0–2,4 V | ≈ 13,2 mA | ≈ 5,5 mA |
| Hijau (terang, hijau murni) | 2,8–3,4 V | ≈ 9,1 mA | ≈ 1,4 mA (sangat redup) |
Pengkabelan rangkaian dan tabel pin
Kaki panjang setiap LED (anoda, +) disambungkan lewat resistor ke pin digital Arduino, dan kaki pendeknya (katoda, −) ke GND. Tidak masalah resistornya di sisi anoda atau katoda, asalkan dipasang seri. Di breadboard, cara paling rapi adalah menyambungkan pin GND Arduino ke jalur biru (−) dan membawa kaki pendek ketiga LED ke jalur itu. Tabel di bawah mencantumkan pin yang dipakai semua sketch di panduan ini; sketch pertama hanya memakai tiga baris pertama. Kamu bisa melihat tata letak pin board-mu di alat Pinout.
| Fungsi | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Merah kendaraan (arah A) | D10 | GPIO 5 | GP13 |
| Kuning kendaraan (arah A) | D9 | GPIO 18 | GP12 |
| Hijau kendaraan (arah A) | D8 | GPIO 19 | GP11 |
| Merah pejalan kaki | D7 | GPIO 21 | GP15 |
| Hijau pejalan kaki | D6 | GPIO 22 | GP14 |
| Tombol pejalan kaki (kaki lainnya ke GND) | D2 | GPIO 23 | GP4 |
| Merah / kuning / hijau arah B | D5 / D4 / D3 | GPIO 25 / 26 / 27 | GP8 / GP7 / GP6 |
| Katoda LED dan tombol | GND | GND | GND |
Langkah 1: kode lampu lalu lintas paling sederhana dengan delay()
1// Arduino trafik lambası: delay() ile en basit sürüm / simplest version with delay()
2const int KIRMIZI = 10; // kırmızı LED / red LED
3const int SARI = 9; // sarı LED / yellow LED
4const int YESIL = 8; // yeşil LED / green LED
5
6// Üç LED'i tek satırda ayarla / set all three LEDs in one line
7void lambalar(int k, int s, int y) {
8 digitalWrite(KIRMIZI, k);
9 digitalWrite(SARI, s);
10 digitalWrite(YESIL, y);
11}
12
13void setup() {
14 pinMode(KIRMIZI, OUTPUT);
15 pinMode(SARI, OUTPUT);
16 pinMode(YESIL, OUTPUT);
17}
18
19void loop() {
20 lambalar(HIGH, LOW, LOW); // DUR: kırmızı / STOP: red
21 delay(5000);
22 lambalar(HIGH, HIGH, LOW); // HAZIRLAN: kırmızı + sarı / GET READY: red + yellow
23 delay(1000);
24 lambalar(LOW, LOW, HIGH); // GEÇ: yeşil / GO: green
25 delay(5000);
26 lambalar(LOW, HIGH, LOW); // YAVAŞLA: sarı / SLOW DOWN: yellow
27 delay(3000);
28}Sketch ini mengatur ketiga pin sebagai output di setup() dan menjalankan empat fase berurutan di dalam loop(). Alih-alih menulis tiga baris digitalWrite berulang-ulang, kita memakai fungsi kecil bernama lambalar() (“lampu-lampu”), sehingga setiap fase terbaca sebagai satu baris dan kesalahan mudah terlihat. Untuk meng-upload, pilih Arduino Uno sebagai board dan port yang benar di menu Tools, lalu klik Upload. Jika upload gagal, ikuti daftar periksa di Kode Arduino gagal di-upload. Untuk mengubah waktunya, cukup ubah nilai milidetik di dalam delay(): 5000 berarti 5 detik.
Langkah 2: lampu lalu lintas dengan push button pejalan kaki
Penyeberangan dengan tombol yang kamu lihat di kota membuat mobil tetap mendapat hijau dan hanya memberi giliran pada pejalan kaki ketika seseorang menekan tombol. Di versi ini kita menambahkan lampu pejalan kaki dua LED (merah dan hijau) dan tombol di D2 ke lampu kendaraan. Satu kaki tombol ke D2 dan kaki yang berseberangan secara diagonal ke GND; karena kodenya memakai INPUT_PULLUP, tidak perlu resistor eksternal dan pin terbaca LOW selama tombol ditekan. Kamu bisa membaca lebih lanjut tentang sambungan internal tombol berkaki empat dan tentang debounce di Cara Menghubungkan Push Button ke Arduino.

1// Yaya butonlu trafik lambası (delay ile) / pedestrian push-button light (with delay)
2const int KIRMIZI = 10, SARI = 9, YESIL = 8; // araç lambası / vehicle light
3const int YAYA_KIRMIZI = 7, YAYA_YESIL = 6; // yaya lambası / pedestrian light
4const int BUTON = 2; // diğer ucu GND / other leg to GND
5
6void setup() {
7 pinMode(KIRMIZI, OUTPUT);
8 pinMode(SARI, OUTPUT);
9 pinMode(YESIL, OUTPUT);
10 pinMode(YAYA_KIRMIZI, OUTPUT);
11 pinMode(YAYA_YESIL, OUTPUT);
12 pinMode(BUTON, INPUT_PULLUP); // basılınca LOW okunur / reads LOW when pressed
13 digitalWrite(YESIL, HIGH); // araçlar geçer / cars go
14 digitalWrite(YAYA_KIRMIZI, HIGH); // yayalar bekler / pedestrians wait
15}
16
17void loop() {
18 if (digitalRead(BUTON) == LOW) { // yaya butona bastı / pedestrian pressed
19 delay(2000); // araçlara kısa süre tanı / short grace time for cars
20 digitalWrite(YESIL, LOW);
21 digitalWrite(SARI, HIGH); // sarı / yellow
22 delay(3000);
23 digitalWrite(SARI, LOW);
24 digitalWrite(KIRMIZI, HIGH); // araçlar durur / cars stop
25 delay(1000); // tüm kırmızı güvenlik payı / all-red safety gap
26 digitalWrite(YAYA_KIRMIZI, LOW);
27 digitalWrite(YAYA_YESIL, HIGH); // yayalar geçer / pedestrians cross
28 delay(6000);
29 for (int i = 0; i < 6; i++) { // yaya yeşili 3 kez yanıp söner / green man flashes 3 times
30 digitalWrite(YAYA_YESIL, i % 2 == 0 ? LOW : HIGH);
31 delay(500);
32 }
33 digitalWrite(YAYA_YESIL, LOW);
34 digitalWrite(YAYA_KIRMIZI, HIGH);
35 delay(1000); // tüm kırmızı / all red
36 digitalWrite(SARI, HIGH); // kırmızı + sarı / red + yellow
37 delay(1000);
38 digitalWrite(KIRMIZI, LOW);
39 digitalWrite(SARI, LOW);
40 digitalWrite(YESIL, HIGH); // araçlar yeniden geçer / cars go again
41 delay(8000); // en kısa yeşil süresi / minimum green time
42 }
43}Sketch ini berfungsi, tapi punya kelemahan serius: begitu tombol ditekan, Arduino menghabiskan sekitar 25 detik tertahan di baris-baris delay(). Tekanan kedua selama waktu itu tidak terdeteksi, tidak ada yang bisa dibaca dari port serial, dan tidak ada layar yang bisa diperbarui. Tekanan selama jeda 8 detik di akhir hilang sama sekali: pejalan kaki menekan dan melepas, tidak terjadi apa-apa, dan ia harus menekan lagi. Menambahkan suara atau hitung mundur membuat struktur ini makin sulit dikerjakan. Solusinya adalah berhenti menunggu dan mulai mengukur waktu.
Langkah 3: kode tanpa blocking dengan millis() dan state machine
State machine adalah desain di mana sistem selalu berada di tepat satu keadaan (state) dan berpindah ke keadaan berikutnya ketika syarat tertentu terpenuhi. Lampu lalu lintas adalah contoh sempurna: “hijau untuk mobil”, “kuning untuk mobil”, dan “pejalan kaki menyeberang” masing-masing adalah satu keadaan. Kodenya tidak lagi menunggu dengan delay(); di setiap putaran loop() hanya mengajukan dua pertanyaan: aku di keadaan mana, dan sudah berapa lama aku di sini? Waktu yang berlalu diukur dengan millis() - durumBaslangic (momen keadaan dimulai), dan ketika waktunya habis kode berpindah. Jika millis() masih baru bagimu, baca dulu Arduino millis() vs delay(). Menulis keadaan-keadaan ke dalam tabel sebelum coding membuat pekerjaannya jauh lebih mudah:
| Keadaan | Lampu kendaraan | Lampu pejalan kaki | Lama | Keadaan berikutnya |
|---|---|---|---|---|
| ARAC_YESIL (kendaraan hijau) | Hijau | Merah | Minimal 8 dtk, sampai ada permintaan | ARAC_SARI (kendaraan kuning) |
| ARAC_SARI (kendaraan kuning) | Kuning | Merah | 3 dtk | YAYA_BEKLE (pejalan kaki menunggu) |
| YAYA_BEKLE (pejalan kaki menunggu) | Merah | Merah | 1 dtk | YAYA_GECER (pejalan kaki menyeberang) |
| YAYA_GECER (pejalan kaki menyeberang) | Merah | Hijau | 6 dtk | YAYA_FLAS (hijau pejalan kaki berkedip) |
| YAYA_FLAS (hijau pejalan kaki berkedip) | Merah | Hijau berkedip | 3 dtk | YAYA_BITTI (penyeberangan selesai) |
| YAYA_BITTI (penyeberangan selesai) | Merah | Merah | 1 dtk | KIRMIZI_SARI (merah + kuning) |
| KIRMIZI_SARI (merah + kuning) | Merah + kuning | Merah | 1 dtk | ARAC_YESIL (kendaraan hijau) |
1// Yaya butonlu trafik lambası: millis() + durum makinesi / pedestrian light: millis() + state machine
2const int KIRMIZI = 10, SARI = 9, YESIL = 8; // araç lambası / vehicle light
3const int YAYA_KIRMIZI = 7, YAYA_YESIL = 6; // yaya lambası / pedestrian light
4const int BUTON = 2; // diğer ucu GND / other leg to GND
5
6enum Durum { ARAC_YESIL, ARAC_SARI, YAYA_BEKLE, YAYA_GECER, YAYA_FLAS, YAYA_BITTI, KIRMIZI_SARI };
7const char* const ISIM[] = { "ARAC_YESIL", "ARAC_SARI", "YAYA_BEKLE", "YAYA_GECER",
8 "YAYA_FLAS", "YAYA_BITTI", "KIRMIZI_SARI" };
9
10// Süreler (ms) / durations (ms)
11const unsigned long MIN_YESIL = 8000; // araçlara en az yeşil / minimum green for cars
12const unsigned long SARI_SURE = 3000; // sarı / yellow
13const unsigned long GUVENLIK = 1000; // tüm kırmızı / all red
14const unsigned long YAYA_SURE = 6000; // yaya yeşili / pedestrian green
15const unsigned long FLAS_SURE = 3000; // yanıp sönen yaya yeşili / flashing green man
16const unsigned long KS_SURE = 1000; // kırmızı + sarı / red + yellow
17
18Durum durum = ARAC_YESIL;
19unsigned long durumBaslangic = 0; // durumun başladığı an / when the state started
20bool yayaTalebi = false; // butona basıldı mı? / was the button pressed?
21
22void aracLamba(bool k, bool s, bool y) {
23 digitalWrite(KIRMIZI, k);
24 digitalWrite(SARI, s);
25 digitalWrite(YESIL, y);
26}
27
28void yayaLamba(bool k, bool y) {
29 digitalWrite(YAYA_KIRMIZI, k);
30 digitalWrite(YAYA_YESIL, y);
31}
32
33// Yeni duruma geç: lambaları ayarla, saati başlat / enter a state: set the lamps, restart the clock
34void gec(Durum yeni) {
35 durum = yeni;
36 durumBaslangic = millis();
37 switch (yeni) {
38 case ARAC_YESIL: aracLamba(0, 0, 1); yayaLamba(1, 0); break;
39 case ARAC_SARI: aracLamba(0, 1, 0); yayaLamba(1, 0); break;
40 case YAYA_BEKLE: aracLamba(1, 0, 0); yayaLamba(1, 0); break;
41 case YAYA_GECER: aracLamba(1, 0, 0); yayaLamba(0, 1); yayaTalebi = false; break;
42 case YAYA_FLAS: aracLamba(1, 0, 0); yayaLamba(0, 1); break;
43 case YAYA_BITTI: aracLamba(1, 0, 0); yayaLamba(1, 0); break;
44 case KIRMIZI_SARI: aracLamba(1, 1, 0); yayaLamba(1, 0); break;
45 }
46 Serial.println(ISIM[yeni]); // durum günlüğü / state log
47}
48
49void setup() {
50 Serial.begin(9600);
51 pinMode(KIRMIZI, OUTPUT);
52 pinMode(SARI, OUTPUT);
53 pinMode(YESIL, OUTPUT);
54 pinMode(YAYA_KIRMIZI, OUTPUT);
55 pinMode(YAYA_YESIL, OUTPUT);
56 pinMode(BUTON, INPUT_PULLUP);
57 gec(ARAC_YESIL);
58}
59
60void loop() {
61 unsigned long gecen = millis() - durumBaslangic; // bu durumda geçen süre / time spent in this state
62
63 // yaya yeşili yanarken basış yok sayılır / presses during the green man are ignored
64 if (digitalRead(BUTON) == LOW && durum != YAYA_GECER) {
65 yayaTalebi = true; // talebi hatırla / remember the request
66 }
67
68 switch (durum) {
69 case ARAC_YESIL:
70 if (yayaTalebi && gecen >= MIN_YESIL) gec(ARAC_SARI);
71 break;
72 case ARAC_SARI:
73 if (gecen >= SARI_SURE) gec(YAYA_BEKLE);
74 break;
75 case YAYA_BEKLE:
76 if (gecen >= GUVENLIK) gec(YAYA_GECER);
77 break;
78 case YAYA_GECER:
79 if (gecen >= YAYA_SURE) gec(YAYA_FLAS);
80 break;
81 case YAYA_FLAS:
82 digitalWrite(YAYA_YESIL, (gecen / 250) % 2 == 0); // 250 ms'de bir yanıp söner / toggles every 250 ms
83 if (gecen >= FLAS_SURE) gec(YAYA_BITTI);
84 break;
85 case YAYA_BITTI:
86 if (gecen >= GUVENLIK) gec(KIRMIZI_SARI);
87 break;
88 case KIRMIZI_SARI:
89 if (gecen >= KS_SURE) gec(ARAC_YESIL);
90 break;
91 }
92}Jantung sketch ini adalah fungsi gec() (“pindah ke”): fungsi ini menyimpan keadaan baru, mengulang timer, mengatur lampu untuk keadaan itu, dan mencetak nama keadaan ke Serial Monitor. Switch di dalam loop() hanya mengecek apakah waktunya sudah habis. Menekan tombol tidak langsung memicu apa pun; tombol menaikkan flag yayaTalebi (permintaan pejalan kaki), dan siklus dimulai begitu mobil sudah mendapat hijau minimal 8 detik. Sekarang tekanan tombol tidak pernah hilang, dan karena tombol hanya mengubah flag, pantulan kontak juga tidak menimbulkan masalah. Tekanan ketika lampu hijau pejalan kaki sudah menyala diabaikan; kalau tidak, siklus baru yang tidak perlu akan dimulai tepat setelah pejalan kaki menyeberang. Buka Serial Monitor di 9600 baud untuk melihat nama setiap perpindahan; output ini membantu ketika mencari bug sekaligus untuk laporan sekolahmu.
Langkah 4: persimpangan dua arah
Di persimpangan sungguhan, lampu kedua jalan saling terhubung: ketika jalan A hijau, jalan B harus merah. Versi ini memakai enam LED: D10, D9, dan D8 untuk arah A, serta D5, D4, dan D3 untuk arah B. Detail penting adalah jeda pengosongan semua merah yang singkat: ketika satu arah menjadi merah, arah lainnya tidak langsung hijau; pengendali menunggu 1 detik agar kendaraan yang masih di dalam persimpangan bisa keluar. Kali ini keadaan-keadaan masuk ke tabel (array), bukan switch; untuk setiap langkah, lampu yang menyala disimpan sebagai bit dalam satu byte, dan lamanya dalam milidetik.
1// İki yönlü kavşak: tablo tabanlı durum makinesi / two-way junction: table-driven state machine
2const byte A_KIRMIZI = 10, A_SARI = 9, A_YESIL = 8; // A yönü (ana yol) / direction A (main road)
3const byte B_KIRMIZI = 5, B_SARI = 4, B_YESIL = 3; // B yönü (ara yol) / direction B (side road)
4const byte PINLER[6] = { A_KIRMIZI, A_SARI, A_YESIL, B_KIRMIZI, B_SARI, B_YESIL };
5
6struct Adim {
7 byte maske; // bit sırası: A_K A_S A_Y B_K B_S B_Y / bit order: A_R A_Y A_G B_R B_Y B_G
8 unsigned long sure; // ms
9};
10
11const Adim PLAN[] = {
12 { 0b001100, 8000 }, // A yeşil, B kırmızı / A green, B red
13 { 0b010100, 3000 }, // A sarı, B kırmızı / A yellow, B red
14 { 0b100100, 1000 }, // tüm yönler kırmızı / all red
15 { 0b100110, 1000 }, // A kırmızı, B kırmızı + sarı / A red, B red + yellow
16 { 0b100001, 5000 }, // A kırmızı, B yeşil / A red, B green
17 { 0b100010, 3000 }, // A kırmızı, B sarı / A red, B yellow
18 { 0b100100, 1000 }, // tüm yönler kırmızı / all red
19 { 0b110100, 1000 }, // A kırmızı + sarı, B kırmızı / A red + yellow, B red
20};
21const byte ADIM_SAYISI = sizeof(PLAN) / sizeof(PLAN[0]);
22
23byte adim = 0;
24unsigned long adimBaslangic = 0;
25
26void uygula(byte maske) {
27 if ((maske & 0b001000) && (maske & 0b000001)) { // iki yeşil aynı anda yanamaz / never two greens
28 maske = 0b100100; // güvenli durum: tüm kırmızı / fail-safe: all red
29 }
30 for (byte i = 0; i < 6; i++) {
31 digitalWrite(PINLER[i], (maske >> (5 - i)) & 1); // soldaki bit A_KIRMIZI / leftmost bit is A_RED
32 }
33}
34
35void setup() {
36 for (byte i = 0; i < 6; i++) pinMode(PINLER[i], OUTPUT);
37 uygula(PLAN[0].maske);
38 adimBaslangic = millis();
39}
40
41void loop() {
42 if (millis() - adimBaslangic >= PLAN[adim].sure) {
43 adimBaslangic += PLAN[adim].sure; // kaymasız zamanlama / drift-free timing
44 adim = (adim + 1) % ADIM_SAYISI;
45 uygula(PLAN[adim].maske);
46 }
47 // Burada buton, sensör ya da ekran işleri çalışabilir / buttons, sensors or a display can run here
48}Setiap baris array PLAN adalah satu langkah. Pada bilangan biner seperti 0b001100, bit dari kiri ke kanan mewakili A merah, A kuning, A hijau, B merah, B kuning, dan B hijau; 1 berarti nyala dan 0 berarti mati. Fungsi uygula() (“terapkan”) menulis enam bit ini ke pin secara berurutan. Pengecekan di awal fungsi mencegah salah ketik menampilkan hijau di kedua arah sekaligus dan sebagai gantinya membuat persimpangan menjadi semua merah. Pengendali persimpangan sungguhan juga punya rangkaian pengaman terpisah yang menangkap hijau yang bertabrakan. Untuk mengubah waktu atau menambah langkah, kamu hanya mengubah tabelnya dan tidak pernah menyentuh sisa kode. Jika pin-mu habis karena jumlah LED bertambah, shift register 74HC595 memberimu delapan output dari tiga pin.
Coba di Tinkercad: simulasi tanpa komponen apa pun
- Buat akun gratis di tinkercad.com dan mulai rangkaian baru di bagian Circuits.
- Seret Arduino Uno R3, breadboard, tiga LED, dan tiga resistor dari daftar komponen di sebelah kanan. Klik LED untuk memilih warnanya dan resistor untuk mengatur nilainya menjadi 220 Ω.
- Gambar kabelnya: anoda LED lewat resistor ke D10, D9, dan D8, katoda ke GND. Mengatur warna kabel (misalnya hitam untuk GND) membuat skemanya mudah dibaca.
- Klik Code, pilih Text dari menu drop-down, hapus kode contoh, dan tempel sketch dari panduan ini.
- Klik Start Simulation; LED mulai berganti secara berurutan. Output serial muncul di Serial Monitor di bagian bawah panel kode.
Tinkercad adalah cara termudah untuk menguji pengkabelan dan kode sebelum merakit dengan komponen sungguhan; jika kamu lupa resistor, simulator menampilkan peringatan di LED bahwa arusnya terlalu tinggi. Untuk menguji versi pejalan kaki, cukup klik tombolnya dengan mouse selama simulasi berjalan. Di komputer yang lambat, simulasi bisa berjalan lebih lambat dari waktu nyata, jadi waktunya mungkin terlihat sedikit lebih lama. Untuk tugas sekolah, kamu bisa menyerahkan tautan berbagi Tinkercad atau tangkapan layar rangkaiannya. Untuk petunjuk rinci lihat simulasi Arduino di Tinkercad, dan untuk alternatif yang juga mendukung ESP32 dan Pico, lihat Wokwi.
Lampu lalu lintas ESP32 dengan mode malam
Sketch Arduino di panduan ini juga berjalan di ESP32: pilih ESP32 Dev Module sebagai board di Arduino IDE dan ubah konstanta pin seperti di tabel. Versi di bawah menambahkan satu fitur: mode malam. Pada jam-jam sepi, banyak persimpangan beralih ke kuning berkedip. Board ESP32 DevKit punya tombol BOOT yang tersambung ke GPIO 0, jadi kamu bahkan tidak butuh tombol tambahan: begitu board sudah menyala, tombol itu bisa dibaca seperti input biasa. Setiap tekanan berganti antara mode normal dan mode malam.
1// ESP32 trafik lambası + gece modu (BOOT düğmesi) / ESP32 traffic light + night mode (BOOT button)
2const int KIRMIZI = 5; // GPIO 5
3const int SARI = 18; // GPIO 18
4const int YESIL = 19; // GPIO 19
5const int BOOT_BUTON = 0; // kart üzerindeki BOOT düğmesi / on-board BOOT button
6
7struct Adim { bool k, s, y; unsigned long sure; };
8const Adim PLAN[] = {
9 { true, false, false, 5000 }, // kırmızı / red
10 { true, true, false, 1000 }, // kırmızı + sarı / red + yellow
11 { false, false, true, 5000 }, // yeşil / green
12 { false, true, false, 3000 }, // sarı / yellow
13};
14const int ADIM_SAYISI = sizeof(PLAN) / sizeof(PLAN[0]);
15
16int adim = 0;
17unsigned long adimBaslangic = 0;
18bool geceModu = false;
19int sonOkuma = HIGH, kararli = HIGH; // debounce için / for debouncing
20unsigned long degisimZamani = 0;
21
22void lambalar(bool k, bool s, bool y) {
23 digitalWrite(KIRMIZI, k);
24 digitalWrite(SARI, s);
25 digitalWrite(YESIL, y);
26}
27
28void setup() {
29 Serial.begin(115200);
30 pinMode(KIRMIZI, OUTPUT);
31 pinMode(SARI, OUTPUT);
32 pinMode(YESIL, OUTPUT);
33 pinMode(BOOT_BUTON, INPUT_PULLUP);
34 lambalar(PLAN[0].k, PLAN[0].s, PLAN[0].y);
35 adimBaslangic = millis();
36}
37
38void loop() {
39 unsigned long simdi = millis();
40
41 // 50 ms kararlı kalan basışı kabul et / accept a press that stays stable for 50 ms
42 int okuma = digitalRead(BOOT_BUTON);
43 if (okuma != sonOkuma) {
44 sonOkuma = okuma;
45 degisimZamani = simdi;
46 }
47 if (simdi - degisimZamani >= 50 && okuma != kararli) {
48 kararli = okuma;
49 if (kararli == LOW) { // yeni basış / new press
50 geceModu = !geceModu;
51 Serial.println(geceModu ? "Gece modu / Night mode" : "Normal mod / Normal mode");
52 adim = 0; // normal mod kırmızıdan başlar / normal mode restarts on red
53 adimBaslangic = simdi;
54 lambalar(PLAN[0].k, PLAN[0].s, PLAN[0].y);
55 }
56 }
57
58 if (geceModu) {
59 lambalar(false, (simdi / 500) % 2 == 0, false); // yanıp sönen sarı / flashing yellow
60 return;
61 }
62
63 if (simdi - adimBaslangic >= PLAN[adim].sure) {
64 adimBaslangic = simdi;
65 adim = (adim + 1) % ADIM_SAYISI;
66 lambalar(PLAN[adim].k, PLAN[adim].s, PLAN[adim].y);
67 }
68}Pembacaan tombol sudah termasuk debounce sederhana: tekanan hanya dihitung jika pembacaannya tidak berubah selama 50 ms. Tabel PLAN yang berisi keadaan lampu adalah bentuk yang lebih mudah dibaca dari ide yang dipakai di sketch persimpangan. Karena pin ESP32 mengeluarkan 3,3 V, LED menarik arus lebih kecil daripada di Arduino dan terlihat sedikit lebih redup. LED merah dan kuning cukup terang dengan 220 Ω, tapi LED hijau terang dengan tegangan maju sekitar 3 V bisa tetap sangat redup; dalam kasus itu turunkan resistor hijau menjadi 100 Ω. Jika kamu baru mengenal ESP32, Apa Itu ESP32? adalah tempat yang bagus untuk mulai, untuk instalasi dan pin yang aman.
Lampu lalu lintas pejalan kaki dengan Raspberry Pi Pico (MicroPython)
Di Raspberry Pi Pico kita menulis state machine yang sama dengan MicroPython. Kali ini keadaan-keadaan disimpan dalam list: setiap baris berisi nama keadaan, nilai kelima lampu, dan lamanya. Tombol memakai interupsi: ketika GP4 turun ke LOW, fungsi buton_kesmesi() (“interupsi tombol”) berjalan dan hanya menaikkan flag permintaan. Jika kamu menyimpan kodenya ke Pico sebagai main.py dengan Thonny, kode itu berjalan otomatis setiap kali board menyala.
1# Raspberry Pi Pico (MicroPython): yaya butonlu trafik lambası / pedestrian traffic light
2from machine import Pin
3import time
4
5yesil = Pin(11, Pin.OUT) # araç yeşil / vehicle green
6sari = Pin(12, Pin.OUT) # araç sarı / vehicle yellow
7kirmizi = Pin(13, Pin.OUT) # araç kırmızı / vehicle red
8yaya_yesil = Pin(14, Pin.OUT) # yaya yeşil / pedestrian green
9yaya_kirmizi = Pin(15, Pin.OUT) # yaya kırmızı / pedestrian red
10buton = Pin(4, Pin.IN, Pin.PULL_UP) # GP4, diğer ucu GND / other leg to GND
11
12# (durum, kırmızı, sarı, yeşil, yaya kırmızı, yaya yeşil, süre ms)
13# (state, red, yellow, green, ped red, ped green, duration ms)
14DURUMLAR = [
15 ("ARAC_YESIL", 0, 0, 1, 1, 0, 8000), # en az yeşil süresi / minimum green
16 ("ARAC_SARI", 0, 1, 0, 1, 0, 3000),
17 ("YAYA_BEKLE", 1, 0, 0, 1, 0, 1000), # tüm kırmızı / all red
18 ("YAYA_GECER", 1, 0, 0, 0, 1, 6000),
19 ("YAYA_FLAS", 1, 0, 0, 0, 1, 3000),
20 ("YAYA_BITTI", 1, 0, 0, 1, 0, 1000), # tüm kırmızı / all red
21 ("KIRMIZI_SARI", 1, 1, 0, 1, 0, 1000),
22]
23
24talep = False
25adim = 0 # şu anki durumun sırası / index of the current state
26
27def buton_kesmesi(pin): # kesmede yalnız bayrak kaldır / only set a flag in the IRQ
28 global talep
29 if DURUMLAR[adim][0] != "YAYA_GECER": # yaya yeşilinde basış yok sayılır / ignored during the green man
30 talep = True
31
32buton.irq(trigger=Pin.IRQ_FALLING, handler=buton_kesmesi)
33
34def uygula(i):
35 global talep
36 ad, k, s, y, yk, yy, _ = DURUMLAR[i]
37 kirmizi.value(k)
38 sari.value(s)
39 yesil.value(y)
40 yaya_kirmizi.value(yk)
41 yaya_yesil.value(yy)
42 if ad == "YAYA_GECER":
43 talep = False # talep karşılandı / request served
44 print("Durum / state:", ad)
45
46uygula(adim)
47baslangic = time.ticks_ms()
48
49while True:
50 gecen = time.ticks_diff(time.ticks_ms(), baslangic) # taşmaya karşı güvenli / wrap-safe
51 ad = DURUMLAR[adim][0]
52
53 if ad == "YAYA_FLAS":
54 yaya_yesil.value((gecen // 250) % 2 == 0) # yanıp sönen yaya yeşili / flashing green man
55
56 if gecen >= DURUMLAR[adim][6] and (ad != "ARAC_YESIL" or talep):
57 adim = (adim + 1) % len(DURUMLAR) # yeşil, talep gelene kadar sürer / green lasts until a request
58 uygula(adim)
59 baslangic = time.ticks_ms()
60
61 time.sleep_ms(10)Di MicroPython kamu memakai time.ticks_ms() sebagai ganti millis() dan time.ticks_diff() sebagai ganti pengurangan biasa; penghitung ticks kembali ke awal setelah nilai tertentu, jadi mengurangkan dua pembacaan secara langsung bisa memberi hasil yang salah. Buat handler interupsi tetap pendek: tanpa print, tanpa sleep, dan tanpa perhitungan panjang, cukup ubah flag. Pin Pico juga bekerja di 3,3 V, jadi catatan LED hijau dari bagian ESP32 juga berlaku di sini. Kamu akan menemukan cara menginstal MicroPython dan penomoran pin di Apa Itu Raspberry Pi Pico?, dan dasar-dasar bahasanya di dasar-dasar MicroPython.
Kesalahan umum dan cara memperbaikinya
| Gejala | Kemungkinan penyebab | Solusi |
|---|---|---|
| Tidak ada LED yang menyala | GND tidak tersambung, atau jalur daya breadboard terputus di tengah | Sambungkan GND Arduino ke jalur biru; jembatani kedua bagian pada breadboard panjang |
| Satu LED tetap gelap | LED terbalik atau tersambung ke pin yang salah | Kaki panjang (anoda) lewat resistor ke pin, kaki pendek ke GND; cocokkan nomor pin dengan kode |
| Warna yang salah menyala | Pin merah dan hijau tertukar di kode | Perbaiki kabel atau konstantanya sesuai tabel pin |
| LED sangat terang dan menjadi hangat | Tidak ada resistor yang dipasang | Tambahkan resistor seri 220 Ω ke setiap LED |
| Tombol tidak berpengaruh atau selalu terbaca ditekan | Tombol dipasang di dua kaki yang sudah tersambung di dalam, atau INPUT_PULLUP terlupa | Pakai kaki diagonal dan tulis pinMode(BUTON, INPUT_PULLUP) |
| Tidak ada reaksi langsung terhadap tombol | Waktu hijau minimum untuk mobil belum habis | Bukan bug; kecilkan MIN_YESIL |
| Program kacau setelah beberapa lama | Variabel waktu dideklarasikan sebagai int | Deklarasikan setiap variabel yang dipakai dengan millis() sebagai unsigned long |
Tips untuk tugas sekolah dan laporan proyekmu
Lampu lalu lintas adalah salah satu tugas Arduino yang paling umum di pelajaran sains, teknologi, dan robotika. Gurumu biasanya ingin melihat bukan hanya rangkaian yang berfungsi, tapi juga bahwa kamu memahaminya dan bisa menjelaskannya. Jika kamu menyusun laporan dengan bagian-bagian berikut, laporanmu akan terlihat rapi dan tidak ada hal penting yang terlewat:
- Tujuan: Jelaskan dalam satu atau dua kalimat apa yang ditunjukkan proyek ini, misalnya “mengatur waktu lampu lalu lintas dengan output digital”.
- Daftar komponen: Tulis nama, jumlah, dan nilai (220 Ω) setiap komponen, seperti di tabel di atas.
- Skema rangkaian: Tambahkan tangkapan layar Tinkercad atau Fritzing; jika kamu menggambarnya dengan tangan, pakai simbol yang benar. Cara membaca skema rangkaian membantu untuk ini.
- Perhitungan resistor: Tunjukkan R = (5 − 2) / 0,015 ≈ 200 Ω dan jelaskan kenapa kamu memilih 220 Ω.
- Tabel keadaan atau diagram alir: Sertakan tabel keadaan, lama, dan perpindahannya; ini bukti terkuat bahwa kamu memahami kodenya.
- Kode dan penjelasan: Sertakan kode lengkap dan jelaskan baris-baris penting dengan kata-katamu sendiri.
- Pengujian dan pengamatan: Ukur lama setiap fase dengan stopwatch, ukur arus satu LED dengan multimeter, dan bandingkan dengan perhitunganmu.
- Kesimpulan dan pengembangan: Ceritakan masalah yang kamu temui, cara kamu memecahkannya, dan fitur yang bisa kamu tambahkan (tombol pejalan kaki, suara, mode malam).
Ide untuk mengembangkan lampu lalu lintasmu
- Layar hitung mundur: Tampilkan sisa detik sampai hijau berakhir di display 7-segmen.
- Sinyal suara untuk pejalan kaki tunanetra: Selama lampu pejalan kaki hijau, bunyikan buzzer dengan cepat, dan pelan selama merah.
- Persimpangan pintar: Deteksi mobil yang menunggu di jalan samping dengan sensor jarak HC-SR04 dan beri arah B hijau hanya ketika ada mobil.
- Mode malam otomatis: Pakai LDR untuk beralih ke kuning berkedip ketika hari gelap.
- Kendali jarak jauh: Buat halaman web di ESP32 dan ubah mode serta waktunya dari ponselmu.
- Perlintasan kereta: Pakai logika yang sama untuk lampu perlintasan kereta api dengan dua LED merah yang berkedip bergantian; proyek Knight Rider dan LED berjalan memakai ide pengaturan waktu yang mirip.
Lampu lalu lintas terlihat seperti proyek kecil, tapi ide-ide di dalamnya, state machine, pengaturan waktu tanpa blocking, dan perpindahan yang aman, juga menjadi dasar robot, sistem alarm, dan perangkat rumah pintar yang akan kamu buat nanti. Untuk memilih apa yang dibuat berikutnya, telusuri daftar ide proyek Arduino. Di aplikasi BlueGrays kamu akan menemukan proyek lampu lalu lintas untuk Arduino, ESP32, dan Raspberry Pi Pico, plus lanjutannya seperti Lampu Lalu Lintas Raspberry Pi Pico dengan Pemilih 4 Mode lewat Tombol, masing-masing dengan skema rangkaian langkah demi langkah dan kode siap pakai untuk dicoba di board-mu sendiri.
Pertanyaan umum
Bagaimana cara membuat lampu lalu lintas dengan Arduino?
Sambungkan kaki panjang LED merah, kuning, dan hijau ke pin digital Arduino (misalnya D10, D9, dan D8) lewat resistor 220 Ω dan kaki pendeknya ke GND. Di kode, atur pin-pin itu sebagai OUTPUT dan nyalakan serta padamkan LED secara berurutan di dalam loop(). delay() cukup untuk versi pertama; untuk tombol dan fitur tambahan kamu butuh millis().
Resistor apa yang kubutuhkan untuk LED lampu lalu lintas?
Di Arduino Uno 5 V, 220 Ω per LED adalah pilihan yang umum dan aman; LED merah lalu menarik sekitar 13–14 mA. 330 Ω memberi cahaya yang lebih redup tapi tetap terlihat jelas. 220 Ω juga bisa dipakai di ESP32 dan Pico 3,3 V; hanya jika LED hijau terang tetap redup kamu perlu turun ke 100 Ω.
Kenapa merah dan kuning menyala bersamaan di lampu lalu lintas?
Di negara seperti Inggris, Jerman, dan Turki, merah dan kuning bersamaan memberi tahu bahwa hijau akan segera menyala: pengemudi bersiap tapi tidak bergerak sampai hijau muncul. Amerika Serikat, Prancis, Italia, dan Spanyol tidak memakai fase ini dan langsung berpindah dari merah ke hijau. Di proyek Arduino-mu, kamu bisa memasukkan atau melewatkan fase ini sesukamu.
Sebaiknya pakai delay atau millis untuk lampu lalu lintas Arduino?
Jika kamu hanya menyalakan LED secara berurutan, delay() adalah pilihan paling sederhana dan bekerja dengan baik. Begitu kamu menambahkan tombol, sensor, layar, atau suara, delay() menghentikan program sejenak dan input-input itu terlewat. Kode yang ditulis dengan millis() dan state machine tidak pernah menunggu dan bisa memantau semuanya sekaligus.
Bisakah aku membuat proyek lampu lalu lintas di Tinkercad?
Bisa. Tinkercad Circuits menyediakan Arduino Uno, LED, resistor, dan push button sebagai komponen siap pakai; gambar rangkaiannya, tempel kode di editor Text, lalu mulai simulasi. Ini ideal untuk menguji rangkaian dan kode tanpa komponen sungguhan dan untuk mendapat tangkapan layar atau tautan berbagi untuk tugasmu.
Bagaimana cara kerja lampu lalu lintas pejalan kaki dengan tombol?
Mobil biasanya mendapat hijau, dan menekan tombol mencatat permintaan. Begitu waktu hijau minimum untuk mobil selesai, lampu menjadi kuning, lalu merah, dan setelah jeda aman singkat lampu pejalan kaki menjadi hijau. Di kode panduan ini lampu hijau pejalan kaki berkedip sebelum berakhir, lalu siklus kembali ke mobil.
Proyek untuk dibuat setelah membaca ini
Lihat semua proyek
Lampu Lalu Lintas
Tiruan mini lampu lalu lintas yang kamu lihat di jalan setiap hari. Merah menyala dua detik, kuning menyala sebentar, hijau menyala dua detik, lalu kembali ke merah lewat kuning lagi, terus berulang.

Lampu Lalu Lintas ESP32
Simulasi lampu lalu lintas sungguhan dengan 3 LED merah-kuning-hijau. Pengaturan waktunya mendekati logika lalu lintas sungguhan: merah lama, kuning singkat, hijau lama. Contoh klasik kendali GPIO berurutan.

Simulator Lampu Lalu Lintas Raspberry Pi Pico (3 LED Berurutan)
Kita menyimulasikan lampu lalu lintas sungguhan dengan LED merah, kuning, dan hijau; proyek 3 LED pertama di seri Pico! Hijau 4 detik "jalan", kuning 1,5 detik "siap", merah 3 detik "berhenti", dan merah+kuning 1 detik "bersiap" (pola Eropa). Pelajari pendefinisian fungsi (def all_off()), logika state machine, dan sinkronisasi beberapa GPIO. 3 LED di GP11 (Hijau), GP12 (Kuning), GP13 (Merah), masing-masing dengan resistor 220Ω, berdampingan di board.

Dua LED Berkedip Bergantian
Dua LED berkedip cepat secara bergantian: ketika satu menyala, yang lain mati, seperti sedang saling melempar bola. Arduino menyalakan setiap lampu selama seperlima detik lalu menyerahkannya ke yang l

Kendali LED dengan Tombol Tekan (Tekan)
Persis seperti bel pintu: lampu tetap menyala selama kamu menekan, dan mati ketika kamu melepasnya. Arduino terus mendengarkan tombol; selama ditekan LED menyala, dan begitu jarimu terangkat LED mati.

Lampu Polisi LED
Persis seperti lampu di mobil polisi: LED merah berkedip tiga kali dengan cepat, lalu LED biru berkedip tiga kali, dan polanya terus berulang tanpa henti. Yang kamu butuhkan hanya dua LED dan dua resi

Lampu Lalu Lintas Raspberry Pi Pico dengan Pemilih 4 Mode lewat Tombol (State Machine)
4 mode lampu lalu lintas dengan 1 tombol! Setiap tekanan mengganti mode: Siklus normal (merah → kuning → hijau), Hanya Merah (tanda berhenti), Kuning Berkedip (mode malam), Mati (perawatan). Konsep: state machine (variabel mode menentukan perilaku), perputaran mode dengan modulo ((mode + 1) % 4 → 0→1→2→3→0), waktu non-blocking (fase LED dengan time.ticks_ms() + time.ticks_diff(); jeda debounce singkat tetap memakai sleep_ms).
Artikel lainnya
Aplikasi BlueGrays
Rakit rangkaian ini langkah demi langkah di ponselmu
Skema pengkabelan, kode, dan daftar komponen dalam satu layar. 200+ proyek Arduino, ESP32, dan Pico siap dibuat.
Pindai dengan ponselmu
Arahkan kamera ke kode ini dan toko aplikasi di ponselmu akan terbuka.
atau buka toko aplikasi

