콘텐츠로 이동

Chapter 11: 거리에 반응하는 신호등 - 조건문 활용

🎯 이 장에서 배우는 것

  • 거리 값에 따라 다른 LED를 켜는 if-elif-else 조건문을 작성할 수 있다
  • 3색 LED 신호등 시스템(초록-노랑-빨강)을 구현할 수 있다
  • 임계값(threshold)의 개념을 이해하고 조절할 수 있다
  • 거리에 따라 깜빡임 속도가 변하는 효과를 만들 수 있다
  • 실생활 '접근 감지' 시스템의 원리를 설명할 수 있다

💡 왜 이걸 배우나요?

주차장에서 후진할 때 들어본 적 있지? "삐... 삐... 삐삐삐삐빕!" 벽에 가까워질수록 소리가 빨라지는 그 시스템. 또는 자동문 앞에 서면 문이 열리고, 멀어지면 닫히는 것. 이런 게 전부 거리 센서 + 조건문의 조합이야.

┌─────────────────────────────────────────────────────────────┐
│  🚗 후방 감지 센서 - 우리가 만들 것과 똑같은 원리!          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│    [벽]                                                     │
│     ║                                                       │
│     ║  ←── 30cm 이상: 🟢 안전 (초록)                       │
│     ║                                                       │
│     ║  ←── 10~30cm: 🟡 주의 (노랑)                         │
│     ║                                                       │
│     ║  ←── 10cm 이하: 🔴 위험! (빨강 + 빠른 깜빡임)        │
│     ║                                                       │
│    [🚗 차]                                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

이번 장에서는 단순히 "가까우면 켜고, 멀면 끈다"가 아니라, 여러 구간으로 나누어 각각 다른 반응을 하는 코드를 만들어볼 거야. 이게 바로 다중 조건문이야.

💭 생각해보기: 네가 자주 가는 장소에서 "거리에 따라 다르게 반응하는 것"을 본 적 있어? (자동문, 에스컬레이터 센서, 화장실 자동 조명 등)


📚 핵심 개념

개념 1: 다중 조건문 (if-elif-else)

이전 장에서 배운 조건문은 "참이면 A, 아니면 B" 두 가지 경우였어. 하지만 실제 상황은 더 복잡해. 신호등을 생각해봐:

  1. 비유로 시작: 다중 조건문은 마치 계단식 분류와 같아요. "키가 150cm 이상이면 A조, 140cm 이상이면 B조, 130cm 이상이면 C조, 그 외는 D조" 이런 식으로 차례대로 확인하다가 맞는 조건을 만나면 거기서 멈춰요.

  2. 정확한 정의: if-elif-else는 여러 조건을 순서대로 검사해서, 처음으로 참인 조건의 코드만 실행하는 구조입니다.

  3. 예시로 확인:

    distance = 25  # 거리 25cm
    
    if distance >= 30:      # 30 이상? → 거짓 (25는 30보다 작음)
        print("안전")       # 건너뜀
    elif distance >= 10:    # 10 이상? → 참! (25는 10보다 큼)
        print("주의")       # ✅ 이거 실행!
    else:                   # 위에서 이미 걸렸으므로
        print("위험")       # 건너뜀
    

쉽게 말하면: 위에서부터 차례로 확인하다가, 처음 "맞다!"가 나오면 그것만 실행하고 끝!

┌─────────────────────────────────────────────────────────────┐
│  🔍 if-elif-else 실행 흐름                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  거리 = 25cm 일 때:                                         │
│                                                             │
│  if distance >= 30:  ─────→ 25 >= 30? ❌ 거짓              │
│      │                          ↓                           │
│  elif distance >= 10: ────→ 25 >= 10? ✅ 참! → 실행!       │
│      │                          │                           │
│  else:                    (도달 안 함)                      │
│                                                             │
│  ⚠️ 순서가 중요해!                                          │
│  만약 elif를 먼저 쓰면 30cm도 "주의"로 분류돼버림           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

개념 2: 임계값 (Threshold)

  1. 비유로 시작: 임계값은 마치 경계선과 같아요. 놀이공원에서 "키 120cm 이상만 탑승 가능"이라는 기준이 있잖아? 그 120cm가 바로 임계값이에요.

  2. 정확한 정의: 임계값(threshold)은 어떤 동작이 일어나거나 상태가 바뀌는 기준점을 말합니다.

  3. 예시로 확인:

    # 우리가 정할 임계값들
    THRESHOLD_FAR = 30    # 30cm 이상 = "멀다"의 기준
    THRESHOLD_NEAR = 10   # 10cm 이하 = "가깝다"의 기준
    
    # 구간 분류
    # 거리 >= 30cm      → 안전 (초록)
    # 10cm < 거리 < 30cm → 주의 (노랑)  
    # 거리 <= 10cm      → 위험 (빨강)
    

쉽게 말하면: "여기부터는 다르게 행동해!"라고 정한 기준 숫자야.

💡 왜 임계값을 변수로 만들까?
나중에 "30cm가 너무 멀어, 20cm로 바꾸자"할 때 코드 맨 위에서 숫자 하나만 바꾸면 돼. 코드 여기저기 흩어진 30을 일일이 찾아 바꾸는 것보다 훨씬 편해!


개념 3: 구간별 동작 설계

실제 시스템을 만들 때는 "어떤 구간에서 어떻게 동작할지" 미리 정리하는 게 중요해.

┌─────────────────────────────────────────────────────────────┐
│  📋 우리 신호등의 동작 설계표                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  구간              │ LED 상태        │ 추가 효과           │
│  ─────────────────┼────────────────┼───────────────────   │
│  30cm 이상 (안전)  │ 🟢 초록 켜짐    │ 계속 켜짐 (안정)    │
│  10~30cm (주의)    │ 🟡 노랑 켜짐    │ 천천히 깜빡임       │
│  10cm 이하 (위험)  │ 🔴 빨강 켜짐    │ 빠르게 깜빡임       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

쉽게 말하면: 코드 짜기 전에 "이 상황엔 이렇게"를 표로 정리하면 헷갈리지 않아!


🔨 따라하기

준비물 확인

부품 수량 연결 핀
초음파 거리 센서 1개 D16 (Trig), D17 (Echo)
LED (초록) 1개 D18
LED (노랑) 1개 D19
LED (빨강) 1개 D20
┌─────────────────────────────────────────────────────────────┐
│  🔌 연결 다이어그램                                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [Grove Shield for Pico]                                    │
│                                                             │
│  D16/D17 ──────── [초음파 센서]  📏                        │
│                    (Trig/Echo)                              │
│                                                             │
│  D18 ────────────  [🟢 초록 LED] (안전)                    │
│                                                             │
│  D19 ────────────  [🟡 노랑 LED] (주의)                    │
│                                                             │
│  D20 ────────────  [🔴 빨강 LED] (위험)                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Step 1: 거리 측정 복습

목표: 초음파 센서로 거리를 정확히 읽어오기 (이전 장 복습)

코드:

# === WHAT: 초음파 센서로 거리 측정하기 ===
# 이전 장에서 배운 거리 측정 코드를 다시 확인해봐요

from machine import Pin
import time

# --- WHY: 초음파 센서 작동 원리 ---
# Trig 핀: 초음파 발사 신호
# Echo 핀: 반사파 수신 신호
# 시간차로 거리 계산!

# HOW: 핀 설정
trig = Pin(16, Pin.OUT)  # Trig는 출력 (신호 보내기)
echo = Pin(17, Pin.IN)   # Echo는 입력 (신호 받기)

def measure_distance():
    """거리를 측정해서 cm 단위로 반환"""
    # 초음파 발사
    trig.low()
    time.sleep_us(2)
    trig.high()
    time.sleep_us(10)
    trig.low()

    # 에코 신호 대기
    while echo.value() == 0:
        start = time.ticks_us()
    while echo.value() == 1:
        end = time.ticks_us()

    # 거리 계산 (소리 속도 = 343m/s, 왕복이니까 /2)
    duration = time.ticks_diff(end, start)
    distance = duration * 0.0343 / 2

    return distance

# 테스트: 1초마다 거리 출력
while True:
    dist = measure_distance()
    print(f"거리: {dist:.1f} cm")
    time.sleep(1)

실행 결과:

거리: 45.2 cm
거리: 32.1 cm
거리: 15.8 cm
거리: 8.3 cm

여기서 잠깐! 🤔
손을 센서에 가까이 대거나 멀리하면서 숫자가 바뀌는지 확인해봐. 대략 어느 정도 거리에서 30cm, 10cm가 되는지 감을 잡아두면 좋아!


Step 2: 3색 LED 연결하기

목표: 세 개의 LED를 각각 제어할 수 있게 설정

코드:

# === WHAT: 3색 LED 개별 제어 테스트 ===
# 초록, 노랑, 빨강 LED가 각각 잘 작동하는지 확인

from machine import Pin
import time

# --- WHY: 각 LED에 다른 핀 할당 ---
# 나중에 조건에 따라 하나만 켜거나 끌 수 있도록!

# HOW: LED 핀 설정
led_green = Pin(18, Pin.OUT)   # 초록 = 안전
led_yellow = Pin(19, Pin.OUT)  # 노랑 = 주의
led_red = Pin(20, Pin.OUT)     # 빨강 = 위험

# 테스트: 순서대로 켜보기
print("초록 LED 테스트")
led_green.high()
time.sleep(1)
led_green.low()

print("노랑 LED 테스트")
led_yellow.high()
time.sleep(1)
led_yellow.low()

print("빨강 LED 테스트")
led_red.high()
time.sleep(1)
led_red.low()

print("테스트 완료!")

실행 결과: ``` 초록 LED 테스트 (1초간 초록 불 켜짐) 노랑 LED 테스