날로 심각해지고 있는 미세먼지 대책에 도움이 되고자 미세먼지 측정기를 제작해 보았습니다.
이 제품은 “아두이노”를 활용하여 고장 없고, 값싸며, 정확하고, 신뢰성 있는 미세먼지농도 알림장치로서, 외부에 측정기를 노출하여 학교나 각급 기관에서 미세먼지 농도를 숩게 확인할 수 있게 하기 위해 , 아날로그 지침과 4단계로 구분된 깃발로 미세먼지 정보를 알리고 있습니다.
통상 미세먼지는 좋음, 보통, 나쁨, 매우 나쁨 단계로 미세먼지 깃발이 올라가며, 지침으로 미세 먼지 농도를 표시하여 먼 곳에서도 확인할 수 있돍 하였고, 특히 미세먼지가 나쁨 이상의 단계에서는 음성메세지가 방송되며, 실내의 환풍기 와 공기청정기를 자동으로 작동시키도록 하고 있습니다.
미세먼지 측정기는 다음과 같이 동작합니다.
여기서 사용된 미세먼지 센서는 Led 와 Photo Sensor사이에 들어오는 미세먼지에 빛이 산란되면서 미세먼지에 비례되는
신호를 얻을 수 있어 "아두이노" 나노단자에 입력되어 다음과 같은 Coding으로 깃발과 Analog 지침으로 표시됩니다.
이 시스템을 작동하기 위한 System Coding 은 다음과 같습니다.
const int led4 = 12; // 적색 led
const int voice = 2; //음성보드
int val10 = 40; // 미세먼지 좋음
int val11 = 80; // 미세먼지 보통
int val12 = 160; // 미세먼지 나쁨
int val13 = 220; //미세먼지 매우 나쁨
int val14 = 900; // 미세먼지 최대 지시값
const int valueMin = 0;
const int valueMax = 300;
int value = 0;
/*
variable
*/
float density, voltage;
int adcvalue;
/*
private function
*/
int Filter(int m)
{
static int flag_first = 0, _buff[10], sum;
const int _buff_max = 10;
int i;
const int valueMin = 0;
const int valueMax = 300;
int range = 0;
if(flag_first == 0)
{
flag_first = 1;
for(i = 0, sum = 0; i < _buff_max; i++)
{
_buff[i] = m;
sum += _buff[i];
}
return m;
}
else
{
sum -= _buff[0];
for(i = 0; i < (_buff_max - 1); i++)
{
_buff[i] = _buff[i + 1];
}
_buff[9] = m;
sum += _buff[9];
i = sum / 10.0;
return i;
}
}
void setup(void)
{
pinMode(iled, OUTPUT);
digitalWrite(iled, LOW); //iled default closed
Serial.begin(9600); //send and receive at 9600 baud
Serial.print("***********************************aveShare ***********************************\n");
pinMode(led1, OUTPUT); // 청색 led
pinMode(led2, OUTPUT); // 녹색 led
pinMode(led3, OUTPUT); // 황색 led
pinMode(led4, OUTPUT); // 적색 led
myServo1.attach(3); // attaches the servo on pin 2 to the servo object
myServo2.attach(9); // attaches the servo on pin 3 to the servo object
myServo3.attach(10); // attaches the servo on pin 4 to the servo object
myServo4.attach(6); // attaches the servo on pin 5 to the servo object
myServo5.attach(5); // attacahes the servo on pin 6 to the servo object
myServo1.write(10); // sets the servo position according to the scaled value
myServo2.write(170); // sets the servo position according to the scaled value
myServo3.write(170); // sets the servo position according to the scaled value
myServo4.write(170); // sets the servo position according to the scaled value
myServo5.write(170); // sets the servo position according to the scaled value
delay(20);
}
void loop(void)
{
/*
get adcvalue
*/
digitalWrite(iled, HIGH);
delayMicroseconds(280);
adcvalue = analogRead(vout);
digitalWrite(iled, LOW);
adcvalue = Filter(adcvalue);
/*
covert voltage (mv)
*/
voltage = (SYS_VOLTAGE / 1024.0) * adcvalue * 11;
/*
voltage to density
*/
if(voltage >= NO_DUST_VOLTAGE)
{
voltage -= NO_DUST_VOLTAGE;
density = voltage * COV_RATIO;
}
else
density = 0;
/*
display the result
*/
Serial.print(" The current dust concentration is: ");
Serial.print(density);
Serial.print(" ug/m3\n");
delay(1000);
int jung = map(density,0,300,0,200);
delay(10);
myServo1.write(170-jung);
delay(10);
// int value = map(jung,0,170,0,7);
delay(10);
Serial.print("Servo value flag = ;") ;
Serial.print(value);
delay (10);
{
if (density <= val10)
{
//Servo 2번과 LED 1을 점등합니다
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
myServo2.write(10);
delay(20);
myServo3.write(170);
delay(20);
myServo4.write(170);
delay(20);
myServo5.write(170);
delay(20);
}
else if (density <= val11)
{
//Servo 3번과 LED 2를 점등합니다.
digitalWrite(led2, HIGH);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
myServo3.write(10);
delay(20);
myServo2.write(170);
delay(20);
myServo4.write(170);
delay(20);
myServo5.write(170);
delay(20);
}
else if (density <= val12)
{
//Servo 4번과 LED3를 점등합니다.
digitalWrite(led3, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
myServo4.write(10);
delay(20);
myServo3.write(170);
delay(20);
myServo2.write(170);
delay(20);
myServo5.write(170);
delay(20);
}
else if (density <= val13)
{
//Servo5번과 LED4를 점등합니다.
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
myServo5.write(10);
delay(20);
myServo3.write(170);
delay(20);
myServo2.write(170);
delay(20);
myServo4.write(170);
delay(20);
digitalWrite(voice,HIGH);
delay(500);
digitalWrite(voice,LOW);
delay(10);
}
else if (density <= val14)
{
// 미세먼지가 220을 넘어서도 Servo5번과 LED4를 점등합니다.
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
myServo5.write(10);
delay(20);
myServo3.write(170);
delay(20);
myServo2.write(170);
delay(20);
myServo4.write(170);
delay(20);
digitalWrite(voice,LOW);
delay(500);
digitalWrite(voice,HIGH);
delay(10);
}
else
{
//Servo 와 LED를 원위치 합니다.
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(voice,HIGH);
myServo1.write(10);
delay(20);
myServo2.write(170);
delay(20);
myServo3.write(170);
delay(20);
myServo4.write(170);
delay(20);
myServo5.write(170);
delay(20);
}
// 5초동안 대기한 후 0로 지침을 변함.
delay(5000);
myServo1.write(170);
}
}