미세먼지 양에 따라 LED색 변경
최저, 최고 기온 표시 -시간과 함께
어제 최저, 최고 기온 표시
온도, 습도, 기압은 측정시간과 함께 SD카드에 기록, 20분 단위로 기록
/*
온습도 센서로 온스도를 측정하여, 24시간을 기준으로 최저 최고온도를 출력하고
미세먼지를 측정하여 대기 질에 따라 RGB LED로 표현
DS3231시계 모듈로 시간 확인, DS3231모듈은 I2C통신을 이용한다. A4, A5핀을 이용한다.
RTCLIB by NeiroN -DS3231 시계 라이브러리
DHT sensor library by Adafruit - DHT22 온습도 라이브러리
LiquidCrystal I2C by Frank de Brabander - LCD I2C용 라이브러리
//(Adafruit BMP 280 Library by Adafruit - BMP280 기압계 라이브러리)
MS5611 by Rob Tillaart -GY63 기압계 라이브러
SD 메모리 카드는 내장 라이브러리 사용
*/
// 미세먼지 없을때 초기 V 값
// 공기청정기 위 등에서 먼지를 가라앉힌 후 voltage값 개별적으로 측정필요
//---------------------------------------------------------------------------------------------------------
#include <Wire.h> // I2C 모듈 통신용 라이브러리 호출
#include <RTClib.h> // DS3231 rtc 시계모듈 사용 라이브러리 호출 RTCLIB by NeiroN
DS3231 rtc; // RTC로 선언 (I2C 주소는 0x57, 0x68)
#include <DHT.h> // DHT 온습도 라이브러리 호출
#define DHTPIN 2 // 온습도센서 2번핀에 연결
#define DHTTYPE DHT22 // 온습도센서 모델지정 DHT22
DHT dht(DHTPIN, DHTTYPE); // DHT 설정(2,DHT22)
//#include <LiquidCrystal.h> // LCD사용위해 라이브러리 호출
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // lcd 설정
#include <LiquidCrystal_I2C.h> // I2C LCD사용위해 라이브러리 호출
LiquidCrystal_I2C lcd(0x27,20,4); //LCD 설정 (I2C주소는 LCD의 종류에 따라 다르기때문에 LCD가 0x3F, 0x27인지 확인하세요)
//LCD 주소는 뒷면 A0 A1 A2 연결로 주소 변경 가능. 연결 안되어 있으면 0x3F, 0x27 둘 중 하나
//***********************
#define no_dust 0.6 //최초 전원 인가 후 깨끗한 환경에서의 지속적으로 측정되는 전압값 넣어주세요. 이 값은 직접 측정해야 함
//***********************
int dustout = A2; // 먼지센서의 5번핀을 먼지 측정위해 아두이노 A2번에 연결(A로표시)
int v_led = A3; // 먼지센서의 3번핀을 아두이노 A3번에 연결. 센서 내부 적외선 led를 on/off 제어(D로표시)-디지털은 6번핀으로
int s_ledr = 9; // 공기 상태에 나쁨 RED
int s_ledg = 8; // 공기 상태에 보통 Green
int s_ledb = 7; // 공기 상태에 좋음 Blue
float vo_value = 0; // 센서로 읽은 값 변수 선언
float sensor_voltage = 0; // 센서로 읽은 값을 전압으로 측정한 값
float dust_density = 0; // 실제 미세먼지 밀도
float tempMax; // 최고온도 실수형 변수 선언
float tempMin; // 최고온도 실수형 변수 선언
// #include <MS5611.h> // 기압계 라이브러리 설정
// MS5611 MS5611(0x77); // 기압계 주소 설정, I2C 통신
#include <Adafruit_Sensor.h> // 아래센서 사용위해 필요 (공통)
#include <Adafruit_BME280.h> // I2C BME280 센서 이용할때
// #include <Adafruit_BMP280.h> // I2C BMP280 센서 이용할때
// #define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bmep; // I2C BME280 센서 이용할때
// Adafruit_BMP280 bmep; // I2C BMP280 센서 이용할때
#define Addre (0x76)
#include <SPI.h> // SD카드를 사용하기 위한 통신 라이브러리
#include <SD.h> // SD카드를 사용하기 위한 통신 라이브러리
const int sd_CS = 10; // CS핀을 10번에 할당
File myFile;
// MOSI-pin 11, MISO-pin 12, CLK-pin 13은 고정, CS-pin 10-환경따라 이것만 변경
// 센서쉴드 핀은 + - D11 D10 D13 D12 순
//------------------------------------------------------------------
void setup()
{
Serial.begin(9600); // 통신속도 9600bps로 시리얼 통신 시작
Wire.begin();
rtc.begin(); // 시계모듈 시작
// rtc.adjust(DateTime(2024, 5, 21, 9, 26, 00)); // RTC의 초기 시간 설정. 한번 설정 후에는 주석 처리 후 다시 업로드해야 시작시 시간 초기화 안됨
// rtc.adjust(DateTime(__DATE__, __TIME__)); // RTC의 초기 시간 설정. 현재 컴퓨터의 시간으로 설정
dht.begin(); // 온습도 센서 시작
delay (2000); // 온습도 측정을 위해 2초 지연. DHT22 센서는 첫 측정을 위해 2초의 시간이 필요
// 각 센서의 핀을 정의
pinMode(v_led,OUTPUT); // 먼지센서 적외선led 출력으로 설정
pinMode(s_ledr,OUTPUT); // LED Red 출력 설정
pinMode(s_ledg,OUTPUT); // LED green 출력 설정
pinMode(s_ledb,OUTPUT); // LED blue 출력 설정
// digitalWrite(v_led,LOW); // 먼지센서 적외선 LED ON
digitalWrite(s_ledr,LOW); // RGB LED OFF상태
digitalWrite(s_ledb,LOW); // RGB LED OFF상태
digitalWrite(s_ledg,LOW); // RGB LED OFF상태
float temp = dht.readTemperature(); //온도값을 temp에 저장
float humi = dht.readHumidity(); //습도값을 humi에 저장
tempMax = temp; // 최고온도 실수형 변수 선언
tempMin = temp; // 최저온도 실수형 변수 선언
// 기압센서 시작
//MS5611.begin(); // ms5611 기압센서 시작
bmep.begin(Addre); // BME280/BMP280 기압센서 시작
// SD카드 기록 시작
SD.begin(sd_CS); // SD카드 준비
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일에 아래 데이터 항목 제목 기록 후 닫기
myFile.println(F("연월일, 시간, 온도, 습도, 기압, 미세먼지, 열지수, 불쾌지수"));
myFile.close();
lcd.begin(20, 4); // LCD 시작
lcd.setCursor(0,0);
lcd.backlight();
lcd.clear();
}
//----------------------------------------------------------------
void loop()
{
// 온도-습도 값 측정
float temp = dht.readTemperature(); //온도값을 temp에 저장
float humi = dht.readHumidity(); //습도값을 humi에 저장
float hic = dht.computeHeatIndex(temp, humi, false); // 열지수-체감온도 계산
float DI = ((9/5)*temp)-((0.55*(1-(humi/100))*(((9/5)*temp)-26)))+32; // 불쾌지수 계산
// if(isnan(humi) || isnan(temp)) { // 온도 습도 값을 읽지 못했을때 재시도
// Serial.println("Fail. Try again");
// lcd.print("Fail. Try again...");
// delay(2000);
// return;
// }
// 하루중 최고 최저 온도 계산
DateTime now = rtc.now(); //현재시간을 세팅
int hh = now.hour();
int mm = now.minute();
int ss = now.second();
int hhmax;
int mmmax;
int ssmax;
int hhmin;
int mmmin;
int ssmin;
int resetTime = (hh*60 + mm); // 시간과 분을 분 단위로 환산하여 2분보자 작거나 같으면 날짜변경으로 처리하여 최저최고기온 초기화
if (resetTime > 2) {
if (temp > tempMax) {tempMax = temp; hhmax = hh; mmmax = mm; ssmax = ss;} //최고온도 계산 기록
if (temp < tempMin) {tempMin = temp; hhmin = hh; mmmin = mm; ssmin = ss;} //최저온도 계산 기록
}
if (resetTime <= 2){
tempMax = temp; hhmax = hh; mmmax = mm; ssmax = ss;
tempMin = temp; hhmin = hh; mmmin = mm; ssmin = ss; // 최고 최저온도 초기값 설정
}
// 기압 측정하기
//MS5611.read(); // 기압센서에서 값 읽어오기
//float pressure = MS5611.getPressure(); // 측정값에서 기압 읽기
//float atmtemp = MS5611.getTemperature(); // 측정값에서 온도 읽기
//bmep.read();
float pressure = bmep.readPressure() / 100.0 ; //BME BMP 센서에서 기압 불러오기
float atmtemp = bmep.readTemperature(); //BME BMP 센서에서 온도 불러오기
// float altmeter = bmep.readAltitude(SEALEVELPRESSURE_HPA); //BME BMP 센서에서 고도 불러오기
// float bmhumi = bmep.readHumidity(); //BME BMP 센서에서 습도 불러오기
// 미세먼지 측정
// 샘플링을 위해서 적외선 LED는 0.32ms 동안 펄스를 유지해야하며, 0.28ms이후에 데이터를 읽을 수 있음
digitalWrite(v_led,LOW); // 센서의 적외석LED를 켜고-320us 지속시켜야 한다. 구조상 PNP트렌지스터가 있어 LOW가 켠상태
delayMicroseconds(280); // 기기 특성상 280us동안 기다린 후 먼지농도 측정
vo_value=analogRead(dustout); // 센서에서 먼지에 의한 전압변화 데이터를 읽음
delayMicroseconds(40); // 320us 유지를 위해 40us 더 기다림, 320us - 280us = 40
digitalWrite(v_led,HIGH); // 적외선 LED를 OFF
delayMicroseconds(9680); // 측정 후 대기상태 유지. 10us(주기) -320us(펄스폭) 한 값
// IRED켜고 끄는데 총 10ms필요, 이때 0.32ms동안 켜고 9.68ms동안 끈다. 이것이 한 펼스인데 9.68ms을 마이크로세컨드로 변환 9680
sensor_voltage=get_voltage(vo_value); // get_voltage 함수 실행
dust_density=get_dust_density(sensor_voltage); // get_dust_density 함수 실행
int dust_density1 = dust_density; // 실수형 자료를 정수형 자료로 변환
// 센서를 이용하여 먼지 없는 상태의 전압을 측정할때 필요
/*
Serial.print("value = ");
Serial.println(vo_value); // 센서에서 읽은 전압
Serial.print("Voltage = ");
Serial.print(sensor_voltage); // 센서에서 읽은 전압을 증폭 변환한 전압.
Serial.println(" [V]");
Serial.print("Dust Density = ");
Serial.print(dust_density); // 먼지 값으로 초기값을 잡을때는 가급적 이 값이 0에 가까운값이 되도록 공기청정기 위에서 측정
Serial.println(" [ug/m^3]");
*/
// 미세먼지에 따른 LED색 변경-핀 부족으로 사용하지 않음
if(dust_density <= 50){
digitalWrite(s_ledr,LOW); // 파랑색 LED켜기-대기질 좋음 상태
digitalWrite(s_ledb,HIGH);
digitalWrite(s_ledg,LOW);
}
else if(dust_density <= 100){
digitalWrite(s_ledr,LOW); // 녹색 LED켜기-대기질 보통 상태
digitalWrite(s_ledb,LOW);
digitalWrite(s_ledg,HIGH) ;
}
else {
digitalWrite(s_ledr,HIGH); // 빨강색 LED켜기-대기질 나쁨 상태
digitalWrite(s_ledb,LOW);
digitalWrite(s_ledg,LOW);
}
// 총 순환 시간을 20초로 만들기 위해
// Serial.println(millis()); // 순환시간 체크용 밀리초로 진행시간 표시
delay(234);
//*************** 시리얼과 LCD 출력을 모아 출력****************
// 시간 LCD 출력
char buf1[20];
char buf2[20];
for (int i=0; i <5; i++ ) { //---------LCD에만 5초간 시간 표시
DateTime now = rtc.now(); //현재시간을 세팅
snprintf(buf1, sizeof(buf1), "%04d-%02d-%02d", now.year(), now.month(), now.day());
snprintf(buf2, sizeof(buf2), "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
lcd.setCursor(5, 1);
lcd.print(buf1);
lcd.setCursor(6, 2);
lcd.print(buf2);
delay(1000);
lcd.clear();
}
// 온도, 습도, 기압, 미세먼지 LCD 출력
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.setCursor(6, 0);
lcd.print(temp,1);
lcd.setCursor(14, 0);
lcd.print((char)223); //문자 도 기호 표시
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Humi: ");
lcd.setCursor(6, 1);
lcd.print(humi,0);
lcd.setCursor(14, 1);
lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("Atmo:");
lcd.setCursor(6, 2);
lcd.print(pressure, 1);
lcd.setCursor(14, 2);
lcd.print("hPa");
lcd.setCursor(0, 3);
lcd.print("PM25:");
lcd.setCursor(6, 3);
lcd.print(dust_density1);
lcd.setCursor(14, 3);
lcd.print("ug/m^3");
delay(7000);
lcd.clear();
// 최저, 최고온도, 열지수, 불쾌지수 LCD 표시
lcd.setCursor(0,0);
lcd.print("Tmax:");
lcd.setCursor(6, 0);
lcd.print(tempMax, 1);
lcd.setCursor(12, 0);
lcd.print((char)223); // 문자 도 기호 표시
lcd.print("C");
lcd.setCursor(15, 0);
char buf3[20];
snprintf(buf3, sizeof(buf3), "%02d:%02d", hhmax, mmmax);
lcd.print(buf3);
lcd.setCursor(0,1);
lcd.print("Tmin:");
lcd.setCursor(6, 1);
lcd.print(tempMin, 1);
lcd.setCursor(12, 1);
lcd.print((char)223); // 문자 도 기호 표시
lcd.print("C");
lcd.setCursor(15, 1);
char buf4[20];
snprintf(buf4, sizeof(buf4), "%02d:%02d", hhmin, mmmin);
lcd.print(buf4);
lcd.setCursor(0, 2);
lcd.print("H I:");
lcd.setCursor(6, 2);
lcd.print(hic,0);
lcd.setCursor(0, 3);
lcd.print("D I:");
lcd.setCursor(6, 3);
lcd.print(DI,0);
delay(7000); // 7초간 유지
lcd.clear(); // 화면지우기
// 시간 시리얼 출력
// DateTime now = rtc.now(); // 현재시간을 불러움-앞에서 선언함
Serial.print(buf1);
Serial.print(" ");
Serial.print(buf2);
Serial.print("\t");
// 온도, 습도, 기압, 미세먼지 등 시리얼 출력
Serial.print(F("온도: "));
Serial.print(temp,1); //온도값 출력
Serial.print(" °C \t");
Serial.print(F("습도: "));
Serial.print(humi,0); //습도값 출력
Serial.print((" % \t"));
Serial.print(F("대기압: "));
Serial.print(pressure,1); //대기압 출력
Serial.print((" hPa \t"));
Serial.print(F("미세먼지: "));
Serial.print(dust_density1); //미세먼지 출력
Serial.print((" ug/m^3 \t"));
Serial.print(F("열지수: "));
Serial.print(hic,0); //열지수 출력
Serial.print("\t");
Serial.print(F("불쾌지수: "));
Serial.print(DI,0);
Serial.print("\t");
Serial.print(F("시계온도: "));
Serial.print(rtc.getTemp(), 1);
Serial.print("\t");
Serial.print(F("기압센서온도: "));
Serial.println(atmtemp, 1);
// SD 카드에 데이타 저장
if (mm == 00 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
if (mm == 20 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
if (mm == 40 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
}
//--------------------------------------
// 정의된 함수, 미세먼지 측정용
float get_voltage(float value)
{
float V= value * 5.0 / 1024; // 아날로그값을 전압값으로 바꿈
return V;
}
float get_dust_density(float voltage)
{
float dust=(voltage - no_dust) / 0.005; // 데이터 시트에 있는 미세먼지 농도(ug/m^3) 공식 기준에 의해 전압을 0.005로 나눔
return dust;
}
미세먼지 양에 따라 LED색 변경
최저, 최고 기온 표시 -시간과 함께
어제 최저, 최고 기온 표시
온도, 습도, 기압은 측정시간과 함께 SD카드에 기록, 20분 단위로 기록
/*
온습도 센서로 온스도를 측정하여, 24시간을 기준으로 최저 최고온도를 출력하고
미세먼지를 측정하여 대기 질에 따라 RGB LED로 표현
DS3231시계 모듈로 시간 확인, DS3231모듈은 I2C통신을 이용한다. A4, A5핀을 이용한다.
RTCLIB by NeiroN -DS3231 시계 라이브러리
DHT sensor library by Adafruit - DHT22 온습도 라이브러리
LiquidCrystal I2C by Frank de Brabander - LCD I2C용 라이브러리
//(Adafruit BMP 280 Library by Adafruit - BMP280 기압계 라이브러리)
MS5611 by Rob Tillaart -GY63 기압계 라이브러
SD 메모리 카드는 내장 라이브러리 사용
*/
// 미세먼지 없을때 초기 V 값
// 공기청정기 위 등에서 먼지를 가라앉힌 후 voltage값 개별적으로 측정필요
//---------------------------------------------------------------------------------------------------------
#include <Wire.h> // I2C 모듈 통신용 라이브러리 호출
#include <RTClib.h> // DS3231 rtc 시계모듈 사용 라이브러리 호출 RTCLIB by NeiroN
DS3231 rtc; // RTC로 선언 (I2C 주소는 0x57, 0x68)
#include <DHT.h> // DHT 온습도 라이브러리 호출
#define DHTPIN 2 // 온습도센서 2번핀에 연결
#define DHTTYPE DHT22 // 온습도센서 모델지정 DHT22
DHT dht(DHTPIN, DHTTYPE); // DHT 설정(2,DHT22)
//#include <LiquidCrystal.h> // LCD사용위해 라이브러리 호출
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // lcd 설정
#include <LiquidCrystal_I2C.h> // I2C LCD사용위해 라이브러리 호출
LiquidCrystal_I2C lcd(0x27,20,4); //LCD 설정 (I2C주소는 LCD의 종류에 따라 다르기때문에 LCD가 0x3F, 0x27인지 확인하세요)
//LCD 주소는 뒷면 A0 A1 A2 연결로 주소 변경 가능. 연결 안되어 있으면 0x3F, 0x27 둘 중 하나
//***********************
#define no_dust 1.20 //최초 전원 인가 후 깨끗한 환경에서의 지속적으로 측정되는 전압값 넣어주세요. 이 값은 직접 측정해야 함
//***********************
int dustout = A2; // 먼지센서의 5번핀을 먼지 측정위해 아두이노 A2번에 연결(A로표시)
int v_led = A3; // 먼지센서의 3번핀을 아두이노 A3번에 연결. 센서 내부 적외선 led를 on/off 제어(D로표시)-디지털은 6번핀으로
int s_ledr = 9; // 공기 상태에 나쁨 RED
int s_ledg = 8; // 공기 상태에 보통 Green
int s_ledb = 7; // 공기 상태에 좋음 Blue
float vo_value = 0; // 센서로 읽은 값 변수 선언
float sensor_voltage = 0; // 센서로 읽은 값을 전압으로 측정한 값
float dust_density = 0; // 실제 미세먼지 밀도
float tempMax; // 최고온도 실수형 변수 선언
float tempMin; // 최고온도 실수형 변수 선언
#include <MS5611.h> // 기압계 라이브러리 설정
MS5611 MS5611(0x77); // 기압계 주소 설정, I2C 통신
#include <SPI.h> // SD카드를 사용하기 위한 통신 라이브러리
#include <SD.h> // SD카드를 사용하기 위한 통신 라이브러리
const int sd_CS = 10; // CS핀을 10번에 할당
File myFile;
// MOSI-pin 11, MISO-pin 12, CLK-pin 13은 고정, CS-pin 10-환경따라 이것만 변경
// 센서쉴드 핀은 + - D11 D10 D13 D12 순
//------------------------------------------------------------------
void setup()
{
Serial.begin(9600); // 통신속도 9600bps로 시리얼 통신 시작
Wire.begin();
rtc.begin();
// rtc.adjust(DateTime(2024, 5, 21, 9, 26, 00)); // RTC의 초기 시간 설정. 한번 설정 후에는 주석 처리 후 다시 업로드해야 시작시 시간 초기화 안됨
rtc.adjust(DateTime(__DATE__, __TIME__)); // RTC의 초기 시간 설정. 현재 컴퓨터의 시간으로 설정
dht.begin(); // 온습도 센서 시작
delay (2000); // 온습도 측정을 위해 2초 지연. DHT22 센서는 첫 측정을 위해 2초의 시간이 필요
// 각 센서의 핀을 정의
pinMode(v_led,OUTPUT); // 먼지센서 적외선led 출력으로 설정
pinMode(s_ledr,OUTPUT); // LED Red 출력 설정
pinMode(s_ledg,OUTPUT); // LED green 출력 설정
pinMode(s_ledb,OUTPUT); // LED blue 출력 설정
// digitalWrite(v_led,LOW); // 먼지센서 적외선 LED ON
digitalWrite(s_ledr,LOW); // RGB LED OFF상태
digitalWrite(s_ledb,LOW); // RGB LED OFF상태
digitalWrite(s_ledg,LOW); // RGB LED OFF상태
float temp = dht.readTemperature(); //온도값을 temp에 저장
float humi = dht.readHumidity(); //습도값을 humi에 저장
tempMax = temp; // 최고온도 실수형 변수 선언
tempMin = temp; // 최저온도 실수형 변수 선언
MS5611.begin(); // 기압센서 시작
SD.begin(sd_CS); // SD카드 준비
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일에 아래 데이터 항목 제목 기록 후 닫기
myFile.println(F("연월일, 시간, 온도, 습도, 기압, 미세먼지, 열지수, 불쾌지수"));
myFile.close();
lcd.begin(20, 4); // LCD 시작
lcd.setCursor(0,0);
lcd.backlight();
lcd.clear();
}
//----------------------------------------------------------------
void loop()
{
// 온도-습도 값 측정
float temp = dht.readTemperature(); //온도값을 temp에 저장
float humi = dht.readHumidity(); //습도값을 humi에 저장
float hic = dht.computeHeatIndex(temp, humi, false); // 열지수-체감온도 계산
float DI = ((9/5)*temp)-((0.55*(1-(humi/100))*(((9/5)*temp)-26)))+32; // 불쾌지수 계산
// if(isnan(humi) || isnan(temp)) { // 온도 습도 값을 읽지 못했을때 재시도
// Serial.println("Fail. Try again");
// lcd.print("Fail. Try again...");
// delay(2000);
// return;
// }
// 하루중 최고 최저 온도 계산
DateTime now = rtc.now(); //현재시간을 세팅
int hh = now.hour();
int mm = now.minute();
int ss = now.second();
int hhmax;
int mmmax;
int ssmax;
int hhmin;
int mmmin;
int ssmin;
int resetTime = (hh*60 + mm); // 시간과 분을 분 단위로 환산하여 2분보자 작거나 같으면 날짜변경으로 처리하여 최저최고기온 초기화
if (resetTime > 2) {
if (temp > tempMax) {tempMax = temp; hhmax = hh; mmmax = mm; ssmax = ss;} //최고온도 계산 기록
if (temp < tempMin) {tempMin = temp; hhmin = hh; mmmin = mm; ssmin = ss;} //최저온도 계산 기록
}
if (resetTime <= 2){
tempMax = temp; hhmax = hh; mmmax = mm; ssmax = ss;
tempMin = temp; hhmin = hh; mmmin = mm; ssmin = ss; // 최고 최저온도 초기값 설정
}
// 기압 측정하기
MS5611.read(); // 기압센서에서 값 읽어오기
float pressure = MS5611.getPressure(); // 측정값에서 기압 읽기
float atmtemp = MS5611.getTemperature(); // 측정값에서 온도 읽기
// 미세먼지 측정
// 샘플링을 위해서 적외선 LED는 0.32ms 동안 펄스를 유지해야하며, 0.28ms이후에 데이터를 읽을 수 있음
digitalWrite(v_led,LOW); // 센서의 적외석LED를 켜고-320us 지속시켜야 한다. 구조상 PNP트렌지스터가 있어 LOW가 켠상태
delayMicroseconds(280); // 기기 특성상 280us동안 기다린 후 먼지농도 측정
vo_value=analogRead(dustout); // 센서에서 먼지에 의한 전압변화 데이터를 읽음
delayMicroseconds(40); // 320us 유지를 위해 40us 더 기다림, 320us - 280us = 40
digitalWrite(v_led,HIGH); // 적외선 LED를 OFF
delayMicroseconds(9680); // 측정 후 대기상태 유지. 10us(주기) -320us(펄스폭) 한 값
// IRED켜고 끄는데 총 10ms필요, 이때 0.32ms동안 켜고 9.68ms동안 끈다. 이것이 한 펼스인데 9.68ms을 마이크로세컨드로 변환 9680
sensor_voltage=get_voltage(vo_value); // get_voltage 함수 실행
dust_density=get_dust_density(sensor_voltage); // get_dust_density 함수 실행
int dust_density1 = dust_density; // 실수형 자료를 정수형 자료로 변환
// 센서를 이용하여 먼지 없는 상태의 전압을 측정할때 필요
/*
Serial.print("value = ");
Serial.println(vo_value); // 센서에서 읽은 전압
Serial.print("Voltage = ");
Serial.print(sensor_voltage); // 센서에서 읽은 전압을 증폭 변환한 전압.
Serial.println(" [V]");
Serial.print("Dust Density = ");
Serial.print(dust_density); // 먼지 값으로 초기값을 잡을때는 가급적 이 값이 0에 가까운값이 되도록 공기청정기 위에서 측정
Serial.println(" [ug/m^3]");
*/
// 미세먼지에 따른 LED색 변경-핀 부족으로 사용하지 않음
if(dust_density <= 50){
digitalWrite(s_ledr,LOW); // 파랑색 LED켜기-대기질 좋음 상태
digitalWrite(s_ledb,HIGH);
digitalWrite(s_ledg,LOW);
}
else if(dust_density <= 100){
digitalWrite(s_ledr,LOW); // 녹색 LED켜기-대기질 보통 상태
digitalWrite(s_ledb,LOW);
digitalWrite(s_ledg,HIGH) ;
}
else {
digitalWrite(s_ledr,HIGH); // 빨강색 LED켜기-대기질 나쁨 상태
digitalWrite(s_ledb,LOW);
digitalWrite(s_ledg,LOW);
}
// 총 순환 시간을 20초로 만들기 위해
// Serial.println(millis()); // 순환시간 체크용 밀리초로 진행시간 표시
delay(234);
//*************** 시리얼과 LCD 출력을 모아 출력****************
// 시간 LCD 출력
char buf1[20];
char buf2[20];
for (int i=0; i <5; i++ ) { //---------LCD에만 5초간 시간 표시
DateTime now = rtc.now(); //현재시간을 세팅
snprintf(buf1, sizeof(buf1), "%04d-%02d-%02d", now.year(), now.month(), now.day());
snprintf(buf2, sizeof(buf2), "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
lcd.setCursor(5, 1);
lcd.print(buf1);
lcd.setCursor(6, 2);
lcd.print(buf2);
delay(1000);
lcd.clear();
}
// 온도, 습도, 기압, 미세먼지 LCD 출력
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.setCursor(6, 0);
lcd.print(temp,1);
lcd.setCursor(14, 0);
lcd.print((char)223); //문자 도 기호 표시
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Humi: ");
lcd.setCursor(6, 1);
lcd.print(humi,0);
lcd.setCursor(14, 1);
lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("Atmo:");
lcd.setCursor(6, 2);
lcd.print(pressure, 1);
lcd.setCursor(14, 2);
lcd.print("hPa");
lcd.setCursor(0, 3);
lcd.print("PM25:");
lcd.setCursor(6, 3);
lcd.print(dust_density1);
lcd.setCursor(14, 3);
lcd.print("ug/m^3");
delay(7000);
lcd.clear();
// 최저, 최고온도, 열지수, 불쾌지수 LCD 표시
lcd.setCursor(0,0);
lcd.print("Tmax:");
lcd.setCursor(6, 0);
lcd.print(tempMax, 1);
lcd.setCursor(12, 0);
lcd.print((char)223); // 문자 도 기호 표시
lcd.print("C");
lcd.setCursor(15, 0);
char buf3[20];
snprintf(buf3, sizeof(buf3), "%02d:%02d", hhmax, mmmax);
lcd.print(buf3);
lcd.setCursor(0,1);
lcd.print("Tmin:");
lcd.setCursor(6, 1);
lcd.print(tempMin, 1);
lcd.setCursor(12, 1);
lcd.print((char)223); // 문자 도 기호 표시
lcd.print("C");
lcd.setCursor(15, 1);
char buf4[20];
snprintf(buf4, sizeof(buf4), "%02d:%02d", hhmin, mmmin);
lcd.print(buf4);
lcd.setCursor(0, 2);
lcd.print("H I:");
lcd.setCursor(6, 2);
lcd.print(hic,0);
lcd.setCursor(0, 3);
lcd.print("D I:");
lcd.setCursor(6, 3);
lcd.print(DI,0);
delay(7000); // 7초간 유지
lcd.clear(); // 화면지우기
// 시간 시리얼 출력
// DateTime now = rtc.now(); // 현재시간을 불러움-앞에서 선언함
Serial.print(buf1);
Serial.print(" ");
Serial.print(buf2);
Serial.print("\t");
// 온도, 습도, 기압, 미세먼지 등 시리얼 출력
Serial.print(F("온도: "));
Serial.print(temp,1); //온도값 출력
Serial.print(" °C \t");
Serial.print(F("습도: "));
Serial.print(humi,0); //습도값 출력
Serial.print((" % \t"));
Serial.print(F("대기압: "));
Serial.print(pressure,1); //대기압 출력
Serial.print((" hPa \t"));
Serial.print(F("미세먼지: "));
Serial.print(dust_density1); //미세먼지 출력
Serial.print((" ug/m^3 \t"));
Serial.print(F("열지수: "));
Serial.print(hic,0); //열지수 출력
Serial.print("\t");
Serial.print(F("불쾌지수: "));
Serial.print(DI,0);
Serial.print("\t");
Serial.print(F("시계온도: "));
Serial.print(rtc.getTemp(), 1);
Serial.print("\t");
Serial.print(F("기압센서온도: "));
Serial.println(atmtemp, 1);
// SD 카드에 데이타 저장
if (mm == 00 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
if (mm == 20 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
if (mm == 40 && ss <= 20) {
myFile = SD.open("aws-data.txt", FILE_WRITE); // 파일명 설정
myFile.print(buf1); myFile.print(", "); myFile.print(buf2); myFile.print(", ");
myFile.print(temp,1); myFile.print(", "); myFile.print(humi,0); myFile.print(", "); myFile.print(pressure,1); myFile.print(", ");
myFile.print(dust_density1); myFile.print(", "); myFile.print(hic,0); myFile.print(", "); myFile.println(DI,0);
myFile.close(); // 기록하고 파일을 닫는다.
}
}
//--------------------------------------
// 정의된 함수, 미세먼지 측정용
float get_voltage(float value)
{
float V= value * 5.0 / 1024; // 아날로그값을 전압값으로 바꿈
return V;
}
float get_dust_density(float voltage)
{
float dust=(voltage - no_dust) / 0.005; // 데이터 시트에 있는 미세먼지 농도(ug/m^3) 공식 기준에 의해 전압을 0.005로 나눔
return dust;
}
센서가 없음. 준비 되면 ..........