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).

Video
Skema rangkaian

Kode sumber
1# ─────────────────────────────────────────
2# BlueGrays · bluegrays.com
3# Lampu Lalu Lintas Raspberry Pi Pico dengan Pemilih 4 Mode lewat Tombol (State Machine)
4# ─────────────────────────────────────────
5# Satu tombol berpindah di antara 4 mode: siklus normal (merah -> kuning
6# -> hijau), hanya merah, kuning berkedip, dan mati. Memakai state machine
7# dan timing non-blocking dengan time.ticks_ms(), jadi tombol selalu
8# responsif.
9#
10# Pin:
11# GP11 -> LED hijau
12# GP12 -> LED kuning
13# GP13 -> LED merah (tiap LED dengan 220 ohm)
14# GP4 -> Tombol (kaki lainnya ke GND)
15
16from machine import Pin
17import time
18
19# ============ LED ============
20green = Pin(11, Pin.OUT) # Hijau
21yellow = Pin(12, Pin.OUT) # Kuning
22red = Pin(13, Pin.OUT) # Merah
23
24# ============ TOMBOL ============
25button = Pin(4, Pin.IN, Pin.PULL_UP) # Terbaca 0 ketika ditekan
26
27# ============ STATUS ============
28# Mode: 0 siklus normal, 1 hanya merah, 2 kuning berkedip, 3 mati
29mode = 0
30last_btn = 1 # Nilai tombol sebelumnya
31blink_state = False # Status kedip kuning
32last_tick = time.ticks_ms() # Pergantian kedip terakhir
33
34# ============ SIKLUS NORMAL ============
35normal_step = 0 # 0: merah, 1: kuning, 2: hijau
36normal_last = time.ticks_ms() # Waktu mulai langkah
37NORMAL_TIMES = [3000, 1000, 3000] # Merah, Kuning, Hijau (ms)
38LEDS = [red, yellow, green]
39
40def all_off():
41 # Matikan semua LED
42 red.off(); yellow.off(); green.off()
43
44# ============ LOOP UTAMA ============
45while True:
46 btn = button.value()
47
48 # ---- Tombol ditekan (1 -> 0): ganti mode ----
49 if last_btn == 1 and btn == 0:
50 mode = (mode + 1) % 4
51 all_off()
52 normal_step = 0
53 normal_last = time.ticks_ms()
54 time.sleep_ms(200) # Debounce
55 last_btn = btn
56
57 now = time.ticks_ms()
58
59 # ---- Siklus lampu lalu lintas normal ----
60 if mode == 0:
61 if time.ticks_diff(now, normal_last) > NORMAL_TIMES[normal_step]:
62 normal_step = (normal_step + 1) % 3
63 normal_last = now
64 all_off()
65 LEDS[normal_step].on()
66
67 # ---- Hanya merah (berhenti) ----
68 elif mode == 1:
69 all_off(); red.on()
70
71 # ---- Kuning berkedip, 0.4 s (hati-hati/malam) ----
72 elif mode == 2:
73 if time.ticks_diff(now, last_tick) > 400:
74 blink_state = not blink_state
75 yellow.value(blink_state)
76 last_tick = now
77 red.off(); green.off()
78
79 # ---- Mati ----
80 else:
81 all_off()
82
83 time.sleep_ms(10)
84FAQ
Apa itu state machine?
Satu variabel (mode) menentukan apa yang sedang dilakukan program. Setiap tekanan tombol mengubah mode, dan loop hanya menjalankan kode untuk mode yang aktif. Ini cara standar menjaga perilaku yang rumit tetap teratur.
Apa yang dilakukan (mode + 1) % 4?
Ia menambah mode satu dan kembali ke 0 ketika mencapai 4, sehingga mode berputar 0, 1, 2, 3, 0, 1... selamanya.
Kenapa memakai ticks_ms(), bukan time.sleep()?
Selama sleep(), Pico tidak bisa membaca tombol, jadi pergantian mode terlambat. ticks_ms() dan ticks_diff() menghindari jeda panjang selama fase LED. Namun, versi ini menunggu 200 ms untuk debounce ketika mode berganti dan 10 ms di akhir setiap loop; tombol tidak dibaca lagi selama jeda ini.
Bisakah aku menambahkan mode baru?
Ya, naikkan jumlah mode menjadi 5 dan tulis blok perilaku terpisah untuk mode baru, seperti hijau berkedip atau menyalakan semua lampu berurutan.
