[실습] 온습도 센서 이용한 온습도 측정
필기자
2026-04-27 17:30
884
0
본문
ASAIR-DHT22 온습도 센서를 이용한 온습도 측정
목 적
1. ASAIR-DHT22 온습도 센서 모듈 설치
2. adafruit-circuitpython-dht 라이브러리 설치 및 명세
3. ASAIR-DHT22 온습도 센서 모듈 구동
1. ASAIR-DHT22 온습도 센서 모듈 설치

2. adafruit-circuitpython-dht 라이브러리 설치 및 명세
--------------------------------------- 다음 오프라인 강의때 실습 -----------------------------------
[응용 문제: 온도 센서와 Blinka 라이브러리 실습]
목 적
- 라즈베리파이에 온습도 센서 사용법을 이해한다.
- adafruit-circuitpython-dht 라이브러리 활용법을 이해한다.
- Adafruit Blinka 라이브러리의 GPIO 제어 방식과 한계를 이해한다.
- 하드웨어 PWM과 소프트웨어 PWM의 차이를 이해한다.
- 온습도 측정값을 활용한 응용 프로그램 작성법을 이해한다.
1. ASAIR-DHT22 온습도 센서 모듈 설치
2. adafruit-circuitpython-dht 라이브러리 설치 및 명세
3. ASAIR-DHT22 온습도 센서 모듈 구동
1. ASAIR-DHT22 온습도 센서 모듈 설치
- ASAIR-DHT22 온습도 센서
- ASAIR-DHT22 센서는 온도와 습도를 측정할 수 있는 디지털 센서
- 높은 정밀도와 안정성을 제공하며, 라즈베리파이와 같은 마이크로컨트롤러와 쉽게 통합할 수 있음.
- 내장된 디지털 신호 처리 기능으로 온도와 습도 데이터를 정확하게 제공함.
- 홈 자동화, 날씨 스테이션, 스마트 농업 등 다양한 응용 분야에 사용됨.
- 기본 사양
- 전원 공급: 3.3V ~ 5.5V DC
- 소비 전류: 최대 1.5mA
- 온도 측정 범위: -40°C ~ 80°C
- 온도 정확도: ±0.5°C
- 습도 측정 범위: 0-100% RH
- 습도 정확도: ±2%
- 응답 시간:
- 습도: 5-30초 (63% 응답 기준)
- 온도: 약 2초
- GPIO 연결
- GND : Ground 접지(핀 14)
- VCC : 5V Power(핀 2)
- DATA : GPIO 18(핀 12)
- NC : 사용하지 않음
- ASAIR-DHT22 센서와 같은 온습도 센서를 연결할 때 GPIO 18(PCM_CLK)와 GPIO 4(GPCLK0)를 사용하는 이유
- 두 핀 모두 기본적으로 특정 기능(PCM 클럭 또는 일반 목적 클럭)을 가지고 있지만 기능이 필요하지 않은 경우 일반 GPIO 핀으로 많이 사용됨.
- 다른 GPIO 핀들의 I2C, SPI, UART 등과 같은 통신 기능을 가지고 있지 않아, 이런 특정 통신 기능과 충돌하지 않음.
- NC 핀이란
- NC (Not Connected) 핀은 전자 부품이나 회로에서 사용되지 않는 핀을 의미
- NC 핀의 목적 및 역할
- 회로 설계 시 표준화된 핀 배열을 유지하면서 특정 핀을 사용하지 않도록 할 수 있음.
- 미래의 업그레이드나 다른 버전에서 추가 기능을 위해 남겨둔 핀일 수 있음.
- 일부 회로에서는 특정 핀이 사용되지 않음으로써 다른 회로에 간섭을 줄일 수 있음.
- NC 핀을 사용하지 않는 이유
- NC 핀은 물리적으로 존재하지만, 내부적으로 회로에 연결되지 않았기 때문에 어떤 기능도 수행하지 않음.
- 회로를 단순하게 유지하기 위해 사용하지 않는 핀은 무시하는 것이 일반적임.
- NC 핀을 명확하게 구분해두면 다른 핀과 혼동을 피할 수 있음.
2. adafruit-circuitpython-dht 라이브러리 설치 및 명세
- 라이브러리 설치
- DHT 센서 드라이버 라이브러리 설치
- 의존성으로 Adafruit Blinka(GPIO 추상화 계층)가 자동 설치됨
- 설치 후 import board, import digitalio, import pwmio, import adafruit_dht 모두 사용 가능
#adafruit-circuitpython-dht 라이브러리 설치
pip install adafruit-circuitpython-dht
- Adafruit Blinka란
- Adafruit가 만든 호환성 계층(compatibility layer) 라이브러리
- CircuitPython(마이크로컨트롤러용 파이썬)에서 동작하는 코드를 라즈베리파이 같은 일반 리눅스 보드에서도 동작하게 해줌
- board.D18 같은 핀 객체를 보드에 맞게 자동 매핑해 줌 → 같은 코드를 다른 보드(아두이노, ESP32 등)에서도 거의 그대로 사용 가능
- 발음: 블링카(Blinka), 핀란드어로 "깜박이다(blink)"라는 뜻
- GPIO 외에도 SPI, I²C, UART 같은 통신 프로토콜 모듈(busio)도 제공하지만, 본 단원에서는 DHT22 활용에만 집중
- board 모듈 (Blinka 제공)
- 라즈베리파이 GPIO 핀을 객체로 표현
- D 뒤의 숫자는 BCM(GPIO) 번호를 의미
- 라즈베리파이의 모든 GPIO 핀이 board.D0 ~ board.D27 객체로 매핑됨
- 전체 핀 매핑표
Blinka BCM 물리 핀 특수 기능 board.D2 GPIO 2 3 I²C SDA board.D3 GPIO 3 5 I²C SCL board.D4 GPIO 4 7 GPCLK0 board.D5 GPIO 5 29 - board.D6 GPIO 6 31 - board.D7 GPIO 7 26 SPI CE1 board.D8 GPIO 8 24 SPI CE0 board.D9 GPIO 9 21 SPI MISO board.D10 GPIO 10 19 SPI MOSI board.D11 GPIO 11 23 SPI SCLK board.D12 GPIO 12 32 하드웨어 PWM0 board.D13 GPIO 13 33 하드웨어 PWM1 board.D14 GPIO 14 8 UART TXD board.D15 GPIO 15 10 UART RXD board.D16 GPIO 16 36 - board.D17 GPIO 17 11 실습 LED 연결 board.D18 GPIO 18 12 하드웨어 PWM0, DHT22 데이터 핀 board.D19 GPIO 19 35 하드웨어 PWM1 board.D20 GPIO 20 38 - board.D21 GPIO 21 40 - board.D22 GPIO 22 15 - board.D23 GPIO 23 16 - board.D24 GPIO 24 18 - board.D25 GPIO 25 22 - board.D26 GPIO 26 37 - board.D27 GPIO 27 13 실습 버튼 연결
- digitalio 모듈 (Blinka 제공) - 디지털 입출력
- GPIO 핀의 디지털 ON/OFF 제어를 담당
- 주요 클래스
- digitalio.DigitalInOut(pin) : GPIO 핀 객체 생성
- 주요 속성/메서드 (DigitalInOut 객체에서 사용)
- .direction : 핀 방향 설정 (입력/출력)
- digitalio.Direction.OUTPUT : 출력 모드
- digitalio.Direction.INPUT : 입력 모드
- .value : 핀의 HIGH/LOW 값
- 출력 모드일 때 : True 대입 → HIGH 출력, False 대입 → LOW 출력
- 입력 모드일 때 : 현재 핀 상태를 읽음 (True/False 반환)
- .deinit() : 핀 자원 해제
- .direction : 핀 방향 설정 (입력/출력)
- 프로그램 예시 - 출력 핀 (LED 1초 간격 깜박임)
- GPIO 17번 핀에 LED 연결
- 1초 간격으로 LED ON/OFF 무한 반복
- Ctrl+C로 종료 시 자원 해제
import time
import board
import digitalio
# 1. 핀 객체 생성 (GPIO 17)
led = digitalio.DigitalInOut(board.D17)
# 2. 방향 설정 (출력 모드)
led.direction = digitalio.Direction.OUTPUT
# 3. 1초 간격으로 LED ON/OFF 반복
try:
while True:
led.value = True # LED ON
print('LED ON')
time.sleep(1)
led.value = False # LED OFF
print('LED OFF')
time.sleep(1)
except KeyboardInterrupt:
# 4. 자원 해제
led.deinit()
print('\n프로그램 종료')
- 프로그램 예시 - 입력 핀 (버튼 폴링)
- GPIO 27번 핀에 버튼 연결
- 0.1초 간격으로 버튼 상태를 계속 읽으며, 눌림 상태가 바뀔 때만 출력
- Blinka는 이벤트(인터럽트)를 지원하지 않으므로 폴링 방식 사용
- Ctrl+C로 종료
import time
import board
import digitalio
# 1. 핀 객체 생성 (GPIO 27)
button = digitalio.DigitalInOut(board.D27)
# 2. 방향 설정 (입력 모드)
button.direction = digitalio.Direction.INPUT
# 3. 폴링 방식으로 버튼 상태 감시
prev_state = button.value
print('버튼 입력 대기 중... (Ctrl+C 종료)')
try:
while True:
curr_state = button.value
# 상태가 바뀐 순간에만 출력 (눌림 검출)
if curr_state != prev_state:
if curr_state:
print('버튼 떼짐 (HIGH)')
else:
print('버튼 눌림 (LOW)')
prev_state = curr_state
time.sleep(0.1) # 0.1초 간격 폴링
except KeyboardInterrupt:
# 4. 자원 해제
button.deinit()
print('\n프로그램 종료')
- 디지털 LED + 버튼 통합 실습 - 버튼으로 LED 제어
- 버튼을 누르고 있는 동안에만 LED가 켜지는 코드
- GPIO 17 (LED), GPIO 27 (버튼) 사용
- 0.05초 간격으로 폴링하여 버튼 상태에 따라 LED 제어
import time
import board
import digitalio
# LED 설정 (GPIO 17, 출력)
led = digitalio.DigitalInOut(board.D17)
led.direction = digitalio.Direction.OUTPUT
# 버튼 설정 (GPIO 27, 입력)
button = digitalio.DigitalInOut(board.D27)
button.direction = digitalio.Direction.INPUT
print('버튼을 누르면 LED가 켜집니다. (Ctrl+C 종료)')
try:
while True:
# 버튼이 눌리면 button.value가 False (LOW)
if not button.value:
led.value = True
else:
led.value = False
time.sleep(0.05)
except KeyboardInterrupt:
led.deinit()
button.deinit()
print('\n프로그램 종료')
- RPi.GPIO와 Blinka digitalio 코드 비교
동작 RPi.GPIO Blinka (digitalio) 핀 모드 설정 GPIO.setmode(GPIO.BCM) (별도 설정 불필요) 핀 객체 생성 GPIO.setup(17, GPIO.OUT) led = digitalio.DigitalInOut(board.D17) 방향 설정 GPIO.setup(17, GPIO.OUT) led.direction = digitalio.Direction.OUTPUT HIGH 출력 GPIO.output(17, GPIO.HIGH) led.value = True LOW 출력 GPIO.output(17, GPIO.LOW) led.value = False 입력값 읽기 GPIO.input(27) button.value 이벤트 감지 GPIO.add_event_detect() 지원하지 않음 (폴링 사용) 자원 해제 GPIO.cleanup() led.deinit()
- pwmio 모듈 (Blinka 제공) - PWM(펄스폭 변조) 제어
- LED 밝기, 모터 속도 등 아날로그처럼 동작하게 만드는 PWM 신호 생성
- 주요 클래스
- pwmio.PWMOut(pin, frequency, duty_cycle) : PWM 출력 객체 생성
- 주요 속성/메서드 (PWMOut 객체에서 사용)
- .frequency : PWM 주파수 (Hz)
- 객체 생성 시 frequency 인자로 초기값 지정
- 속성에 값을 대입하여 동적으로 변경 가능
- .duty_cycle : 듀티 사이클 (0 ~ 65535, 16비트 정수)
- 0 → 0% (항상 OFF)
- 32768 → 약 50%
- 65535 → 100% (항상 ON)
- RPi.GPIO의 0~100(%)와 단위가 다르므로 환산 필요
- .deinit() : PWM 정지 및 자원 해제
- .frequency : PWM 주파수 (Hz)
- 프로그램 예시 - LED 듀티 단계별 변화 관찰
- GPIO 12번 핀에 LED 연결 (하드웨어 PWM 가능 핀)
- 주파수 1000Hz, 듀티 0% → 25% → 50% → 75% → 100%로 1초씩 유지하며 반복
- 각 단계별 LED 밝기 차이를 눈으로 확인
import time
import board
import pwmio
# 1. PWM 출력 객체 생성 (GPIO 12, 1000Hz, 초기 듀티 0)
led = pwmio.PWMOut(board.D12, frequency=1000, duty_cycle=0)
# 2. 듀티 사이클 단계 (0%, 25%, 50%, 75%, 100%)
duty_steps = [0, 25, 50, 75, 100]
print('LED 밝기 단계별 변화 (Ctrl+C 종료)')
try:
while True:
for percent in duty_steps:
duty = int(percent / 100 * 65535)
led.duty_cycle = duty
print(f'듀티: {percent:3d}% ({duty})')
time.sleep(1)
except KeyboardInterrupt:
# 3. 자원 해제
led.deinit()
print('\n프로그램 종료')
- 하드웨어 PWM
- SoC(BCM2835/BCM2711) 칩 내부에 PWM 전용 회로가 내장
- CPU 부하 거의 없음, 정밀한 타이밍 보장
- 고주파(수 MHz)까지 안정적으로 출력 가능
- 라즈베리파이는 GPIO 12, 13, 18, 19의 4개 핀에서만 사용 가능
- PWM 채널은 2개 (PWM0, PWM1)
- PWM0 채널 : GPIO 12, GPIO 18
- PWM1 채널 : GPIO 13, GPIO 19
- 같은 채널을 공유하는 두 핀은 동일한 주파수/듀티로만 동작
- 소프트웨어 PWM
- CPU가 직접 ON/OFF를 반복하여 PWM을 흉내냄
- 모든 GPIO 핀에서 사용 가능
- CPU 부하 발생, 다른 작업이 끼어들면 타이밍 흔들림
- 주파수 한계 : 약 1kHz
- 1초에 1000번 ON/OFF = 1주기 1ms = 듀티 50%면 500µs ON/500µs OFF
- 리눅스가 RTOS가 아니므로 µs 단위 타이밍 흔들림 발생
- 1kHz 이상은 듀티 정확도가 떨어지고 CPU 부하가 급증
- LED 밝기 조절 정도엔 충분, 정밀 모터 제어나 오디오 신호 같은 고주파 용도엔 부적합
- 라이브러리별 PWM 지원 비교
라이브러리 하드웨어 PWM 소프트웨어 PWM 최대 주파수 (안정) 듀티 사이클 단위 사용 가능 핀 RPi.GPIO 지원하지 않음 지원 (모든 핀) 약 1 kHz 0 ~ 100 (%) 모든 GPIO pwmio (Blinka) 지원 지원하지 않음 수 MHz 0 ~ 65535 (16비트) GPIO 12, 13, 18, 19 pigpio 지원 지원 (DMA 기반, 안정적) HW: 수 MHz / SW: 수십 kHz 0 ~ 1000000 모든 GPIO
- 듀티 사이클 단위 환산
- RPi.GPIO 50% → pwmio 약 32768 (= 65535 × 0.5)
- 퍼센트(0~100)를 16비트값으로 환산: duty = int(percent / 100 × 65535)
- PWM LED 실습 - LED 밝기 점진적 페이드 (Blinka pwmio 사용)
- GPIO 12번 핀에 LED 연결 (하드웨어 PWM 가능 핀)
- 밝기를 0% → 100% → 0%로 부드럽게 변화시켜 페이드 효과 구현
- 주파수 1000Hz 고정, duty_cycle 0.05초 간격으로 5%씩 변화 (한 사이클 약 4초)
import time
import board
import pwmio
# PWM 출력 객체 생성 (GPIO 12, 1000Hz, 초기 듀티 0)
led = pwmio.PWMOut(board.D12, frequency=1000, duty_cycle=0)
print('LED 페이드 인/아웃 (Ctrl+C 종료)')
try:
while True:
# 0 → 100% (밝아짐)
for percent in range(0, 101, 5):
led.duty_cycle = int(percent / 100 * 65535)
print(f'듀티: {percent:3d}%')
time.sleep(0.05)
# 100% → 0% (어두워짐)
for percent in range(100, -1, -5):
led.duty_cycle = int(percent / 100 * 65535)
print(f'듀티: {percent:3d}%')
time.sleep(0.05)
except KeyboardInterrupt:
led.deinit()
print('\n프로그램 종료')
- RPi.GPIO와 Blinka pwmio 코드 비교
동작 RPi.GPIO Blinka (pwmio) 핀 모드 설정 GPIO.setmode(GPIO.BCM) (별도 설정 불필요) 핀 출력 모드 설정 GPIO.setup(12, GPIO.OUT) (객체 생성 시 자동 처리) PWM 객체 생성 pwm = GPIO.PWM(12, 1000) led = pwmio.PWMOut(board.D12, frequency=1000, duty_cycle=0) PWM 시작 pwm.start(0) (객체 생성과 동시에 시작) 듀티 사이클 변경 (50%) pwm.ChangeDutyCycle(50) led.duty_cycle = 32768 듀티 사이클 단위 0 ~ 100 (%) 0 ~ 65535 (16비트 정수) 주파수 변경 pwm.ChangeFrequency(500) led.frequency = 500 최대 안정 주파수 약 1 kHz 수 MHz PWM 정지 pwm.stop() led.deinit() 자원 해제 GPIO.cleanup() led.deinit() 사용 가능 핀 모든 GPIO (소프트웨어 PWM) GPIO 12, 13, 18, 19 (하드웨어 PWM)
- 주의: GPIO 17, 27 같은 일반 핀에 pwmio.PWMOut을 호출하면 오류 발생
- 예: pwmio.PWMOut(board.D17, ...) → ValueError 또는 RuntimeError
- 모든 핀에서 PWM이 필요한 경우에는 RPi.GPIO의 소프트웨어 PWM 사용
- Blinka 라이브러리의 한계
- 이벤트(인터럽트) 미지원
- RPi.GPIO의 add_event_detect 같은 콜백 등록 기능이 없음
- 버튼 입력 등은 while 루프로 직접 값을 읽는 폴링(polling) 방식만 가능
- 이벤트 기반 제어가 필요한 경우 RPi.GPIO 또는 별도 패치 사용 필요
- 하드웨어 PWM만 지원
- pwmio는 GPIO 12, 13, 18, 19에서만 동작
- 그 외 핀에서 PWM이 필요하면 RPi.GPIO 소프트웨어 PWM 사용 (단, 약 1kHz 이내로 제한됨)
- 듀티 사이클 단위 차이
- pwmio는 0~65535(16비트), RPi.GPIO는 0~100(%)
- 코드 이식 시 환산 필요
- 실습 환경에서의 RPi.GPIO vs Blinka 기능 비교
기능 RPi.GPIO (+ gpio_patch) Blinka 디지털 출력 지원 지원 디지털 입력 지원 지원 이벤트 감지 (콜백) 지원 (gpio_patch로 폴링 fallback 처리) 지원하지 않음 모든 핀 PWM 지원 (소프트웨어 PWM, 약 1kHz 한계) 지원하지 않음 (하드웨어 4개 핀만) 고주파 PWM 지원하지 않음 지원 (4개 핀, 수 MHz) 듀티 사이클 단위 0 ~ 100 (직관적) 0 ~ 65535 (환산 필요) - 정리
- Blinka는 센서 라이브러리(adafruit_dht 등) 의존성과 간단한 GPIO 제어용으로 적합
- 이벤트 처리, 모든 핀 PWM이 필요한 경우 기존 RPi.GPIO를 병행 사용
- 고주파 PWM이 필요한 경우 Blinka pwmio (GPIO 12/13/18/19) 사용
- 이벤트(인터럽트) 미지원
- adafruit_dht 모듈
- DHT 시리즈 센서 전용 드라이버 라이브러리
- 1-Wire 타이밍 제어, 데이터 파싱, 체크섬 검증을 모두 내부에서 처리
- 주요 클래스
- adafruit_dht.DHT22(pin) : DHT22 센서 객체 생성
- adafruit_dht.DHT11(pin) : DHT11 센서 객체 생성
- 주요 속성/메서드 (DHT22/DHT11 객체에서 사용)
- .temperature : 현재 온도(°C, float)
- 속성을 읽는 시점에 1-Wire 통신이 시작되며 측정이 발생
- 측정 실패 시 None 또는 RuntimeError 발생
- .humidity : 현재 습도(%, float)
- 속성을 읽는 시점에 측정이 발생
- 측정 실패 시 None 또는 RuntimeError 발생
- .exit() : 센서 자원 해제(GPIO 정리)
- .temperature : 현재 온도(°C, float)
- 주요 예외 처리
- RuntimeError : 일시적 통신 실패(타이밍 누락) → 무시하고 다음 측정 시도
- Exception : GPIO 점유 충돌 등 치명적 오류 → exit() 호출 후 종료
- 라즈베리파이 가상환경에서 파이썬 코딩
- VSCode에서 dht22_sensor.py 파일 생성
- DHT22 센서에서 온도와 습도 데이터를 읽어 주기적으로 출력하는 코드 실습
import time
import board
import adafruit_dht
# DHT22 센서 설정 (GPIO 18)
dht_device = adafruit_dht.DHT22(board.D18)
while True:
try:
# 센서에서 온도와 습도 읽기
temperature = dht_device.temperature
humidity = dht_device.humidity
# 데이터 출력
if humidity is not None and temperature is not None:
print(f'온도: {temperature:.1f}°C')
print(f'습도: {humidity:.1f}%')
else:
print('읽기 실패. 데이터가 없습니다.')
except RuntimeError as error:
# 센서에서 데이터를 읽는 중 오류 발생 처리
print(error.args[0])
except Exception as error:
dht_device.exit()
raise error
# 10초 동안 대기
time.sleep(10)
- 코드 라인별 해설
- import board
- Adafruit Blinka 라이브러리의 모듈
- 라즈베리파이 GPIO 핀을 객체 형태로 추상화하여 제공
- import adafruit_dht
- DHT 시리즈 센서 전용 드라이버 라이브러리
- 내부에서 1-Wire 통신, 데이터 파싱, 체크섬 검증까지 모두 처리
- dht_device = adafruit_dht.DHT22(board.D18)
- DHT22 센서 객체 생성
- board.D18 → BCM GPIO 18번 핀(물리 핀 12)을 데이터 핀으로 지정
- temperature = dht_device.temperature
- 이 속성을 읽는 시점에 실제 측정이 발생(라이브러리가 1-Wire 통신 시작)
- 측정 성공 시 float(섭씨 온도) 반환, 실패 시 None 또는 RuntimeError
- humidity = dht_device.humidity
- 마찬가지로 호출 시점에 측정 발생
- 측정 성공 시 float(% RH) 반환
- if humidity is not None and temperature is not None:
- 측정값이 None인 경우(일시적 실패)에 대비한 방어 코드
- except RuntimeError as error:
- 일시적인 타이밍 실패는 정상적으로 자주 발생함
- 오류 메시지만 출력하고 다음 루프에서 재측정 시도
- except Exception as error:
- RuntimeError 외의 치명적 오류 발생 시 처리
- dht_device.exit()로 GPIO 자원을 해제한 후 예외를 다시 던져 프로그램 종료
- time.sleep(10)
- 10초 간격으로 측정 반복
- 너무 자주 측정하면 센서가 정확한 값을 제공하지 못함
- import board
- 10초 대기 시간을 갖는 이유
- DHT22 센서의 제한 사항으로 인해 최소 2초의 간격을 두고 데이터를 요청해야 하며, 너무 자주 데이터를 요청하면 센서가 정확한 값을 제공하지 못함.
- 자주 데이터를 요청하면 전력 소비가 증가함으로, 10초 간격으로 데이터를 요청함으로써 전력 소비를 줄일 수 있음.
- 온도와 습도는 일반적으로 빠르게 변하지 않으므로, 10초 간격으로 데이터를 요청하면 실시간 모니터링에 충분히 적절한 데이터를 얻을 수 있음.
- RuntimeError가 자주 발생하는 이유
- DHT22는 마이크로초(µs) 단위로 비트 신호를 송신함
- 라즈베리파이 OS(Linux)는 실시간 운영체제(RTOS)가 아니므로, 다른 작업이 끼어들면 비트 타이밍을 놓칠 수 있음
- 이 경우 라이브러리는 RuntimeError를 발생시키며, 이는 비정상이 아닌 정상적으로 자주 일어나는 현상임
- 따라서 try/except로 감싸 무시하고 다음 측정으로 넘어가는 구조가 표준 패턴임
- 첫 측정값의 신뢰도
- 전원 인가 직후 센서 내부 회로가 안정화되기 전에는 측정값이 부정확할 수 있음
- 첫 1~2회 측정값은 무시하거나, 일정 시간 워밍업 후 사용하는 것이 안정적
--------------------------------------- 다음 오프라인 강의때 실습 -----------------------------------
[응용 문제: 온도 센서와 Blinka 라이브러리 실습]
- 응용 예시 1 : 온도 임계치에 따른 LED 제어 (Blinka digitalio 사용)
- 온도가 28°C 이상일 때 LED를 켜고, 미만일 때 LED를 끄는 코드
- GPIO 17번 핀에 LED 연결
- RPi.GPIO 없이 Blinka의 digitalio 모듈만으로 LED 제어
- 10초 간격으로 측정 후 LED 상태 갱신
import time
import board
import digitalio
import adafruit_dht
# LED 설정 (GPIO 17)
led = digitalio.DigitalInOut(board.D17)
led.direction = digitalio.Direction.OUTPUT
# DHT22 센서 설정 (GPIO 18)
dht_device = adafruit_dht.DHT22(board.D18)
# 임계 온도
THRESHOLD = 28.0
print('온도 모니터링 시작 (Ctrl+C 종료)')
try:
while True:
try:
temperature = dht_device.temperature
humidity = dht_device.humidity
if temperature is not None:
print(f'온도: {temperature:.1f}°C / 습도: {humidity:.1f}%')
if temperature >= THRESHOLD:
led.value = True
print('LED ON (고온 경고)')
else:
led.value = False
print('LED OFF')
except RuntimeError as error:
print(error.args[0])
time.sleep(10)
except KeyboardInterrupt:
led.deinit()
dht_device.exit()
print('\n프로그램 종료')
- 응용 예시 2 : 온도에 따른 LED 밝기 PWM 제어 (Blinka pwmio 사용)
- 온도가 높아질수록 LED를 더 밝게 표시
- 측정 범위: 20°C ~ 35°C → 듀티 사이클 0% ~ 100%로 매핑
- GPIO 12번 핀에 LED 연결 (하드웨어 PWM 가능 핀)
- 주의: GPIO 18은 DHT22 데이터 핀으로 사용 중이므로 PWM 핀으로 사용 불가
import time
import board
import pwmio
import adafruit_dht
# PWM LED 설정 (GPIO 12, 1000Hz)
led = pwmio.PWMOut(board.D12, frequency=1000, duty_cycle=0)
# DHT22 센서 설정 (GPIO 18)
dht_device = adafruit_dht.DHT22(board.D18)
# 온도 → 듀티 사이클(0~65535) 매핑 함수
def temp_to_duty(temp, t_min=20.0, t_max=35.0):
if temp <= t_min:
return 0
if temp >= t_max:
return 65535
percent = (temp - t_min) / (t_max - t_min)
return int(percent * 65535)
print('온도 → LED 밝기 매핑 시작 (Ctrl+C 종료)')
try:
while True:
try:
temperature = dht_device.temperature
if temperature is not None:
duty = temp_to_duty(temperature)
led.duty_cycle = duty
percent = duty / 65535 * 100
print(f'온도: {temperature:.1f}°C / 듀티: {duty} ({percent:.1f}%)')
except RuntimeError as error:
print(error.args[0])
time.sleep(10)
except KeyboardInterrupt:
led.deinit()
dht_device.exit()
print('\n프로그램 종료')
댓글목록0