가스·공기 · 난이도 어려움
MQ-7 일산화탄소 센서에 5V 60초·1.4V 90초 히터 주기가 필요한 이유
MQ-7은 히터를 5V로 60초, 1.4V로 90초 번갈아 데우며 저온 구간 끝에서 CO를 재도록 설계된 센서예요. 5V를 계속 주는 일반 모듈의 한계, MOSFET과 PWM으로 히터 주기를 만드는 법, CO를 만들지 않고 할 수 있는 탐구를 정리했어요.
이 센서로 무엇을 잴 수 있나
MQ-7은 일산화탄소(CO)에 감도가 높도록 만든 산화주석 센서예요. 한웨이 데이터시트의 감지 범위는 CO 20~2000ppm이에요. 그런데 MQ-7은 다른 MQ 센서와 쓰는 법이 달라요. 히터를 5V로 60초, 1.4V로 90초씩 번갈아 데워야 하고, CO는 낮은 온도 구간에서 재요. 데이터시트는 "높은 온도(5V)에서는 낮은 온도에서 달라붙은 다른 기체를 씻어 낸다"고 설명해요.
학교에서는 CO를 만들 수 없고 만들어서도 안 돼요. 그래서 이 글은 CO 농도 대신 센서가 움직이는 방식을 재요. 히터 주기에 따라 출력이 어떤 모양으로 오르내리는지, 주기마다 저온 끝 값이 얼마나 일정한지, 알코올 같은 다른 기체에는 언제 더 반응하는지, 히터가 실제로 전력을 얼마나 쓰는지예요. 이것을 알면 "왜 싼 모듈로 CO 경보기를 만들면 안 되는지"를 근거를 들어 설명할 수 있어요.
원리
히터 저항은 33Ω(±5%)이에요. 계산해 보면 5V에서는 5² ÷ 33 ≈ 0.76W, 1.4V에서는 1.4² ÷ 33 ≈ 0.06W예요. 60초와 90초로 시간 평균을 내면 약 0.34W이고, 데이터시트의 히터 소비 전력 "약 350mW"와 맞아요. 흔한 MQ-7 모듈은 히터를 VCC 5V에 그대로 연결해 두어서, 0.76W를 쉬지 않고 받아요. 설계 평균의 두 배가 넘는 열이에요.
측정도 정해진 때에 해요. 데이터시트는 깨끗한 공기에서 CO로 옮겼을 때 한두 주기(5V에서 1.4V까지 2.5분) 안에 재라고 하고, 감도 조정 순서도 "90초가 끝나는 순간"과 "60초가 끝나는 순간"의 신호로 설명해요. CO는 낮은 온도에서 잰다고 했으니, 이 글은 90초 저온 구간의 끝 값을 판단에 써요. 감도 곡선의 기준 Ro는 "깨끗한 공기 속 100ppm CO에서의 저항", 부하 저항은 10kΩ이에요. 제목이 "MQ-7 Semiconductor Sensor for Carbon Monoxide"인 새 형식 판은 저온 전압을 1.5V로 적어요.
피코로 1.4V를 만들 때는 PWM을 써요. 히터 열은 전압의 제곱에 비례하므로, 5V를 켰다 껐다 하는 비율(듀티)을 (1.4 ÷ 5)² ≈ 0.078로 두면 1.4V를 건 것과 같은 열이 나요. duty_u16으로는 65535 × 0.078 ≈ 5138이에요.
준비물
- 기본: 라즈베리파이 피코, MQ-7 모듈, 10kΩ·20kΩ 저항 1개씩, 브레드보드, 점퍼선
- 히터 주기(도전): 히터 핀이 따로 나온 MQ-7 센서 단품(6핀), 로직 레벨 N채널 MOSFET 1개(데이터시트에 게이트 2.5V나 3.3V 조건의 온저항이 적힌 것), 10kΩ 저항(게이트 풀다운), 10kΩ·20kΩ 저항
- 멀티미터(히터 전압·전류 확인), 손 소독제, 면봉
배선
브레드보드 따라 꽂기 순서 (10단계)
- 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
- 빨간 선: 피코 40번 핀(VBUS) 옆 칸 a2 → 아래쪽 + 줄(5V). 이제 이 줄 전체가 5V예요. 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)은 절대 서로 잇지 않아요.
- 검은 선: 피코 3번 핀(GND) 옆 칸 j4 → 아래쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
- 일산화탄소 CO MQ-7 꽂기: 다리 VCC · GND · AO를 아래쪽 j24 · j25 · j26에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
- 빨간 선(5V 전원): 일산화탄소 CO VCC 줄 i24 → 아래쪽 + 줄(5V)
- 검은 선(GND): 일산화탄소 CO GND 줄 i25 → 아래쪽 − 줄(GND)
- 저항 10kΩ(색띠 갈색·검정·주황): g26 ↔ g28 (AO 다리 칸 → 나눔 칸 28열)
- 저항 20kΩ(색띠 빨강·검정·주황): i28 ↔ 아래쪽 − 줄(GND)
- 초록 선: 나눔 칸 h28 → 피코 31번 핀(GP26) 옆 칸 a11. 5V 신호가 3.3V 아래로 줄어 피코가 안전해요.
- 마지막 확인: ① 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)이 서로 이어지지 않았나요? ② 모든 부품의 GND가 − 줄에 이어졌나요? ③ 5V 신호 다리는 저항을 거쳐 피코에 이어졌나요? ④ 긴 브레드보드는 + − 줄이 가운데에서 끊긴 것도 있어요(빨간·파란 선이 끊겨 있으면 짧은 선으로 이어요). ⑤ 그림과 한 칸씩 비교한 뒤 USB를 꽂아요.
기본(모듈 그대로):
| 모듈 핀 | 피코 핀 | 비고 |
|---|---|---|
| VCC | VBUS (40번) | 히터에 5V가 계속 들어가요 |
| GND | GND (38번) | 공통 접지 |
| AO | GP26 (31번) | 10kΩ·20kΩ 분압 뒤 연결 |
| DO | 연결 안 함 |
히터 주기(센서 단품, 바닥의 A·B·H 표시를 확인):
| 센서 핀(단품) | 피코 핀·연결 부품 | 비고 |
|---|---|---|
| H 한쪽 | VBUS (40번) | 히터 + |
| H 다른 쪽 | MOSFET 드레인 | 소스는 GND, 게이트는 GP15(20번), 게이트와 GND 사이 10kΩ |
| A 두 핀 | VBUS (40번) | 측정 전압 Vc 5V |
| B 두 핀 | 10kΩ ─ GP26 ─ 20kΩ ─ GND | 두 저항(합 30kΩ)이 RL 역할 |
두 경우 모두 출력이 5V까지 오를 수 있어 10kΩ·20kΩ으로 2/3로 낮춰 GP26에 넣어요. 단품 배선에서는 이 30kΩ이 부하 저항이 돼요. 데이터시트가 권하는 RL 범위(5~47kΩ) 안이에요. 게이트 풀다운 10kΩ은 피코가 켜지는 동안 GP15가 떠 있어도 히터가 꺼진 상태로 있게 해요.
코드
기본 모듈용이에요. 히터 주기가 없으니 시작 값과 비교한 경향만 봐요.
from machine import ADC, Pin
import time
mq7 = ADC(Pin(26)) # 모듈 AO → 10kΩ/20kΩ 분압 → GP26
def volt():
s = 0
for i in range(16):
s += mq7.read_u16()
return s / 16 * 3.3 / 65535 * 1.5
base = volt()
print(f"시작 전압 {base:.3f} V (히터 5V 연속: 경향만 봐요)")
while True:
v = volt()
rise = (v - base) / base * 100 if base > 0 else 0
print(f"DATA: mq7_v={v:.3f}, rise={rise:.1f}")
time.sleep(2)
히터 주기용이에요. 60초 고온, 90초 저온을 되풀이하며 1초마다 값을 내보내요.
from machine import ADC, Pin, PWM
import time
mq7 = ADC(Pin(26)) # RL 양 끝 전압 → 10kΩ/20kΩ 분압 → GP26
heater = PWM(Pin(15)) # GP15 → MOSFET 게이트 → 히터
heater.freq(1000)
HIGH = 65535 # 5V 그대로(고온 60초)
LOW = 5138 # 65535×(1.4/5)²: 1.4V를 걸 때와 같은 열(저온 90초)
def volt():
s = 0
for i in range(16):
s += mq7.read_u16()
return s / 16 * 3.3 / 65535 * 1.5
cycle = 0
while True:
cycle += 1
heater.duty_u16(HIGH)
for t in range(60):
print(f"DATA: mq7_v={volt():.3f}, heater=5.0")
time.sleep(1)
heater.duty_u16(LOW)
for t in range(90):
v = volt()
print(f"DATA: mq7_v={v:.3f}, heater=1.4")
time.sleep(1)
print(f"{cycle}번째 주기, 저온 끝 값 {v:.3f} V (이 값끼리 비교)")
heater.freq(1000)은 1초에 1000번 켰다 껐다 하는 PWM이에요. 히터는 열이 천천히 변해서 평균 전력만 느껴요.- 고온 60초 동안은
heater=5.0, 저온 90초 동안은heater=1.4를 함께 찍어 그래프에서 구간을 구분해요. - 주기가 끝날 때 마지막
v, 곧 저온 구간 끝 값을 따로 출력해요. 주기끼리 비교할 때 이 값을 써요.
값 해석과 보정
주기 구동 그래프는 톱니 모양이 돼요. 온도가 바뀌면 막의 저항도 바뀌기 때문이에요. 그래서 한 주기 전체를 평균 내면 안 돼요. 주기와 주기를 비교할 때는 저온 끝 값끼리만 견줘요.
모듈 그대로 쓴 값은 데이터시트의 측정 조건(저온 90초의 끝)을 만들지 못한 값이에요. 그 값으로 CO 농도를 말할 수 없고, 같은 날 같은 자리에서 변화의 방향을 보는 정도로만 써요.
데이터시트의 감도 곡선에는 CO 말고도 수소, LPG, 메테인, 알코올 곡선이 함께 그려져 있어요. 값이 올랐다고 CO라고 단정할 수 없다는 뜻이에요. 데이터시트는 200ppm CO 표준 가스로 RL을 맞추라고 하는데, 학교에서는 할 수 없으니 ppm 환산도 하지 않아요.
자주 하는 실수
- 모듈이 히터 주기를 알아서 돌린다고 생각하기. 대부분의 모듈은 5V를 계속 줘요. 단품 배선을 하지 않았다면 주기 코드를 돌려도 히터는 그대로예요.
- 고온 값과 저온 값을 섞어 평균 내기. 서로 다른 온도에서 잰 값이라 평균은 아무 뜻이 없어요.
- 3.3V로 다 켜지지 않는 MOSFET 쓰기. 고온 구간에 히터 전압이 5V보다 한참 낮으면 MOSFET이 덜 켜진 거예요. 멀티미터로 히터 양 끝 전압을 확인해요.
- 6핀 센서의 같은 전극끼리 전압 걸기. 데이터시트는 1·3번이나 4·6번 핀 사이에 전압을 걸면 리드선이 끊어진다고 경고해요.
- CO를 만들어 시험하기. 어떤 이유로도 하지 않아요. 아래 안전을 꼭 읽어요.
이 센서로 잴 수 있는 탐구
1. 주기마다 저온 끝 값은 얼마나 일정할까 - 질문: 깨끗한 공기에서 켠 뒤 몇 번째 주기부터 저온 끝 값이 안정될까? - 바꾸는 것: 주기 번호(1~20번째, 약 50분) - 재는 것: 주기별 저온 끝 전압(V), 5주기씩 묶은 표준편차(V) - 방법: 같은 자리에서 주기 코드를 50분 돌리고, 출력된 끝 값을 표로 모아 앞뒤 구간의 흔들림을 비교해요.
2. 고온과 저온 중 언제 알코올에 더 반응할까 - 질문: 같은 소독제 면봉을 고온 구간에 댈 때와 저온 구간에 댈 때 반응이 다를까? - 바꾸는 것: 면봉을 대는 구간(고온 60초 중간, 저온 90초 중간) - 재는 것: 대기 직전 10초 평균보다 오른 비율(%) - 방법: 면봉 거리 4cm, 대는 시간 10초로 고정해요. 구간마다 3번 재고, 시도 사이에는 두 주기를 쉬어요.
3. 히터는 실제로 전력을 얼마나 쓸까 - 질문: 모듈 그대로일 때와 주기 구동일 때 히터 평균 전력은 얼마나 다를까? - 바꾸는 것: 구동 방식(5V 연속, 주기 구동) - 재는 것: 히터 전류(mA), VBUS 전압(V), 계산한 평균 전력(mW) - 방법: 단품 배선에서는 멀티미터를 히터 선에 직렬로 넣어 고온·저온 구간 전류를 따로 재요. 모듈은 히터 선을 따로 끊을 수 없으니 VCC 선에 넣어 전체 전류를 재요(측정 회로와 LED 전류가 조금 섞여요). 전력은 VBUS × 전류로 구하고, 주기 구동은 60초와 90초로 시간 평균을 내 데이터시트의 약 350mW와 비교해요.
안전
- 일산화탄소는 색도 냄새도 없고 아주 위험해요. 학생은 CO를 만드는 어떤 일도 하지 않아요. 촛불, 숯, 버너를 피우거나 자동차 배기가스를 모으거나, 닫힌 공간에서 무엇을 태우지 않아요.
- 이 장치는 인증받은 일산화탄소 경보기가 아니에요. 집, 캠핑, 난방 기구 주변의 CO 안전은 인증 경보기에 맡기세요. 인증 경보기가 울리면 즉시 밖으로 나가요.
- 히터가 뜨거워요. 주기 코드를 멈춰도 PWM이 켜진 채 남을 수 있으니, 실험이 끝나면 USB를 뽑아요.
- 배선을 바꿀 때는 전원을 끄고, VBUS 선이 GP 핀에 닿지 않게 해요.