from machine import Pin, PWM
import time
# ── 부품 설정 ──
trig = Pin(16, Pin.OUT)
echo = Pin(17, Pin.IN)
r = PWM(Pin(10)); r.freq(1000)
g = PWM(Pin(11)); g.freq(1000)
b = PWM(Pin(12)); b.freq(1000)
buzzer = PWM(Pin(5))
buzzer.duty_u16(0)
# ── 거리 구간 설정 ──
LEVELS = [
# (최대거리, 색상(R,G,B), 경고음 간격, 상태)
(10, (255, 0, 0), 0.00, '위험'),
(25, (255, 60, 0), 0.10, '매우 근접'),
(50, (255, 200, 0), 0.30, '근접'),
(90, (120, 255, 0), 0.60, '주의'),
(999, ( 0, 255, 0), None, '안전'),
]
# ── 함수 ──
def get_distance():
"""거리를 cm로 반환. 실패하면 -1"""
trig.low()
time.sleep_us(2)
trig.high()
time.sleep_us(10)
trig.low()
t0 = time.ticks_us()
while echo.value() == 0:
start = time.ticks_us()
if time.ticks_diff(start, t0) > 30000:
return -1
while echo.value() == 1:
end = time.ticks_us()
if time.ticks_diff(end, start) > 30000:
return -1
return (time.ticks_diff(end, start) * 0.0343) / 2
def color(rgb):
"""(R, G, B) 0~255 값으로 색 지정"""
r.duty_u16(int(rgb[0] / 255 * 65535))
g.duty_u16(int(rgb[1] / 255 * 65535))
b.duty_u16(int(rgb[2] / 255 * 65535))
def find_level(d):
"""거리에 맞는 구간을 찾아 반환"""
for limit, rgb, gap, name in LEVELS:
if d < limit:
return rgb, gap, name
return LEVELS[-1][1], LEVELS[-1][2], LEVELS[-1][3]
def beep(gap):
"""gap 간격으로 한 번 경고음. gap이 0이면 연속음"""
if gap == 0:
buzzer.freq(2000)
buzzer.duty_u16(20000)
time.sleep(0.2)
else:
buzzer.freq(1500)
buzzer.duty_u16(20000)
time.sleep(0.06)
buzzer.duty_u16(0)
time.sleep(gap)
# ── 메인 ──
try:
while True:
d = get_distance()
if d < 0: # 측정 실패
color((0, 0, 40)) # 희미한 파랑
buzzer.duty_u16(0)
time.sleep(0.2)
continue
rgb, gap, name = find_level(d)
color(rgb)
if gap is None: # 안전 구간
buzzer.duty_u16(0)
time.sleep(0.2)
else:
beep(gap)
print(f'{d:5.1f} cm {name}')
except KeyboardInterrupt:
buzzer.duty_u16(0)
color((0, 0, 0))
print('종료')
Loading
pi-pico-w
pi-pico-w