홍창민정보·인공지능 교사

움직임·거리·위치 · 난이도 쉬움

HC-SR04 초음파 거리 센서를 Echo 분압과 기온별 음속 보정으로 정확하게 쓰기

HC-SR04는 40kHz 초음파가 되돌아오는 시간으로 2cm~4m 거리를 재요. 5V Echo를 1kΩ·2kΩ으로 나눠 피코에 잇는 배선, 기온에 맞춘 음속 계산, 다섯 번 재서 중앙값을 쓰는 코드, 거리·재질·각도에 따른 오차 탐구를 정리했어요.

글 홍창민 · 갱신 2026-10-31 · 읽는 데 약 8분 · 가상 실행 확인 (실물 미확인)

이 센서로 무엇을 잴 수 있나

HC-SR04는 초음파를 내보내고 물체에 부딪혀 돌아오는 데 걸린 시간으로 거리를 재는 모듈이에요. 데이터시트(ElecFreaks 판)에 적힌 측정 범위는 2cm~4m, 측정 각도는 15°, 동작 전압은 5V, 전류는 15mA예요. 이름이 비슷한 HC-06과 헷갈리기 쉬운데, HC-06은 블루투스 직렬 통신 모듈이고 초음파 거리 센서의 이름은 HC-SR04예요.

교실에서는 벽이나 상자처럼 평평하고 단단한 물체까지의 거리, 물에 닿지 않고 위에서 잰 수면 높이, 같은 간격으로 여러 번 재서 구한 장난감 수레의 속도 같은 것을 잴 수 있어요. 반대로 수건처럼 소리를 빨아들이는 물체, 크게 기울어진 면, 2cm보다 가까운 물체는 잘 잡지 못해요. 이 한계 자체도 좋은 탐구 대상이에요.

원리

Trig 핀에 10µs 넘게 HIGH를 주면 모듈이 40kHz 초음파를 8번 내보내고, Echo 핀을 HIGH로 올려요. 소리가 돌아오면 Echo가 LOW로 내려가니, Echo가 HIGH였던 시간이 곧 소리가 갔다 온 시간이에요. 거리는 그 시간 × 음속 ÷ 2예요. 왕복이라 2로 나눠요.

데이터시트는 음속을 340m/s로 계산하라고 적고, 같은 쪽에 "µs ÷ 58 = cm"라는 간단한 식도 줘요. 그런데 이 둘은 서로 조금 달라요. 58µs에 2cm를 간다는 말은 음속이 약 344.8m/s라는 뜻이거든요. 음속은 공기 온도에 따라 바뀌고, 흔히 쓰는 근사식은 음속(m/s) ≈ 331.3 + 0.606 × 기온(℃)이에요. 이 식으로 보면 340m/s는 약 14℃, 344.8m/s는 약 22℃의 음속이에요. 교실 온도가 계절마다 다르니, 코드에 그날 기온을 넣어 음속을 계산하는 편이 정확해요.

데이터시트는 한 번 잰 뒤 60ms 넘게 쉬고 다음 측정을 하라고 권해요. 앞에서 보낸 소리의 메아리가 늦게 돌아와 다음 측정에 섞이는 것을 막기 위해서예요.

준비물

  • 라즈베리파이 피코와 USB 케이블
  • HC-SR04(5V용) 또는 HC-SR04P(3~5.5V용)
  • 1kΩ 저항 1개, 2kΩ 저항 1개, 브레드보드, 점퍼선
  • 줄자, 온도계, 과녁으로 쓸 두꺼운 종이판(A4 크기 이상)
  • 탐구용: 수건, 스펀지, 각도기

배선

HC-SR04 초음파 거리 센서를 Echo 분압과 기온별 음속 보정으로 정확하게 쓰기: 브레드보드에 피코와 센서를 꽂은 배선 그림
시나브로 PICO 브레드보드 작업대와 같은 계산으로 그린 배선이에요. 위 + 줄은 3.3V, 아래 + 줄은 5V예요.
브레드보드 따라 꽂기 순서 (11단계)
  1. 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
  2. 빨간 선: 피코 40번 핀(VBUS) 옆 칸 a2 → 아래쪽 + 줄(5V). 이제 이 줄 전체가 5V예요. 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)은 절대 서로 잇지 않아요.
  3. 검은 선: 피코 3번 핀(GND) 옆 칸 j4 → 아래쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
  4. 초음파 거리 센서 HC-SR04 꽂기: 다리 VCC · Trig · Echo · GND를 아래쪽 j24 · j25 · j26 · j27에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
  5. 빨간 선(5V 전원): 초음파 거리 센서 VCC 줄 i24 → 아래쪽 + 줄(5V)
  6. 초록 선(신호): 초음파 거리 센서 Trig 줄 i25 → 피코 22번 핀(GP17) 옆 칸 a20
  7. 저항 1kΩ(색띠 갈색·검정·빨강): g26 ↔ g29 (Echo 다리 칸 → 나눔 칸 29열)
  8. 저항 2kΩ(색띠 빨강·검정·빨강): i29 ↔ 아래쪽 − 줄(GND)
  9. 초록 선: 나눔 칸 h29 → 피코 21번 핀(GP16) 옆 칸 a21. 5V 신호가 3.3V 아래로 줄어 피코가 안전해요.
  10. 검은 선(GND): 초음파 거리 센서 GND 줄 i27 → 아래쪽 − 줄(GND)
  11. 마지막 확인: ① 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)이 서로 이어지지 않았나요? ② 모든 부품의 GND가 − 줄에 이어졌나요? ③ 5V 신호 다리는 저항을 거쳐 피코에 이어졌나요? ④ 긴 브레드보드는 + − 줄이 가운데에서 끊긴 것도 있어요(빨간·파란 선이 끊겨 있으면 짧은 선으로 이어요). ⑤ 그림과 한 칸씩 비교한 뒤 USB를 꽂아요.
모듈 핀 피코 핀 비고
VCC VBUS (40번) 5V, 데이터시트 동작 전류 15mA
Trig GP17 (22번) 피코의 3.3V 출력을 그대로 연결
Echo GP16 (21번) 1kΩ·2kΩ 분압 뒤 연결
GND GND (38번) 피코와 접지를 함께 써요

Echo는 5V 전원에서 5V 펄스를 내요. 그래서 Echo ─ 1kΩ ─ ● ─ 2kΩ ─ GND로 잇고 가운데 점(●)을 GP16에 연결해요. 가운데 점의 전압은 5V × 2/3, 약 3.33V예요. 피코 2(RP2350)의 디지털 핀은 3.3V 전원이 켜져 있는 동안 5.5V까지 견디지만, 피코 전원이 꺼진 때에는 그렇지 않아요. 센서가 피코보다 먼저 켜지는 일도 있으니 어느 보드든 분압해요. 저항을 1kΩ·2kΩ처럼 작게 쓰는 이유는 펄스의 모서리가 무뎌지지 않게 하려는 거예요(분압 회로).

HC-SR04P처럼 3.3V로 동작하는 판이라면 VCC를 3V3(36번)에 잇고 Echo를 분압 없이 GP16에 연결해요. 이때 Echo도 3.3V로 나와요. 판에 적힌 모델명을 먼저 확인해요.

코드

from machine import Pin, time_pulse_us
import time

trig = Pin(17, Pin.OUT, value=0)
echo = Pin(16, Pin.IN)            # Echo → 1kΩ/2kΩ 분압 → GP16
TEMP_C = 20.0                     # 지금 공기 온도(℃). 온도계로 재서 바꿔요
v = 331.3 + 0.606 * TEMP_C        # 음속(m/s)

def ping():
    trig.value(1)
    time.sleep_us(10)             # 10µs 넘게 HIGH
    trig.value(0)
    return time_pulse_us(echo, 1, 30000)   # Echo가 HIGH였던 시간(µs). 음수면 실패

print(f"기온 {TEMP_C}℃, 음속 {v:.1f} m/s로 계산해요")
while True:
    vals = []
    for i in range(5):
        t = ping()
        if t > 0:
            d = t * v / 20000     # 왕복 ÷ 2, m/s × µs → cm
            if 2 <= d <= 400:
                vals.append(d)
        time.sleep_ms(60)         # 데이터시트: 60ms 넘게 쉬고 다시 재기
    if vals:
        vals.sort()
        print(f"DATA: dist={vals[len(vals) // 2]:.1f}, n={len(vals)}")
    else:
        print("DATA: dist=-1, n=0")
    time.sleep(0.5)
  • TEMP_C에 그날 기온을 넣으면 음속을 다시 계산해요. 20℃면 343.4m/s예요.
  • time_pulse_us(echo, 1, 30000)은 Echo가 HIGH로 있던 시간을 µs로 돌려줘요. 30ms 안에 끝나지 않으면 음수를 돌려줘요. 30ms는 20℃에서 약 5m 거리라 측정 범위 4m보다 넉넉해요.
  • t * v / 20000은 µs와 m/s를 cm로 바꾸고 왕복을 2로 나눈 식이에요.
  • 다섯 번 재서 2~400cm 안의 값만 모으고, 가운데 값(중앙값)을 내보내요. n은 다섯 번 중 성공한 횟수라서, 값을 얼마나 믿을지 알려 주는 숫자예요.

값 해석과 보정

기온을 틀리게 넣으면 얼마나 어긋날까요? 코드는 20℃로 계산하는데 실제 공기가 30℃라면 음속이 349.5m/s라서, 코드가 낸 거리는 실제보다 약 1.7% 짧아요. 200cm 거리라면 3.5cm쯤 모자라요. 실제가 0℃라면 반대로 약 3.7% 길게 나와요. 1cm를 다투는 실험이라면 기온을 꼭 함께 재요.

기온을 맞춰도 생기는 차이는 보정식으로 줄여요. 줄자로 잰 실제 거리와 센서 거리를 여러 점에서 기록한 뒤, 실제 거리 = a × 센서 거리 + b 꼴의 직선을 구해요. b는 센서 앞면과 줄자의 0점이 다른 데서 오는 차이, a는 남은 음속 차이나 시간 측정 차이를 담아요.

n이 자주 5보다 작으면 과녁이 너무 멀거나, 기울었거나, 소리를 빨아들이는 재질이라는 신호예요. 측정 각도가 15°라서 거리가 멀수록 소리가 퍼지는 폭도 넓어져요. 과녁보다 가까운 책상 모서리나 옆 벽이 먼저 메아리를 보내면 엉뚱하게 짧은 거리가 나오니, 소리가 지나가는 길을 비워 둬요.

자주 하는 실수

  1. Echo를 GP16에 바로 꽂기. 5V 펄스가 그대로 들어가요. 반드시 분압하거나 HC-SR04P를 써요.
  2. 1kΩ과 2kΩ의 자리를 바꾸기. 비율이 1/3이 되어 약 1.67V만 들어가요. RP2350이 HIGH로 읽는 최소 전압(2V)보다 낮아서 "메아리 없음"만 계속 나와요.
  3. 60ms보다 빨리 연달아 재기. 앞 측정의 메아리가 섞여 값이 들쭉날쭉해요.
  4. 음수를 거리로 쓰기. time_pulse_us의 음수는 시간 초과라는 뜻이에요. 그래프에 넣기 전에 걸러요.
  5. 센서를 손에 들고 재기. 각도가 조금만 바뀌어도 과녁이 빔 밖으로 나가요. 받침에 고정해요.

이 센서로 잴 수 있는 탐구

1. 거리에 따라 오차가 커질까 - 질문: 실제 거리가 멀어질수록 센서 거리와 줄자 거리의 차이가 커질까? - 바꾸는 것: 과녁까지의 거리 10cm부터 200cm까지 20cm 간격 - 재는 것: 센서 거리와 줄자 거리의 차이(cm), 성공 횟수 n - 방법: 센서를 받침에 고정하고 종이판을 바닥에 수직으로 세워요. 거리마다 10줄씩 기록해 평균을 내고, 그 결과로 보정식을 구해요. 잴 때의 기온도 적어요.

2. 재질에 따라 메아리가 약해질까 - 질문: 단단한 판과 수건, 스펀지는 성공 횟수가 얼마나 다를까? - 바꾸는 것: 과녁 재질(종이판, 수건을 씌운 판, 스펀지). 거리는 50cm로 고정 - 재는 것: 20줄 기록에서 n의 평균, 거리 오차(cm) - 방법: 같은 판에 재질만 바꿔 붙여 크기를 맞춰요. 재질마다 3번 반복해요.

3. 과녁이 기울면 언제부터 놓칠까 - 질문: 판을 기울이는 각도가 커지면 성공 횟수가 어떻게 줄어들까? - 바꾸는 것: 판의 기울기 0°, 15°, 30°, 45°(각도기로 맞춤). 거리 50cm 고정 - 재는 것: n의 평균, dist=-1이 나온 비율(%) - 방법: 판의 가운데를 같은 자리에 두고 각도만 바꿔요. 소리가 다른 벽으로 튕겨 가지 않도록 주변을 비우고 각도마다 3번 반복해요.

안전

  • VBUS(5V) 선이 GP 핀에 닿지 않게 하고, 배선은 USB를 뽑은 채로 바꿔요.
  • 이 장치는 교육용이에요. 주차 보조나 시각 보조처럼 사람의 안전이 걸린 곳에 쓰지 마세요.
  • 센서를 단 로봇을 움직일 때는 느린 속도에서 먼저 시험하고, 계단이나 책상 끝 가까이에서는 손으로 잡을 준비를 해요.

더 알아보기

글쓴이

홍창민 · 울산 학성고등학교 정보·인공지능 교사. 수업에 쓰는 도구(시나브로 PICO 웹 IDE, 학교 AI 서버 등)를 직접 만들어 운영해요. 소개 보기 · 고칠 곳 알려 주기