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

가스·공기 · 난이도 쉬움

BME280 기압으로 해발 고도와 계단 높이 차이 재기, 온도·습도 오차까지

BME280은 온도·습도·기압을 I²C로 함께 주는 3.3V 센서예요. 주소 0x76·0x77과 칩 ID로 BMP280을 가려내는 법, 해면 기압을 넣어 고도를 구하고 출발점 기압으로 계단 높이를 재는 피코 코드, 자체 발열 같은 오차를 줄이는 법을 정리했어요.

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

이 센서로 무엇을 잴 수 있나

BME280은 보쉬(Bosch Sensortec)가 만든 2.5mm 크기의 칩 하나로 온도, 상대습도, 기압을 함께 재는 센서예요. 데이터시트의 동작 범위는 −40~85℃, 0~100%RH, 300~1100hPa이에요. 습도 정확도는 ±3%RH, 기압 절대 정확도는 ±1.0hPa(0~65℃)이고, 25℃에서 온도 정확도는 ±0.5℃예요.

기압을 이렇게 촘촘히 재는 이유는 높이 때문이에요. 데이터시트는 기압 잡음 0.2Pa를 높이 1.7cm로 환산해 적고, 쓰임새에 "층 바뀜 감지, 엘리베이터 감지"를 넣어 두었어요. 그래서 학교에서는 계단을 오르며 한 층 높이를 기압으로 재거나, 며칠 동안 기압을 기록해 날씨와 비교하거나, 교실의 온도와 습도를 기록하는 데 써요.

원리

공기는 위로 갈수록 얇아져서 기압이 낮아져요. 데이터시트의 환산(0.2Pa ≈ 1.7cm)을 거꾸로 하면, 땅 가까이에서는 1hPa가 약 8.5m 높이에 해당해요. 이 글의 코드는 robert-hh 라이브러리와 같은 식을 써요.

고도 = 44330 × (1 − (p ÷ p₀)^0.1903)

p는 지금 기압, p₀은 기준 기압이에요. p₀에 해면 기압(바다 높이로 환산한 기압)을 넣으면 해발 고도가, 출발점에서 잰 기압을 넣으면 출발점보다 몇 m 높은지가 나와요. 해면 기압은 날씨에 따라 날마다 바뀌어요. 그래서 기본값 1013.25hPa를 그대로 두면 고도가 틀려요. 차이가 5hPa라면 오차는 40m 남짓이에요.

통신은 I²C예요. 주소는 SDO 핀을 GND에 연결하면 0x76, 3.3V에 연결하면 0x77이고, SDO를 떠 있게 두면 주소가 정해지지 않아요. 칩 ID 레지스터(0xD0)를 읽으면 BME280은 0x60, 습도가 없는 BMP280은 0x58(양산품)이 나와요.

준비물

  • 라즈베리파이 피코와 USB 케이블
  • BME280 I²C 모듈(4핀 또는 6핀)
  • 점퍼선, 브레드보드
  • 라이브러리 파일 bme280_float.py(robert-hh/BME280)를 피코에 저장
  • (탐구 1) 줄자

배선

BME280 기압으로 해발 고도와 계단 높이 차이 재기, 온도·습도 오차까지: 브레드보드에 피코와 센서를 꽂은 배선 그림
시나브로 PICO 브레드보드 작업대와 같은 계산으로 그린 배선이에요. 위 + 줄은 3.3V, 아래 + 줄은 5V예요.
브레드보드 따라 꽂기 순서 (9단계)
  1. 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
  2. 주황 선: 피코 36번 핀(3V3(OUT)) 옆 칸 a6 → 위쪽 + 줄(3.3V). 이제 이 줄 전체가 3.3V예요.
  3. 검은 선: 피코 38번 핀(GND) 옆 칸 a4 → 위쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
  4. 온도·습도·기압 BME280 꽂기: 다리 SDA · SCL · VCC/VIN · GND를 위쪽 a24 · a25 · a26 · a27에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
  5. 파란 선(신호): 온도·습도·기압 SDA 줄 b24 → 피코 6번 핀(GP4) 옆 칸 j7
  6. 파란 선(신호): 온도·습도·기압 SCL 줄 b25 → 피코 7번 핀(GP5) 옆 칸 j8
  7. 주황 선(3.3V 전원): 온도·습도·기압 VCC/VIN 줄 b26 → 위쪽 + 줄(3.3V)
  8. 검은 선(GND): 온도·습도·기압 GND 줄 b27 → 위쪽 − 줄(GND)
  9. 마지막 확인: ① 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)이 서로 이어지지 않았나요? ② 모든 부품의 GND가 − 줄에 이어졌나요? ③ 5V 신호 다리는 저항을 거쳐 피코에 이어졌나요? ④ 긴 브레드보드는 + − 줄이 가운데에서 끊긴 것도 있어요(빨간·파란 선이 끊겨 있으면 짧은 선으로 이어요). ⑤ 그림과 한 칸씩 비교한 뒤 USB를 꽂아요.
모듈 핀 피코 핀 비고
VIN 또는 VCC 3V3(OUT) (36번) 칩 전원 범위 1.71~3.6V
GND GND (38번) 공통 접지
SDA GP4 (6번) I2C0 SDA
SCL GP5 (7번) I2C0 SCL
SDO(있으면) GND 또는 3V3 GND면 0x76, 3V3면 0x77
CSB(있으면) 3V3 3.3V에 연결해야 I²C로 동작

이 센서는 분압 저항이 필요 없어요. 칩이 3.3V로 동작하고, VIN을 3V3에 꽂으면 모듈의 SDA·SCL 풀업 저항이 어디에 연결되어 있든 신호가 3.3V를 넘지 않아요. 5V를 넣으면 칩이 망가지거나 신호가 5V로 올라갈 수 있어요. CSB 핀은 데이터시트에 따르면 3.3V에 연결되어야 I²C가 켜지고, 한 번이라도 LOW로 내려가면 다시 전원을 켤 때까지 I²C가 꺼져요. CSB가 핀으로 나와 있지 않은 모듈은 보드 안에서 처리된 것이니, CSB 핀이 보이는 6핀 모듈만 확인하면 돼요.

코드

from machine import Pin, I2C
import time
import bme280_float as bme280

i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
found = i2c.scan()
addr = None
for a in (0x76, 0x77):
    if a in found:
        addr = a
if addr is None:
    raise RuntimeError("BME280을 못 찾았어요: 3V3, GND, SDA=GP4, SCL=GP5 확인")
chip = i2c.readfrom_mem(addr, 0xD0, 1)[0]
if chip != 0x60:
    raise RuntimeError("칩 ID가 0x60이 아니에요(0x58이면 습도 없는 BMP280)")
bme = bme280.BME280(i2c=i2c, address=addr)
print("주소", hex(addr), "칩 ID", hex(chip))

P0 = 1013.25                   # 해면 기압(hPa). 오늘 기상청 값으로 바꾸기
t, p, h = bme.read_compensated_data()
p_start = p / 100              # 출발점 기압: 높이 차이의 기준

while True:
    t, p, h = bme.read_compensated_data()
    hpa = p / 100
    alt = 44330 * (1 - (hpa / P0) ** 0.1903)       # 해면 기압 기준 고도(m)
    dz = 44330 * (1 - (hpa / p_start) ** 0.1903)   # 출발점보다 몇 m 높은가
    print(f"DATA: temp={t:.2f}, hum={h:.1f}, hpa={hpa:.2f}, alt={alt:.1f}, dz={dz:.2f}")
    time.sleep(2)
  • 먼저 I²C로 0x76과 0x77을 찾고, 칩 ID가 0x60인지 확인해요. 아니면 이유를 알려 주며 멈춰요.
  • read_compensated_data()는 (온도 ℃, 기압 Pa, 습도 %RH)를 돌려줘요. 기압을 100으로 나눠 hPa로 바꿔요.
  • P0에 오늘의 해면 기압을 넣어요. 기상청 관측 자료에서 가까운 지점의 해면기압(hPa)을 찾으면 돼요.
  • p_start는 코드를 켠 곳의 기압이에요. dz는 그곳보다 몇 m 높은지라서, 해면 기압을 몰라도 높이 차이를 잴 수 있어요.

값 해석과 보정

높이 차이(dz)는 짧은 시간에 잴수록 정확해요. 날씨가 바뀌면 출발점의 기압 자체가 바뀌기 때문이에요. 계단 실험은 출발점으로 다시 돌아와 dz가 0으로 돌아오는지 확인하고, 남은 차이를 그 실험의 오차로 적어요. 데이터시트의 상대 정확도 ±0.12hPa(700~900hPa, 25~40℃ 조건)는 약 1m에 해당하니, 한 층(몇 m) 차이는 충분히 보여요.

온도도 조심해요. 데이터시트는 기압 값이 온도 1℃ 변화마다 ±1.5Pa(높이 ±12.6cm) 흔들릴 수 있다고 적어요. 따뜻한 교실과 찬 계단을 오가면 이만큼 더해진다는 뜻이에요. 층마다 30초 멈춰 값이 자리 잡게 해요.

온도 값은 주변 공기보다 높게 나오기 쉬워요. 데이터시트는 이 온도가 기판 온도, 칩의 자체 발열, 주변 온도에 따라 달라지고 보통 주변보다 높다고 적어요. 피코 바로 위에 꽂거나 손에 쥐면 더 높아져요. 선을 길게 빼서 떨어뜨려 두세요.

습도 ±3%RH는 센서 하나가 참값에서 3%RH까지 벗어날 수 있다는 뜻이에요. 그래서 두 센서는 서로 6%RH까지 달라도 둘 다 규격 안일 수 있어요. 같은 센서로 잰 변화를 비교해요.

자주 하는 실수

  1. BMP280을 BME280으로 알고 쓰기. 겉모양이 거의 같아요. 습도가 늘 0이거나 코드가 칩 ID 0x58을 알려 주면 BMP280이에요.
  2. VIN에 5V를 넣기. 칩 전원 범위는 3.6V까지예요. 3V3에 연결해요.
  3. P0를 1013.25 그대로 두고 "우리 학교 고도"라고 발표하기. 그날의 해면 기압을 넣지 않으면 수십 m가 틀릴 수 있어요.
  4. 센서를 피코 위에 바로 꽂고 기온을 재기. 피코와 칩의 열로 온도가 높게 나와요.
  5. SDO를 아무 데도 연결하지 않은 모듈 쓰기. 주소가 정해지지 않아 0x76과 0x77 어느 쪽에서도 안 보일 수 있어요.

이 센서로 잴 수 있는 탐구

1. 한 층 올라가면 기압은 얼마나 줄까 - 질문: 계단으로 한 층 오를 때마다 기압은 몇 hPa 줄고, 기압으로 계산한 높이는 실제와 얼마나 맞을까? - 바꾸는 것: 층(1층부터 4층까지 각 층 계단참) - 재는 것: 기압(hPa), dz(m), 줄자로 잰 실제 높이(m) - 방법: 노트북에 연결한 채 두 사람이 함께 움직여요. 1층에서 코드를 시작하고 층마다 30초 멈춰 평균을 내요. 다시 1층으로 내려와 출발값과의 차이를 확인하고, 3번 반복해요. 실제 높이는 계단 한 칸 높이 × 칸 수로 구해요.

2. 기압이 내려가면 날씨가 나빠질까 - 질문: 2주 동안 같은 시각의 기압 변화가 날씨 변화와 함께 나타날까? - 바꾸는 것: 날짜(2주) - 재는 것: 매일 같은 시각의 기압(hPa), 기상청 해면기압(hPa), 그날의 날씨 기록 - 방법: 같은 자리에서 잰 기압과 해면기압의 차이가 날마다 거의 같은지도 함께 봐요. 차이가 일정하면 그 값이 우리 학교 높이 때문에 생긴 차이예요.

3. 센서 위치가 온도에 얼마나 영향을 줄까 - 질문: 피코 바로 옆에 둔 센서와 20cm 선 끝에 둔 센서의 온도는 얼마나 다를까? - 바꾸는 것: 센서 위치(피코 옆, 20cm 떨어짐), 읽는 간격(2초, 60초) - 재는 것: 온도(℃)와 두 조건의 차이(℃) - 방법: 같은 책상에서 30분씩 기록하고 마지막 10분 평균을 비교해요. 센서가 하나면 조건을 바꿔 가며 같은 시간대에 재요.

안전

  • 계단 실험은 걸으면서 화면을 보지 않아요. 계단참에 멈춘 뒤 기록하고, 뛰지 않아요.
  • 전원은 3.3V만 써요. 배선은 USB를 뽑고 바꿔요.
  • 이 장치는 인증받은 기상 관측 장비가 아니에요. 날씨 경보나 안전 판단에 쓰지 마세요.

더 알아보기

글쓴이

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