산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이

부품 및 소모품

부품수량
아두이노 나노 R31
Seeed Grove 기압계 센서 (BMP280)1
DHT11 온습도 센서 (4핀)1
0.96" OLED 128x64 디스플레이 모듈 (ElectroPeak)1
GUVA-S12SD UV 센서1
DS3231 RTC 모듈1

필수 도구 및 장비

앱 및 온라인 서비스

프로젝트 소개

인터넷 없이 로컬에서 기상 데이터를 측정하고 확인할 수 있는 날씨 스테이션을 만들고 싶었습니다. 주변 기압, 온도, 습도, 자외선 지수(창가 설치 시)를 측정하고, 시간/날짜/요일도 표시하는 시계 화면도 포함했습니다.

아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이

1단계: 케이스 제작 (3D 프린팅)

아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이
아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이

Autodesk Fusion 360으로 케이스 설계, 녹색 PLA로 출력. 서포트 필요, 20% 인필, 70mm/s 속도(엔더 3). STL 파일은 프로젝트에 첨부.

2단계: BMP280 (기압/온도, SPI 모드)

라이브러리: Adafruit_BMP280.h. bmp.readPressure()로 압력(Pa) 읽고 100으로 나누어 hPa 환산. bmp.readTemperature()로 온도. bmp.readAltitude(해수면기압)로 고도 계산(해수면 기압은 지역 평균값으로 수정).

3단계: DS3231 RTC (I2C)

라이브러리: DS3231.h. 최초 라이브러리 예제 DS3231_set.ino로 시간/날짜 설정. 메인 코드에서 clock.getHour(), getMinute(), getDate(), getMonth(), getYear(), getDoW()(요일) 호출. 요일은 switch-case로 한글/영문 변환.

4단계: DHT11 (습도)

라이브러리: DHT.h. dht.readHumidity()로 습도(%) 읽기.

5단계: GUVA-S12SD UV 센서

GaN 기반 쇼트키 포토다이오드. 240~370nm 파장 감지(UVB 및 대부분 UVA 커버). 보정된 아날로그 전압 출력 → 아두이노 ADC로 읽기.

float sensorValue = analogRead(A0);
float sensorVoltage = sensorValue / 1024.0 * 5.0;
int UV_index = sensorVoltage / 0.1;  // 0.1V당 UV Index 1

6단계: OLED 디스플레이 (I2C, 128x64)

라이브러리: Adafruit_GFX.h, Adafruit_SSD1306.h. 비트맵 이미지(프레임 0,1,2)로 아이콘 표시. 4페이지(시간, 기압/고도, 온도/습도, UV 지수)를 5초 간격으로 순환 표시.

영상 클립

동영상으로 동작 확인 가능.

코드 (전체 스케치)

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <DS3231.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

DS3231 clock;
bool century = false, h12Flag, pmFlag;
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);

#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// 비트맵 데이터 (frame0, frame1, frame2) - 생략, 원본 참조

void setup() {
  Serial.begin(57600);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 failed"));
  }
  Wire.begin();
  dht.begin();
  if (!bmp.begin()) {
    Serial.println(F("Problem.bmp"));
    while (1) delay(10);
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0, 9);
  display.setFont(&FreeSans9pt7b);
  display.println("**** LOCAL ****");
  display.setCursor(0, 38);
  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.println("wather");
  display.setCursor(27, 58);
  display.println("Station");
  display.display();
  delay(2000);

  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                  Adafruit_BMP280::SAMPLING_X2,
                  Adafruit_BMP280::SAMPLING_X16,
                  Adafruit_BMP280::FILTER_X16,
                  Adafruit_BMP280::STANDBY_MS_500);
}

void loop() {
  // 1. 시간 화면
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(13, 15);
  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.print(clock.getHour(h12Flag, pmFlag));
  display.setCursor(38, 15); display.println(":");
  display.setCursor(50, 15); display.println(clock.getMinute());
  display.setCursor(70, 15); display.println(pmFlag ? " PM" : " AM");
  display.setFont(&FreeSans9pt7b);
  display.setCursor(20, 60); display.println(clock.getDate());
  display.setCursor(40, 60); display.println("/");
  display.setCursor(46, 60); display.println(clock.getMonth(century));
  display.setCursor(65, 60); display.println("/");
  display.setCursor(70, 60); display.println("20");
  display.setCursor(90, 60); display.println(clock.getYear());
  display.setCursor(30, 30);
  switch (clock.getDoW()) {
    case 1: display.println("Saturday"); break;
    case 2: display.println("Sunday"); break;
    case 3: display.println("Monday"); break;
    case 4: display.println("Tuesday"); break;
    case 5: display.println("Wednesday"); break;
    case 6: display.println("Thursday"); break;
    case 7: display.println("Friday"); break;
  }
  display.display(); delay(5000);

  // 2. 기압/고도 화면
  display.clearDisplay();
  display.drawBitmap(0, 0, frame0, 40, 40, 1);
  display.setFont(&FreeSans9pt7b);
  display.setCursor(41, 28); display.println(bmp.readPressure() / 100);
  display.setCursor(110, 28); display.setFont(); display.println("hPa");
  display.setCursor(0, 55); display.setFont(&FreeSans9pt7b); display.println("Altitude:");
  display.setCursor(65, 62); display.println(bmp.readAltitude(1005.47));
  display.setCursor(113, 62); display.println("m");
  display.display(); delay(5000);

  // 3. 온도/습도 화면
  display.clearDisplay();
  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.drawBitmap(0, 5, frame1, 40, 51, 1);
  display.setCursor(35, 30); display.print(bmp.readTemperature());
  display.setFont(&FreeSans9pt7b);
  display.setCursor(102, 28); display.println(" *");
  display.setCursor(110, 31); display.println(" C");
  display.setFont(); display.setCursor(66, 45); display.println("RH :");
  byte RH = dht.readHumidity();
  display.setCursor(95, 45); display.println(RH);
  display.setCursor(110, 45); display.println("%");
  display.drawBitmap(0, 56, frame2, 135, 15, 1);
  display.display(); delay(5000);

  // 4. UV 지수 화면
  display.clearDisplay();
  float sensorValue = analogRead(A0);
  float sensorVoltage = sensorValue / 1024.0 * 5.0;
  int UV_index = sensorVoltage / 0.1;
  display.setFont(&FreeSans9pt7b);
  display.setCursor(0, 15); display.print(" UV INDEX ");
  display.setCursor(58, 45); display.println(UV_index);
  display.display(); delay(5000);
}

커스텀 파트 및 인클로저

STL 파일 프로젝트에 포함.

회로도

아두이노 나노 날씨 스테이션: 센서 키트 & OLED 디스플레이

제조공정

  1. 라즈베리 파이 태양광 기상 관측소 DIY 제작
  2. 라즈베리 파이 2와 ADS-WS1로 야외 기상 관측소 구축하기
  3. 라즈베리 파이 기상 관측소 만들기: 매일 이메일로 날씨 데이터 전송
  4. 고급 기상 관측소 v2.0: 실시간 온도, 기압, 습도, 고도 모니터링
  5. 아두이노 기반 6연발 칵테일 제조기 – 나만의 자동 바텐더 만들기
  6. 스마트 홈 연동을 위한 다중 위치 온도 센서 시스템
  7. 고성능 아두이노 기상 관측용 데이터 로거 제작 가이드
  8. 1만 원대 휴대용 아두이노 날씨 스테이션 – 나노, DHT22, BMP180, LCD로 직접 제작
  9. 아두이노 & ThingSpeak로 실시간 날씨 모니터링 IoT 구축
  10. ESP8266과 DHT22 온습도 센서로 와이파이 기상 관측소 만들기