가스·공기 · 난이도 쉬움
BME280 기압으로 해발 고도와 계단 높이 차이 재기, 온도·습도 오차까지
BME280은 온도·습도·기압을 I²C로 함께 주는 3.3V 센서예요. 주소 0x76·0x77과 칩 ID로 BMP280을 가려내는 법, 해면 기압을 넣어 고도를 구하고 출발점 기압으로 계단 높이를 재는 피코 코드, 자체 발열 같은 오차를 줄이는 법을 정리했어요.
이 센서로 무엇을 잴 수 있나
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) 줄자
배선
브레드보드 따라 꽂기 순서 (9단계)
- 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
- 주황 선: 피코 36번 핀(3V3(OUT)) 옆 칸 a6 → 위쪽 + 줄(3.3V). 이제 이 줄 전체가 3.3V예요.
- 검은 선: 피코 38번 핀(GND) 옆 칸 a4 → 위쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
- 온도·습도·기압 BME280 꽂기: 다리 SDA · SCL · VCC/VIN · GND를 위쪽 a24 · a25 · a26 · a27에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
- 파란 선(신호): 온도·습도·기압 SDA 줄 b24 → 피코 6번 핀(GP4) 옆 칸 j7
- 파란 선(신호): 온도·습도·기압 SCL 줄 b25 → 피코 7번 핀(GP5) 옆 칸 j8
- 주황 선(3.3V 전원): 온도·습도·기압 VCC/VIN 줄 b26 → 위쪽 + 줄(3.3V)
- 검은 선(GND): 온도·습도·기압 GND 줄 b27 → 위쪽 − 줄(GND)
- 마지막 확인: ① 위쪽 + 줄(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까지 달라도 둘 다 규격 안일 수 있어요. 같은 센서로 잰 변화를 비교해요.
자주 하는 실수
- BMP280을 BME280으로 알고 쓰기. 겉모양이 거의 같아요. 습도가 늘 0이거나 코드가 칩 ID 0x58을 알려 주면 BMP280이에요.
- VIN에 5V를 넣기. 칩 전원 범위는 3.6V까지예요. 3V3에 연결해요.
- P0를 1013.25 그대로 두고 "우리 학교 고도"라고 발표하기. 그날의 해면 기압을 넣지 않으면 수십 m가 틀릴 수 있어요.
- 센서를 피코 위에 바로 꽂고 기온을 재기. 피코와 칩의 열로 온도가 높게 나와요.
- 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를 뽑고 바꿔요.
- 이 장치는 인증받은 기상 관측 장비가 아니에요. 날씨 경보나 안전 판단에 쓰지 마세요.
더 알아보기
- 데이터시트: Bosch Sensortec "BME280 Data sheet" BST-BME280-DS001(동작 범위, 정확도, I²C 주소, 칩 ID, 자체 발열 주석, 권장 측정 모드)
- 라이브러리: robert-hh/BME280의
bme280_float.py(MIT 라이선스,read_compensated_data(),sealevel,altitude) - 기초 글: I²C 장치 여러 개 연결하기, 피코 핀 지도, 센서 값의 신뢰도, 브레드보드 기초