아두이노, ESP8266, ThingSpeak로 신뢰할 수 있는 개인 기상 관측소 만들기
부품 및 소모품
부품 수량
Adafruit BMP180 1
DHT11 온습도 센서 (4핀) 1
LDR (조도 의존 저항) 1
Espressif ESP8266 ESP-01 1
아두이노 Nano R3 1
저항 4.75kΩ 1
저항 51kΩ 1
LM2596 DC-DC 벅 컨버터 스텝다운 전원 모듈 1
DC 잭 1
스위치 1
12V-2A 벽면 어댑터 1
PCB 1
수 헤더 40핀 1열 (0.1") 1
암 헤더 8핀 1열 (0.1") 5
플라스틱 박스 1
필요한 도구 및 장비
와이어 스트리퍼
글루 건 (일반)
납땜 인두 (일반)
드라이버
줄 (수작업용)
앱 및 온라인 서비스
프로젝트 소개
소개: 개인 기상 관측소 만들기
방에 앉아 있는데 덥거나 춥게 느껴져서 방의 온도나 습도가 궁금했던 적이 있으신가요? 저도 그런 경험이 있어 개인 기상 관측소 프로젝트를 시작하게 되었습니다.
이 장치는 방의 온도, 습도, 기압, 조도를 모니터링하여 thingspeak.com의 비공개 채널로 업로드합니다.
1단계: 빠른 영상
5분 안에 모든 것을 요약한 짧은 영상입니다. 유튜브에서 보기
2단계: 개인 기상 관측소에 필요한 전자 부품
설명: DHT11로 습도, BMP180으로 온도와 기압, LDR로 조도 강도를 대략적으로 측정합니다. 아두이노 Nano가 이 센서들로부터 데이터를 수집하여 ESP8266으로 전송하고, ESP8266이 thingspeak.com의 비공개 채널로 업로드합니다. 아두이노 Nano는 12V-2A 벽면 어댑터로 전원을 공급하고, 센서들과 ESP8266은 LM2596 기반 벅 컨버터에서 강압된 전압을 공급받습니다.
부품 목록:
BMP180 기압 및 온도 센서
DHT11 습도 센서
조도 의존 저항 (LDR)
ESP8266 와이파이 모듈 (펌웨어 준비됨)
아두이노 Nano
저항 2개 - 51kΩ, 4.7kΩ
LM2596 벅 컨버터
DC 잭
스위치
12V-2A 벽면 어댑터
3단계: 개인 기상 관측소에 필요한 도구 및 추가 물품
설명: 와이어 스트리퍼로 전선 피복 벗기기, 줄로 인클로저 절단/구멍 매끄럽게 다듬기, 글루 건으로 인클로저 내부에 부품 고정, 드라이버로 인클로저 뚜껑 닫기, 납땜 인두와 납으로 범용 기판(GCB)에 회로 조립. 4x4x2 인치 플라스틱 박스가 인클로저 역할을 합니다. GCB에서 제대로 조립하기 위해 수/암 버그 스트립과 암 커넥터도 필요합니다.
도구 목록:
와이어 스트리퍼
줄
글루 건
드라이버
납땜 인두와 납
추가 물품 목록:
4x4x2 인치 플라스틱 박스 (이 크기 사용, 비슷한 크기면 괜찮음)
범용 기판
수/암 버그 스트립
암 커넥터
4단계: 소프트웨어 요구사항
센서 데이터 값을 보려면 thingspeak.com의 비공개 채널이 필요합니다. 아두이노 Nano용 코드를 작성하기 위해 아두이노 IDE도 필요합니다 (PC/노트북과 인터넷 접속 가능한 와이파이 공유기가 있다고 가정).
Thingspeak.com 비공개 채널
아두이노 IDE (최신 버전 권장)
arduino.cc 에서 최신 아두이노 IDE를 다운로드할 수 있습니다. 이제 thingspeak.com에서 비공개 채널을 만들어 보겠습니다.
5단계: Thingspeak.com에서 비공개 채널 만들기
웹 브라우저에서 thingspeak.com 접속, 우측 상단 'Sign Up' 탭 클릭
세부 정보 입력 후 'Create account' 클릭
'New Channel' 탭 클릭
채널 세부 정보 입력하고 4개 필드 활성화 (센서 값 4개 전송), 아래로 스크롤하여 'Save Channel' 클릭
'API Keys' 탭 클릭하고 'Write API Key' 메모
이제 여러분의 비공개 ThingSpeak 채널이 준비되었습니다.
6단계: 개인 기상 관측소 회로도
개인 기상 관측소 회로도 이미지와 프리칭 파일을 첨부합니다. 연결은 매우 간단합니다.
BMP180 → 아두이노 Nano I2C 포트
LDR → 51kΩ 저항과 전압 분할기 구성, 연결점 → 아두이노 Nano A1 핀
DHT11 데이터 핀 → 4.7kΩ 저항으로 풀업, 아두이노 Nano A0 핀 연결
ESP8266 TX/RX → 아두이노 Nano D10/D11, CH_PD → 3.3V 레일
LM2596 모듈 출력을 포텐셔미터로 3.3V 조정. 이 출력을 BMP180, DHT11, LDR, ESP8266 VCC/GND에 연결
LM2596 모듈 입력 ← 12V-2A 벽면 어댑터, 아두이노 Nano Vin/GND에도 동일 연결
이 회로를 범용 기판에 조립해 보겠습니다.
7단계: 범용 기판(GCB)에 회로 조립
3단계의 하드웨어 도구와 추가 물품을 사용합니다.
아두이노 Nano와 ESP8266 배치를 위해 암 버그 스트립 사용
납땜 인두와 납으로 전기적으로 기판에 연결
모든 센서와 LM2596 모듈의 도달 범위를 연장하기 위해 암 커넥터 사용 (인클로저 뚜껑과 벽에 부착됨)
수 버그 스트립으로 위 확장 연결점 만들기
와이어(와이어 스트리퍼로 피복 벗김)나 녹인 납 레일로 회로도 구현
멀티미터로 쇼트 체크 후 회로에 전원 공급
8단계: 코드
개인 기상 관측소 코드는 꽤 간단합니다. 이식성을 위해 주석을 잘 달았습니다. 코드를 업로드하기 전에 다음 사항을 확인하세요.
모든 라이브러리 설치 완료
코드 14행의 하이픈을 본인의 액세스 포인트 SSID(와이파이 공유기)로 변경
코드 15행의 하이픈을 본인의 와이파이 비밀번호로 변경
코드 17행의 하이픈을 본인의 ThingSpeak 비공개 채널 Write API Key로 변경
아두이노 Nano 프로그래밍 시 12V DC 전원이 OFF 상태인지 확인
코드와 사용한 라이브러리 다운로드: GitHub - Personal Weather Station
9단계: 인클로저 준비
4x4x2 인치 박스에 다양한 모양과 크기의 구멍을 뚫어야 합니다. 인클로저 선호하는 벽면에 DC 잭과 스위치 구멍, 뚜껑에 센서 구멍을 만듭니다.
뜨거운 칼로 플라스틱을 자르고, 줄로 구멍을 매끄럽게 다듬습니다.
10단계: 뚜껑 닫기
조립된 GCB를 인클로저 안에 넣습니다. 스위치와 DC 잭을 벽면 구멍에, 센서를 뚜껑 구멍에 배치합니다. 위치를 확정한 후 글루 건으로 고정하고, 드라이버로 뚜껑을 닫습니다.
이제 여러분의 개인 기상 관측소가 완성되었습니다! 전원을 켜고 스마트폰/PC/노트북/태블릿에서 ThingSpeak 비공개 채널을 통해 전 세계 어디서든 방의 온도, 습도, 기압, 조도를 확인하세요.
이 프로젝트는 여기까지입니다. 궁금한 점은 댓글로 남겨주세요. 읽어주셔서 감사합니다.
코드
코드 (아두이노)
#include <SoftwareSerial.h>
#include <Wire.h>
#include <dht.h>
#include <Adafruit_BMP085.h>
#define DEBUG 0 // 디버깅을 위해 시리얼 모니터 사용 시 1로 변경
#define dht_pin A0 // DHT 센서용 A0 핀 정의
#define lightSensor A1 // LDR 전압 분할기용 입력 핀 A1 정의
dht DHT;
Adafruit_BMP085 bmp;
SoftwareSerial esp8266Module(10, 11); // RX, TX
String network = "----"; // 액세스 포인트 SSID
String password = "-------------"; // 와이파이 비밀번호
#define IP "184.106.153.149" // thingspeak.com IP 주소
String GET = "GET /update?key=----------------"; // 채널 키로 교체
void setup() {
if(DEBUG){
Serial.begin(9600);
}
esp8266Module.begin(9600);
if (!bmp.begin()) {
if(DEBUG){
Serial.println("Could not find a valid BMP085 sensor, check wiring!");
}
while (1) {}
}
delay(2000);
}
void loop() {
setupEsp8266();
DHT.read11(dht_pin);
double humi = DHT.humidity;
double bmp_temp = bmp.readTemperature();
double bmp_pressure = bmp.readPressure();
int lightIntensity = analogRead(lightSensor);
updateTemp(String(bmp_temp), String(lightIntensity), String(bmp_pressure), String(humi));
delay(30000);
}
// ESP8266 설정, 스테이션 모드로 전환 및 와이파이 AP 연결
void setupEsp8266() {
if(DEBUG){ Serial.println("Reseting esp8266"); }
esp8266Module.flush();
esp8266Module.println(F("AT+RST"));
delay(7000);
if (esp8266Module.find("OK")) {
if(DEBUG){ Serial.println("Found OK"); Serial.println("Changing espmode"); }
esp8266Module.flush();
changingMode();
delay(5000);
esp8266Module.flush();
connectToWiFi();
} else {
if(DEBUG){ Serial.println("OK not found"); }
}
}
// ESP8266을 스테이션 모드로 설정
bool changingMode() {
esp8266Module.println(F("AT+CWMODE=1"));
if (esp8266Module.find("OK")) {
if(DEBUG){ Serial.println("Mode changed"); }
return true;
} else if(esp8266Module.find("NO CHANGE")){
if(DEBUG){ Serial.println("Already in mode 1"); }
return true;
} else {
if(DEBUG){ Serial.println("Error while changing mode"); }
return false;
}
}
// ESP8266을 와이파이 액세스 포인트에 연결
bool connectToWiFi() {
if(DEBUG){ Serial.println("inside connectToWiFi"); }
String cmd = F("AT+CWJAP=\"");
cmd += network;
cmd += F("\",\"");
cmd += password;
cmd += F("\"");
esp8266Module.println(cmd);
delay(15000);
if (esp8266Module.find("OK")) {
if(DEBUG){ Serial.println("Connected to Access Point"); }
return true;
} else {
if(DEBUG){ Serial.println("Could not connect to Access Point"); }
return false;
}
}
// 센서 데이터를 thingspeak.com으로 전송
void updateTemp(String voltage1, String voltage2, String voltage3, String voltage4) {
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
esp8266Module.println(cmd);
delay(5000);
if(esp8266Module.find("Error")){
if(DEBUG){ Serial.println("ERROR while SENDING"); }
return;
}
cmd = GET + "&field1=" + voltage1 + "&field2=" + voltage2 + "&field3=" + voltage3 + "&field4=" + voltage4 + "\r\n";
esp8266Module.print("AT+CIPSEND=");
esp8266Module.println(cmd.length());
delay(15000);
if(esp8266Module.find(">")) {
esp8266Module.print(cmd);
if(DEBUG){ Serial.println("Data sent"); }
} else {
esp8266Module.println("AT+CIPCLOSE");
if(DEBUG){ Serial.println("Connection closed"); }
}
}
개인 기상 관측소 라이브러리 및 코드
Readme 확인: https://github.com/jayraj4021/Personal-Weather-Station-14
회로도
schematic.fzz