#170Pemula

Sensor Parkir Raspberry Pi Pico (HC-SR04 + 3 LED + Buzzer)

Bawa sensor parkir mundur mobilmu ke meja! Raspberry Pi Pico memakai sensor ultrasonik HC-SR04 untuk mengukur jarak ke rintangan sekitar 16 kali per detik. Makin dekat rintangannya, LED hijau, kuning, dan merah menyala bergiliran dan buzzer berbunyi bip makin cepat; di bawah 10 cm nadanya berbunyi terus dan LED merah berkedip. Pengukuran jarak ultrasonik, suara PWM, dan pengaturan waktu non-blocking dalam satu proyek.

0.0(0)
1 selesai
Sensor Parkir Raspberry Pi Pico (HC-SR04 + 3 LED + Buzzer)
Versi meja dari sensor parkir di mobil. HC-SR04 mengirim suara yang terlalu tinggi untuk telingamu dan mendengarkan pantulannya untuk mengukur seberapa jauh rintangan; begitu ada sesuatu dalam jarak satu meter, LED hijau menyala dan buzzer berbunyi bip pelan. Makin dekat, LED kuning dan merah ikut menyala dan bunyi bip makin cepat dan tinggi, dan di bawah 10 sentimeter nadanya tidak pernah berhenti sementara lampu merah berkedip.

Video

Skema rangkaian

Sensor Parkir Raspberry Pi Pico (HC-SR04 + 3 LED + Buzzer) - Circuit

Kode sumber

MicroPython
1# ─────────────────────────────────────────
2#   BlueGrays · bluegrays.com
3#   Sensor Parkir Raspberry Pi Pico (HC-SR04 + 3 LED + Buzzer)
4# ─────────────────────────────────────────
5# Sensor parkir mobil. HC-SR04 mengukur jarak ke penghalang; semakin
6# dekat, LED hijau, kuning, dan merah menyala bergantian dan bip makin
7# cepat. Jika sangat dekat, nadanya jadi terus-menerus dan LED merah
8# berkedip.
9#
10# Pin:
11#   GP27 -> TRIG HC-SR04
12#   GP26 -> HC-SR04 ECHO (pembagi 1k + 2k di hardware asli)
13#   VBUS -> HC-SR04 VCC (5V), GND.6 -> HC-SR04 GND
14#   GP4  -> 220 ohm -> LED merah (katoda ke GND)
15#   GP8  -> 220 ohm -> LED kuning (katoda ke GND)
16#   GP12 -> 220 ohm -> LED hijau (katoda ke GND)
17#   GP17 -> Buzzer (+), kaki lainnya ke GND
18
19from machine import Pin, PWM, time_pulse_us
20import time
21
22# ============ PENGATURAN ============
23GREEN_CM = 100         # Hijau nyala, bip mulai
24YELLOW_CM = 50         # Kuning ikut menyala
25RED_CM = 25            # Merah ikut menyala
26STOP_CM = 10           # Nada terus-menerus + merah berkedip
27
28BEEP_MS = 60           # Panjang satu bip
29SLOW_GAP_MS = 700      # Jeda antar bip di GREEN_CM
30FAST_GAP_MS = 50       # Jeda antar bip di dekat STOP_CM
31VOLUME = 32768         # Duty PWM, 32768 = 50%
32FLASH_MS = 120         # Periode kedip merah di zona STOP
33
34MEASURE_MS = 60        # Interval pengukuran, min 60 ms
35PRINT_MS = 250         # Interval cetak Serial
36ECHO_TIMEOUT_US = 12000  # lebih dari ~2 m = tidak ada penghalang
37SOUND_CM_PER_US = 0.0343  # Kecepatan suara (20 C)
38LOOP_MS = 5            # Langkah loop utama
39
40# Zona dari dekat ke jauh: (nama, batas atas cm, (hijau, kuning, merah), nada Hz)
41ZONES = (
42    ("DUR / STOP", STOP_CM, (1, 1, 1), 1900),
43    ("KIRMIZI / RED", RED_CM, (1, 1, 1), 1900),
44    ("SARI / YELLOW", YELLOW_CM, (1, 1, 0), 1500),
45    ("YESIL / GREEN", GREEN_CM, (1, 0, 0), 1200),
46)
47CLEAR = len(ZONES)     # Zona tanpa penghalang
48STOP = 0               # Indeks zona STOP
49
50# ============ HARDWARE ============
51trig = Pin(27, Pin.OUT, value=0)
52echo = Pin(26, Pin.IN)
53led_green = Pin(12, Pin.OUT, value=0)
54led_yellow = Pin(8, Pin.OUT, value=0)
55led_red = Pin(4, Pin.OUT, value=0)
56buzzer = PWM(Pin(17))
57buzzer.duty_u16(0)
58
59
60# ============ PENGUKURAN ============
61def measure_cm():
62    # Kirim pulsa TRIG 10 us, ukur berapa lama ECHO tetap HIGH
63    trig.value(0)
64    time.sleep_us(2)
65    trig.value(1)
66    time.sleep_us(10)
67    trig.value(0)
68    pulse = time_pulse_us(echo, 1, ECHO_TIMEOUT_US)
69    if pulse < 0:
70        return None    # Tidak ada echo atau terlalu jauh
71    # Suara menempuh jalan pergi dan pulang: setengahnya
72    return pulse * SOUND_CM_PER_US / 2
73
74
75def median3(values):
76    # Median dari 3 pembacaan terakhir: satu pembacaan buruk tidak membuat LED berkedip
77    a, b, c = values
78    return max(min(a, b), min(max(a, b), c))
79
80
81def zone_of(dist):
82    if dist is None:
83        return CLEAR
84    for i, zone in enumerate(ZONES):
85        if dist <= zone[1]:
86            return i
87    return CLEAR
88
89
90def beep_gap_ms(dist):
91    # Antara STOP_CM dan GREEN_CM jeda bip bertambah secara linear dari FAST ke SLOW
92    ratio = (dist - STOP_CM) / (GREEN_CM - STOP_CM)
93    ratio = min(1.0, max(0.0, ratio))
94    return int(FAST_GAP_MS + ratio * (SLOW_GAP_MS - FAST_GAP_MS))
95
96
97# ============ SUARA ============
98tone_on = False
99tone_hz = 0
100
101
102def tone(hz):
103    # Biarkan PWM jika nada sudah menyala
104    global tone_on, tone_hz
105    if tone_on and tone_hz == hz:
106        return
107    buzzer.freq(hz)
108    buzzer.duty_u16(VOLUME)
109    tone_on = True
110    tone_hz = hz
111
112
113def silence():
114    global tone_on
115    if tone_on:
116        buzzer.duty_u16(0)
117        tone_on = False
118
119
120def set_leds(green, yellow, red):
121    led_green.value(green)
122    led_yellow.value(yellow)
123    led_red.value(red)
124
125
126def self_test():
127    # Tes singkat LED dan buzzer ketika dinyalakan: hijau -> kuning -> merah
128    for leds, hz in (((1, 0, 0), 1200), ((1, 1, 0), 1500), ((1, 1, 1), 1900)):
129        set_leds(*leds)
130        tone(hz)
131        time.sleep_ms(90)
132        silence()
133        time.sleep_ms(160)
134    set_leds(0, 0, 0)
135
136
137# ============ LOOP UTAMA ============
138print("== BlueGrays · bluegrays.com ==")
139print("Pico Park Sensoru / Parking Sensor")
140print("Yesil <= %d cm, sari <= %d cm, kirmizi <= %d cm, surekli ses <= %d cm"
141      % (GREEN_CM, YELLOW_CM, RED_CM, STOP_CM))
142print("Green <= %d cm, yellow <= %d cm, red <= %d cm, continuous tone <= %d cm"
143      % (GREEN_CM, YELLOW_CM, RED_CM, STOP_CM))
144self_test()
145
146FAR = 999.0                       # Placeholder untuk tidak ada penghalang
147history = [FAR, FAR, FAR]         # 3 pembacaan terakhir
148distance = None                   # Jarak yang sudah difilter (cm)
149zone = CLEAR
150last_zone = -1
151now = time.ticks_ms()
152next_measure = now
153next_print = now
154last_beep = time.ticks_add(now, -10000)   # Bip pertama langsung berbunyi
155beep_end = now
156
157while True:
158    now = time.ticks_ms()
159
160    # 1) Pengukuran: setiap MEASURE_MS, dengan filter median
161    if time.ticks_diff(now, next_measure) >= 0:
162        next_measure = time.ticks_add(now, MEASURE_MS)
163        reading = measure_cm()
164        history = history[1:] + [reading if reading is not None else FAR]
165        filtered = median3(history)
166        distance = None if filtered >= FAR else filtered
167        zone = zone_of(distance)
168        if zone != last_zone:
169            name = "ENGEL YOK / CLEAR" if zone == CLEAR else ZONES[zone][0]
170            print("Bolge / Zone ->", name)
171            last_zone = zone
172
173    # 2) LED: grafik bar, merah berkedip di zona STOP
174    if zone == CLEAR:
175        set_leds(0, 0, 0)
176    elif zone == STOP:
177        flash_on = (now // FLASH_MS) % 2 == 0
178        set_leds(1, 1, 1 if flash_on else 0)
179    else:
180        set_leds(*ZONES[zone][2])
181
182    # 3) Suara: timer bip non-blocking
183    if zone == CLEAR:
184        silence()
185    elif zone == STOP:
186        tone(ZONES[STOP][3])          # Sangat dekat: nada terus-menerus
187    else:
188        if tone_on and time.ticks_diff(now, beep_end) >= 0:
189            silence()
190        # Jeda dihitung ulang setiap putaran: bip berikutnya langsung lebih cepat begitu kamu
191        # mendekat
192        period = BEEP_MS + beep_gap_ms(distance)
193        if not tone_on and time.ticks_diff(now, last_beep) >= period:
194            tone(ZONES[zone][3])
195            last_beep = now
196            beep_end = time.ticks_add(now, BEEP_MS)
197
198    # 4) Serial monitor: jarak dalam cm
199    if time.ticks_diff(now, next_print) >= 0:
200        next_print = time.ticks_add(now, PRINT_MS)
201        if distance is None:
202            print("Mesafe / Distance: --- (engel yok / no obstacle)")
203        else:
204            print("Mesafe / Distance: %5.1f cm" % distance)
205
206    time.sleep_ms(LOOP_MS)
207

FAQ

Kenapa ECHO butuh pembagi tegangan di rangkaian sungguhan?

HC-SR04 bekerja pada 5V dan output ECHO-nya 5V, tetapi pin Pico menerima paling tinggi 3,3V. Sambungkan ECHO ke GP26 lewat 1 kΩ dan GP26 ke GND lewat 2 kΩ, sehingga pin menerima sekitar 3,3V. Di Wokwi pembagi ini tidak diperlukan.

Bagaimana cara mengubah jarak peringatan?

Ubah konstanta `GREEN_CM`, `YELLOW_CM`, `RED_CM`, dan `STOP_CM` di bagian atas kode. Jaga urutan ambangnya `STOP_CM < RED_CM < YELLOW_CM < GREEN_CM`; misalnya, pakai `STOP_CM = 30`, `RED_CM = 50`, `YELLOW_CM = 100`, dan `GREEN_CM = 150`. LED dan bunyi bip otomatis mengikuti ambang baru.

Kenapa bunyi bip makin cepat secara halus, bukan per zona?

`beep_gap_ms()` mengatur jeda secara linear sesuai jarak: 700 ms di 100 cm, 50 ms di 10 cm. Jeda dihitung ulang di setiap putaran loop utama, jadi bunyi bip berikutnya datang lebih cepat begitu rintangan mendekat. Zona hanya mengubah LED dan nada.

Apakah aku perlu menginstal library?

Tidak. Fungsi `time_pulse_us()` yang dipakai untuk pengukuran adalah bagian dari modul bawaan `machine`. Pasang MicroPython di Pico dan simpan kodenya sebagai `main.py` di Thonny; sensor menyala sendiri dengan tes LED dan tiga bunyi bip.