정확한 강수 예보: 아두이노, 파이썬, 케라스로 구축하는 AI 강우 예측 시스템
부품 및 소모품
| 부품 |
수량 |
| 분리형 뚜껑이 있는 소형 플라스틱 박스 (나사 고정형, 11×7×5cm) |
1 |
| AAA 배터리 홀더 3구 |
1 |
| AAA 충전식 배터리 (NiMH) |
3 |
| 6V 소형 태양광 패널 |
1 |
| 스파크펀 아두이노 프로 미니 328 - 5V/16MHz |
1 |
| 1N4004 다이오드 (역전류 방지용) |
1 |
| 범용 NPN 트랜지스터 + 1k 저항 (주변기기 전원 제어용) |
1 |
| 빗물 감지 센서 |
1 |
| HC-12 시리얼 통신 모듈 (송신용) |
1 |
| HC-12 USB 시리얼 모듈 (수신/베이스 스테이션용) |
1 |
| BME280 대기 센서 모듈 (온도, 습도, 기압) |
1 |
| BH1750 조도 센서 모듈 |
1 |
| PCB, 와이어, 납땜, KF301-2P 커넥터, 수/암 PCB 커넥터, 글루 |
1식 |
| 3.3V 레귤레이터 |
1 |
필수 도구
- USB-시리얼 FTDI 어댑터 (FT232RL) - 프로 미니 프로그래밍용
- 드릴, 세밀한 톱, 드라이버, 납땜 인두, 와이어 커터
- 아두이노 IDE
프로젝트 개요
목표: 6시간 후 비가 올지 안 올지(이진 분류)를 예측하는 시스템을 처음부터 끝까지 구축합니다.
- 기상 관측소 직접 제작: 태양광 패널과 초저전력 모드(수십 µA)로 완전 오프그리드 동작
- 펌웨어 프로그래밍: 10분마다 센서 데이터 수집 및 전송
- 베이스 스테이션에서 데이터 수집/저장: MongoDB 시계열 데이터베이스
- 데이터 전처리 및 모델 학습: Pandas로 정제/피처 엔지니어링, Keras 신경망으로 학습
- 예측 및 알림: 6시간 후 강우 여부 예측 후 이메일 발송
약 600일 치 데이터로 80% 내외 정확도 달성. 외부 날씨 API나 ML API 없이 자체 데이터로 실용적인 예보 시스템을 만듭니다.
1단계: 관측소 제작용 부품과 도구
(위 부품표 참조) 기술 요구사항: 납땜, 기초 아두이노 프로그래밍, 리눅스 서비스 설정, 기본 프로그래밍 능력
2단계: 기상 관측소 조립
- 박스에 구멍 4개 뚫기 (태양광 패선선, 센서 3개용)
- PCB에 아두이노 프로 미니(암 커넥터), HC-12, 3.3V 레귤레이터, 다이오드, 트랜지스터, 저항, KF301-2P 2개(태양광/배터리), 센서용 암 커넥터 3개 납땜. 아두이노 내장 LED는 반드시 제거 (전력 소모 큼)
- 충전된 AAA NiMH 배터리 3개 장착
- BME280, 조도 센서, 빗물 센서를 박스 바깥에 연결 (빗물 센서는 별도 지주에 설치)
- 비/눈 피할 수 있는 곳에 설치, 태양광 패널이 햇빛 잘 받는 방향 향하게
3단계: 아두이노 코드
역할: 10분마다 센서 읽기 → HC-12로 인코딩 전송 → 주변기기 전원 차단 → 8초 딥슬립 × 75회(=10분) → 반복
전송 데이터 포맷: H1:78|T1:12|PS1:1022|L1:500|R1:0|V1:4010| (습도, 온도, 기압, 조도, 강우, 전압)
배터리 전압이 4.2V 이상이면 일반 delay()로 과충전 방지.
필수 라이브러리: LowPower, SoftwareSerial, Wire, Adafruit_Sensor, Adafruit_BME280, BH1750
// 주요 구조체 및 함수 요약
struct sensorData { byte humidity; int temperature; byte rain; int pressure; long voltage; int light; };
void loop() { updateSensors(); transmitData(); customSleep(75); }
void customSleep(long cycles) {
if (sensors.voltage > 4200) { delay(cycles * 8000); return; }
digitalWrite(peripherialsPowerPin, LOW);
for (int i=0; i
전체 코드: GitHub
4단계: 베이스 스테이션 준비 (리눅스 + HC-12 USB)
- Anaconda 설치 (Python 3.6.2 환경 'weather' 생성)
- MongoDB 설치 (인덱스:
db.weather_station.createIndex({"date": 1}))
- 프로젝트 클론:
git clone https://github.com/danionescu0/home-automation.git
- 의존성 설치:
pip install -r requirements.txt (Keras, Pandas, PyMongo, Scikit-learn 등)
- config.py에서 MongoDB 호스트/포트, HC-12 시리얼 포트(/dev/ttyUSB0 등) 설정
5단계: 실전 운용
- 데이터 수집:
python serial_listener.py (10분마다 DB 저장)
- 모델 학습:
python train.py --days_behind 600 --test-file-percent 10 --datapoints-behind 8 --hour-granularity 6
- 그래프 확인:
python graphs.py --days-behind 10
- 예측 및 이메일 알림:
python predict.py --datapoints-behind 8 --hour-granularity 6 --from-addr ... --to-addr ...
- 크론탭에 등록해 매시간 자동 예측 가능
6단계: 작동 원리 (머신러닝 파이프라인)
데이터 준비 (가장 중요)
- MongoDB에서 원시 데이터 로드
- 결측치 제거, 6시간 간격으로 그룹화
- 각 센서별 min/max/mean/percentile(10,30,70,90), 상승/하락/정체 횟수 등 피처 생성
rain_avg > 0.1이면 has_rain=1 else 0 (타겟 변수)
- 과거 8개 데이터포인트(48시간) 피처를 현재 행에 추가 (시계열 특성 반영)
- NaN 행 제거, 현재 시점 피처 제거(타겟만 남김), StandardScaler로 0~1 정규화
- train/test 분할 (6:4)
신경망 모델 (Keras)
model = Sequential([
Input(shape=(n_features,)),
Dense(n_features//2, activation='relu'), Dropout(0.05),
Dense(n_features//2, activation='relu'), Dropout(0.05),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='rmsprop', loss='mean_absolute_error', metrics=['accuracy'])
model.fit(X, y, batch_size=1, epochs=50)
하이퍼파라미터(레이어 수, 뉴런 수, 드롭아웃, 옵티마이저, 손실함수, 배치, 에폭)는 데이터에 맞춰 튜닝 필요. --grid-search 옵션으로 자동 탐색 가능.
7단계: 보너스 - 공식 기상 데이터(Dark Sky API) 활용
풍속, 풍향, 자외선, 가시거리 등 더 많은 변수가 포함된 공식 데이터로 학습 시 정확도 80% → 90%로 향상. 데이터 품질이 모델 성능에 결정적임을 확인.
코드 저장소
GitHub: danionescu0/home-automation (weather-predict 폴더)
회로도
Fritzing 파일(sketch.fzz) 및 회로도 이미지 참조