이 튜토리얼에서는 아두이노 기반 무선 기상 관측소를 만드는 방법을 배웁니다. 아래 비디오를 시청하거나 작성된 튜토리얼을 읽어보세요.
개요
실외 온도와 습도는 DHT22 센서로 측정하고, 이 데이터를 NRF24L01 트랜시버 모듈을 통해 실내 유닛으로 무선 전송합니다. 실내 유닛에는 또 다른 DHT22 센서가 있어 실내 온도와 습도를 측정하며, DS3231 실시간 시계 모듈이 아두이노 전원이 꺼져도 시간을 유지합니다. 모든 데이터는 0.96인치 OLED 디스플레이에 출력됩니다.
아두이노 무선 기상 관측소 회로도
회로도와 프로젝트 작동 원리를 살펴보겠습니다. 각 모듈의 자세한 작동 원리는 별도 튜토리얼에서 다루었으므로 참고하세요: NRF24L01 튜토리얼, DHT22 튜토리얼, DS3231 튜토리얼.
이 프로젝트에 필요한 구성품은 아래 링크에서 구할 수 있습니다:
NRF24L01 트랜시버 모듈
DHT22 센서
DS3231 실시간 시계
아두이노 나노
실시간 시계 모듈과 OLED 디스플레이는 모두 I2C 프로토콜로 아두이노와 통신하므로 아두이노 나노의 I2C 핀(아날로그 핀 4, 5)에 연결됩니다. NRF24L01 트랜시버 모듈 바로 옆에 커패시터를 두어 전원 공급을 더 안정적으로 만들었습니다. 또한 DHT22 데이터 핀에 풀업 저항을 연결해 센서가 제대로 작동하도록 했습니다.
전원 공급의 경우 실내 유닛에는 12V DC 어댑터를 사용했고, 실외 유닛에는 약 7.5V를 내는 리튬이온 배터리 두 개를 사용했습니다. 이 구성으로 실외 유닛은 데이터를 주기적으로 전송하고 그 사이에 아두이노를 슬립 모드(소비 전력 약 7mA)로 두어 약 10일간 작동할 수 있습니다.
커스텀 PCB 설계
회로도에 따라 전자 부품을 정리하기 위해 EasyEDA 무료 온라인 회로 설계 소프트웨어로 커스텀 PCB를 설계했습니다. 동일한 PCB를 실내/실외 유닛 모두에 사용할 수 있으며, 아두이노 보드만 다르게 프로그래밍하면 됩니다.
설계를 마치면 PCB 제조용 거버 파일을 내보낼 수 있습니다. 이 프로젝트의 EasyEDA 프로젝트 파일은 여기서 확인하세요.
거버 파일을 JLCPCB(이 비디오의 후원사)에 주문합니다.
거버 파일을 드래그 앤 드롭해 업로드하면 거버 뷰어에서 PCB를 검토할 수 있습니다. 모든 게 정상이면 원하는 PCB 속성을 선택하고 합리적인 가격에 주문할 수 있습니다. JLCPCB 첫 주문 시 최대 10개 PCB를 단 2달러에 받을 수 있습니다.
며칠 후 PCB가 도착했습니다. 품질이 훌륭하고 설계와 정확히 일치합니다.
PCB에 핀 헤더를 납땜해 부품을 쉽게 연결/분리할 수 있게 했습니다.
커패시터와 풀업 저항도 납땜했습니다. 이제 부품을 PCB의 핀 헤더에 장착하기만 하면 됩니다.
케이스 제작
프로젝트 케이스를 만들기 위해 8mm 두께의 MDF 보드를 사용했고, 원형 톱으로 모든 조각을 크기에 맞게 잘랐습니다.
정확한 온습도 측정을 위해 케이스 양쪽에 공기가 들어올 수 있는 슬롯을 뚫었습니다. 드릴과 줄을 사용해 실내/실외 유닛 양쪽 옆 패널에 여러 개의 슬롯을 만들었습니다.
전면 패널에는 OLED 디스플레이용 슬롯을 만들었고, 장식용으로 작은 알루미늄 조각을 잘라 전면 패널에 부착했습니다.
목재 접착제와 클램프, 나사로 케이스를 조립했습니다.
스프레이 페인트로 케이스를 도색했습니다. 실외 유닛은 흰색, 실내 유닛은 검은색을 사용했습니다. 페인트가 마른 후 PCB를 케이스에 넣었습니다.
실내 유닛 후면에 전원 잭과 스위치를, 실외 유닛에는 점퍼 와이어를 전원 스위치로 사용했습니다.
이제 아두이노 무선 기상 관측소가 작동합니다. 남은 건 프로그램이 어떻게 작동하는지 살펴보는 것입니다.
아두이노 무선 기상 관측소 코드
실외 유닛(송신기) 코드
/* 아두이노 무선 통신 튜토리얼 실외 유닛 - 송신기 by Dejan Nedelkovski, www.HowToMechatronics.com 라이브러리: NRF24L01 - TMRh20/RF24, https://github.com/tmrh20/RF24/ DHT22 - DHTlib, https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib LowPower - https://github.com/rocketscream/Low-Power */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>
#include <LowPower.h>
#define dataPin 8 // DHT22 데이터 핀
dht DHT; // DHT 객체 생성
RF24 radio(10, 9); // CE, CSN
const byte address[6] = "00001";
char thChar[32] = "";
String thString = "";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
int readData = DHT.read22(dataPin); // 센서에서 데이터 읽기
int t = DHT.temperature; // 온도 값 가져오기
int h = DHT.humidity; // 습도 값 가져오기
thString = String(t) + String(h);
thString.toCharArray(thChar, 12); // 문자 배열로 변환
// 실내 유닛으로 데이터 무선 전송
for (int i = 0; i <= 3; i++) { // 데이터 3회 전송
radio.write(&thChar, sizeof(thChar));
delay(50);
}
// 2분간 슬립, 15*8 = 120초
for (int sleepCounter = 15; sleepCounter > 0; sleepCounter--) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
설명: 실외 유닛은 무선 통신의 송신기입니다. RF24 라이브러리, DHT 라이브러리, 아두이노를 슬립 모드로 넣는 LowPower 라이브러리를 포함합니다. 인스턴스, 핀, 변수를 정의한 후 setup에서 무선 통신 주소를 초기화합니다. loop에서는 DHT22 센서에서 온도와 습도를 읽습니다. 이 값들은 처음에 정수이고 분리되어 있으므로 하나의 String 변수로 합치고 문자 배열에 넣어 radio.write() 함수로 실내 유닛에 전송합니다. for 루프로 데이터를 3번 전송해 수신기가 바쁠 때에도 데이터를 받을 수 있게 합니다. 마지막에 아두이노를 일정 시간 슬립 모드로 두어 전력 소모를 최소화합니다.
설명: 실내 유닛(수신기)에서는 DS3231 실시간 시계 모듈용 라이브러리와 OLED 디스플레이용 U8G2 라이브러리 두 가지를 추가로 포함합니다. 앞서와 같은 방식으로 인스턴스, 핀, 프로그램에 필요한 변수들을 정의합니다. 또한 온도와 습도 아이콘을 비트맵으로 정의합니다.