Last active
July 12, 2024 08:10
-
-
Save partrita/f1f2d2d4bfa7cc535d7ab1347d09b229 to your computer and use it in GitHub Desktop.
My arduino sensor kit code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================== | |
// 미세먼지, 온습도 관측 프로젝트 | |
//============================== | |
#include <Wire.h> | |
#include <LiquidCrystal_I2C.h> | |
#include <DHT11.h> | |
#if defined(ARDUINO) && ARDUINO >= 100 | |
#define printByte(args) write(args); | |
#else | |
#define printByte(args) print(args,BYTE); | |
#endif | |
//I2C LCD는 일반적으로 0x27혹은 0x3F입니다 | |
LiquidCrystal_I2C lcd(0x27, 16, 2); | |
byte temperatureImage[] = {0x04,0x0A,0x0A,0x0A,0x0E,0x1F,0x1F,0x0E}; | |
byte humidityImage[] = {0x04,0x0E,0x0E,0x1F,0x1F,0x1F,0x1F,0x0E}; | |
byte doImage[] = {0x1C,0x14,0x1C,0x00,0x00,0x00,0x00,0x00}; | |
//LCD "micro" 이미지 | |
byte microImage[] = {0x00, | |
0x00, | |
0x09, | |
0x09, | |
0x09, | |
0x0E, | |
0x08, | |
0x08 | |
}; | |
//LCD "3" 이미지 | |
byte threeImage[] = {0x18,0x04,0x18,0x04,0x18,0x00,0x00,0x00}; | |
// 특수 문자 | |
uint8_t heartImage[8] = {0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0E, 0x04, 0x00}; | |
//=====디지털 핀 | |
const int DHT_PIN = 2; | |
const int DUST_PIN = 8; | |
const int BUZZER_PIN = 5; | |
//=====온습도센서 관련 변수 | |
float humidity = 0; | |
float temperature = 0; | |
DHT11 dht11(DHT_PIN); | |
//=====먼지센서 관련 변수 | |
unsigned long duration; | |
unsigned long starttime; | |
unsigned long sampletime_ms = 4000;// 먼지센서의 샘플링시간을 4초로 설정합니다. | |
unsigned long lowpulseoccupancy = 0; | |
float ratio = 0; | |
float concentration = 0; | |
float dustDensity = 0; | |
float dustState = 0; | |
boolean DustCalculate_RUN = false; | |
boolean DustCalculate_Done = false; | |
unsigned int buzzer_count = 0; | |
// 핀 초기화 | |
void initPin() { | |
pinMode(DUST_PIN, INPUT); | |
pinMode(BUZZER_PIN, OUTPUT); | |
} | |
// LCD 초기화 | |
void initLCD() { | |
lcd.init(); // 초기화 | |
lcd.backlight(); // 백라이트 키기 | |
// 그림아이콘을 등록합니다. | |
lcd.createChar(0, humidityImage); | |
lcd.createChar(1, temperatureImage); | |
lcd.createChar(2, doImage); | |
lcd.createChar(3, microImage); | |
lcd.createChar(4, threeImage); | |
lcd.createChar(5, heartImage); | |
lcd.home(); | |
lcd.print("Loading..."); | |
lcd.write(byte(5)); | |
} | |
void setup() | |
{ | |
initPin(); | |
initLCD(); | |
starttime = millis(); | |
pinMode(LED_BUILTIN, OUTPUT); | |
} | |
void loop() | |
{ | |
//부저가 다 울린 뒤에 미세먼지 측정 시작! | |
//미세먼지 측정 중에는 부저와 시작시간 초기화 안되도록 함. | |
if(DustCalculate_RUN == true) | |
{ | |
calcDustDensity(); | |
//미세먼지 측정 후에 온습도 측정 / LCD 표시 | |
if(DustCalculate_Done == true) { | |
calcHumidityAndTemperature(); | |
printLCD(); | |
DustCalculate_Done = false; | |
} | |
} else { | |
/* | |
국제 미세먼지농도에 따른 경계단계 기준분류 | |
30ug/m^3 이하 : 좋음 / 30~80ug/m^3 : 보통 / 80~150ug/m^3 : 나쁨 / 150ug/m^3 초과 : 매우 나쁨 | |
먼지농도 경계 단계에 따라 LCD 표시내용이 달라지며, | |
부저가 각각 보통 1번 / 나쁨 2번 / 매우 나쁨 3번 연속으로 울리도록 되어있습니다. | |
*/ | |
if (buzzer_count > 0 ) { | |
digitalWrite(BUZZER_PIN, HIGH); | |
delay(100); | |
digitalWrite(BUZZER_PIN, LOW); | |
delay(200); | |
buzzer_count--; | |
} else digitalWrite(BUZZER_PIN, LOW); | |
//시작시간 초기화 | |
if((dustState > 0 && buzzer_count == 0) || (dustState == 0)) | |
{ | |
DustCalculate_RUN = true; | |
starttime = millis(); | |
} | |
} | |
// the loop function runs over and over again forever | |
digitalWrite(LED_BUILTIN, HIGH); // LED turns on | |
delay(1000 / (dustDensity + 1)); // wait for second | |
digitalWrite(LED_BUILTIN, LOW); // turns off | |
delay(1000 / (dustDensity + 1)); | |
} | |
void printLCD() { | |
//LCD에 먼지센서와 온습도센서를 출력합니다. | |
lcd.clear(); | |
lcd.setCursor(0, 0); | |
lcd.print(dustDensity); | |
lcd.write(3); | |
lcd.print("g/m"); | |
lcd.write(4); | |
lcd.setCursor(10, 0); | |
if(dustState == 0)lcd.print(" GOOD"); | |
else if(dustState == 1)lcd.print(" SOSO"); | |
else if(dustState == 2)lcd.print(" BAD "); | |
else if(dustState == 3)lcd.print(" SOBAD"); | |
lcd.write(byte(5)); | |
lcd.setCursor(0, 1); | |
lcd.write(0); | |
lcd.print(" "); | |
lcd.print(humidity); | |
lcd.print("% "); | |
lcd.write(1); | |
lcd.print(" "); | |
lcd.print(temperature); | |
lcd.write(2); | |
// lcd.print("C "); | |
} | |
/** 신뢰할 수 있는 먼지밀도 계산하기 | |
대부분의 아날로그센서의 경우 값이 튀는 현상이 있는데, | |
이것을 보정하기 위해 여러번 값을 누적한 후, | |
평균값을 내어 신뢰할 수 있는 먼지밀도를 구합니다. | |
*/ | |
void calcDustDensity() { | |
duration = pulseIn(DUST_PIN, LOW); | |
lowpulseoccupancy = lowpulseoccupancy + duration; | |
if ((millis() - starttime) > sampletime_ms) { | |
DustCalculate_RUN = false; | |
DustCalculate_Done = true; | |
ratio = lowpulseoccupancy / (sampletime_ms * 10.0); // Integer percentage 0=>100 | |
concentration = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve | |
dustDensity = concentration * 100 / 23000; | |
lowpulseoccupancy = 0; | |
if(dustDensity > 150) buzzer_count = 3; | |
else if(dustDensity > 80) buzzer_count = 2; | |
else if(dustDensity > 30) buzzer_count = 1; | |
else buzzer_count = 0; | |
dustState = buzzer_count; | |
} | |
} | |
/** 습도,온도 계산 | |
DHT온습도센서를 이용해서 온도와 습도를 계산합니다. | |
*/ | |
void calcHumidityAndTemperature() { | |
dht11.read(humidity, temperature); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment