콘텐츠로 이동

챕터 12: 거리로 음악을 - 테레민 만들기

Part 2: 거리와 빛으로 세상 감지


🎯 이 장에서 배우는 것

  • 거리 값을 주파수(Hz)로 매핑해 부저 음높이를 제어할 수 있다
  • 연속적인 센서 입력으로 실시간 출력 변화를 구현할 수 있다
  • 값 매핑(mapping) 함수의 원리를 이해하고 활용할 수 있다
  • 창의적 악기 인터페이스의 가능성을 탐구할 수 있다

💡 왜 이걸 배우나요?

🎵 테레민(Theremin)이란?

1920년대 발명된 최초의 전자악기
손을 대지 않고 허공에서 연주하는 신비로운 악기

    ♪ ♫ ♪
     \|/
      🖐️  ← 손 위치에 따라 음이 변해요!

   [테레민 안테나]

테레민의 마법 같은 원리: - 손이 가까우면 → 높은 음 🎵 - 손이 멀면 → 낮은 음 🎶

우리는 이 원리를 초음파 센서 + 부저로 구현할 거야!

실제로 어디에 쓰일까?

응용 분야 설명
악기 거리 기반 전자악기, 모션 컨트롤러
접근 경보 자동차 후방 감지 - 가까울수록 빠른 경고음
인터랙티브 전시 관람객 움직임에 반응하는 사운드 아트
게임 컨트롤러 손 동작으로 게임 캐릭터 조작

이번 챕터의 핵심:

센서 값 → 다른 범위의 값으로 변환(매핑)하는 기술


📚 핵심 개념

개념 1: 값 매핑(Mapping)

1. 비유로 시작:

"값 매핑은 마치 환율 변환과 같아요"

1000원을 달러로 바꾸면 약 0.75달러가 되듯이, 거리 2~30cm를 주파수 200~2000Hz로 바꾸는 거야.

┌──────────────────────────────────────────────────────────────┐
│                      값 매핑 개념                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   입력 범위 (거리)              출력 범위 (주파수)            │
│   ┌─────────────────┐          ┌─────────────────┐          │
│   │ 2cm ──────30cm  │    →     │ 2000Hz ───200Hz │          │
│   └─────────────────┘          └─────────────────┘          │
│                                                              │
│   [2cm]  ──매핑──→  [2000Hz] (가까우면 높은 음)              │
│   [16cm] ──매핑──→  [1100Hz] (중간 거리, 중간 음)            │
│   [30cm] ──매핑──→  [200Hz]  (멀면 낮은 음)                  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2. 정확한 정의:

"값 매핑은 한 범위의 값을 다른 범위의 값으로 비례 변환하는 것입니다"

수학 공식:

출력값 = (입력값 - 입력최소) × (출력최대 - 출력최소) / (입력최대 - 입력최소) + 출력최소

3. 예시로 확인:

# 거리 10cm를 주파수로 매핑
# 거리 범위: 2~30cm → 주파수 범위: 2000~200Hz (반비례)

거리 = 10
# 계산: 2000 - (10-2) × (2000-200) / (30-2)
# = 2000 - 8 × 1800 / 28
# = 2000 - 514 = 1486Hz

# 10cm 거리 → 약 1486Hz 소리!

쉽게 말하면: 센서 값을 부저가 이해하는 주파수로 번역해주는 것!


개념 2: 주파수(Hz)와 음높이

1. 비유로 시작:

"주파수는 마치 1초에 줄을 몇 번 튕기는지와 같아요"

낮은 음 (200Hz): 1초에 200번 진동
───〰️〰️〰️〰️〰️───  천천히 진동 → 낮은 소리

높은 음 (2000Hz): 1초에 2000번 진동
───∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿───  빠르게 진동 → 높은 소리

2. 정확한 정의:

"주파수(Hz)는 1초당 진동 횟수를 의미하며, 숫자가 클수록 높은 음이 납니다"

3. 음계와 주파수:

┌────────────────────────────────────────────────┐
│              피아노 음계와 주파수               │
├────────────────────────────────────────────────┤
│                                                │
│  도(C4)  = 262Hz   🎹                          │
│  레(D4)  = 294Hz      🎹                       │
│  미(E4)  = 330Hz         🎹                    │
│  파(F4)  = 349Hz            🎹                 │
│  솔(G4)  = 392Hz               🎹              │
│  라(A4)  = 440Hz                  🎹           │
│  시(B4)  = 494Hz                     🎹        │
│  도(C5)  = 523Hz                        🎹     │
│                                                │
│  * 440Hz(라)가 국제 표준 기준음!               │
│                                                │
└────────────────────────────────────────────────┘

쉽게 말하면: Hz 숫자가 높으면 높은 음, 낮으면 낮은 음!


개념 3: PWM으로 소리 만들기

1. 비유로 시작:

"PWM으로 소리를 내는 것은 마치 진동벨과 같아요"

빠르게 껐다 켜면 높은 소리, 천천히 껐다 켜면 낮은 소리!

┌──────────────────────────────────────────────────┐
│              PWM으로 소리 생성                    │
├──────────────────────────────────────────────────┤
│                                                  │
│  낮은 음 (200Hz)                                 │
│  ┌───┐     ┌───┐     ┌───┐                      │
│  │   │     │   │     │   │      천천히 ON/OFF   │
│  ┘   └─────┘   └─────┘   └───                   │
│                                                  │
│  높은 음 (2000Hz)                                │
│  ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐                   │
│  │ │ │ │ │ │ │ │ │ │ │ │ │ │    빠르게 ON/OFF   │
│  ┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─                   │
│                                                  │
│  → PWM의 주파수(freq)를 바꾸면 음높이가 변해!    │
│                                                  │
└──────────────────────────────────────────────────┘

2. 정확한 정의:

"PWM의 주파수를 변경하면 부저의 진동 속도가 바뀌어 다른 높이의 소리가 납니다"

3. 코드로 확인:

from machine import Pin, PWM

buzzer = PWM(Pin(16))
buzzer.duty_u16(32768)  # 50% 듀티 (소리 크기)

# 주파수 변경 = 음높이 변경
buzzer.freq(262)   # 도
buzzer.freq(440)   # 라
buzzer.freq(1000)  # 높은 음

쉽게 말하면: buzzer.freq(숫자) → 숫자를 바꾸면 음높이가 바뀐다!


🔨 따라하기

Step 1: 하드웨어 연결

목표: 초음파 센서와 부저를 Pico에 연결한다

┌─────────────────────────────────────────────────────────────┐
│                     회로 연결도                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐                                           │
│   │ 초음파센서   │                                           │
│   │  (HC-SR04)  │                                           │
│   │ ┌─────────┐ │                                           │
│   │ │ ● ● ● ● │ │                                           │
│   │ └─────────┘ │                                           │
│   │ V T E G    │                                           │
│   └─│─│─│─│────┘                                           │
│     │ │ │ │                                                 │
│     │ │ │ └── GND ────────┐                                │
│     │ │ └──── GP5 (Echo) ─┤                                │
│     │ └────── GP4 (Trig) ─┤                                │
│     └──────── 5V ─────────┤                                │
│                           │                                 │
│   ┌─────────────┐         │      ┌──────────────────┐      │
│   │    부저     │         │      │                  │      │
│   │   ┌───┐    │         │      │   Raspberry Pi   │      │
│   │   │ ♪ │    │         │      │      Pico        │      │
│   │   └───┘    │         │      │                  │      │
│   │  SIG GND   │         │      │  GP4  ●──────────│      │
│   └───│───│────┘         │      │  GP5  ●──────────│      │
│       │   │              │      │  GP16 ●──────────│      │
│       │   └── GND ───────┤      │  5V   ●──────────│      │
│       └────── GP16 ──────┤      │  GND  ●──────────│      │
│                          │      │                  │      │
│                          └──────│──────────────────│      │
│                                 └──────────────────┘      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Grove 쉴드 사용 시:

부품 연결 위치
초음파 센서 D4 포트 (Trig=GP4, Echo=GP5)
부저 D16 포트

여기서 잠깐! 🤔

초음파 센서는 5V가 필요해! Grove 쉴드의 D4 포트는 5V를 공급해주니까 걱정 마.


Step 2: 초음파 센서 테스트

목표: 거리 측정이 제대로 되는지 확인한다

```python

=== WHAT: 초음파 거리 측정 테스트 ===

손을 가까이/멀리 하면서 거리 값 확인

--- WHY: 테레민 만들기 전에 센서가 잘 작동하는지 확인 ---

from machine import Pin import time

초음파 센서 핀 설정

trig = Pin(4, Pin.OUT) # 초음파 발사 핀 echo = Pin(5, Pin.IN) # 초음파 수신 핀

def measure_distance(): """거리 측정 함수 (cm 단위 반환)""" # 초음파 발사 (10us 펄스) trig.low() time.sleep_us(2) trig.high() time.sleep_us(10) trig.low()

# 에코 대기 (타임아웃 30ms)
timeout = time.ticks_us() + 30000
while echo.value() == 0:
    if time.ticks_us() > timeout:
        return -1  # 타임아웃
    start = time.ticks_us()

timeout = time.ticks_us() + 30000
while echo.value() == 1:
    if time.ticks_us() > timeout:
        return -1  # 타임아웃
    end = time.ticks_us()

# 거리 계산 (소리 속도: 343m/s)
duration = end - start
distance = duration * 0.0343 / 2  # cm

return distance

테스트 루프

print("🔊 초음파 센서 테스트 시작!") print("손을