아두이노프로세싱 프로그래밍

초보자를 위한 “아두이노 온습도 센서 DHT11 및 FND 7 세그먼트 디스플레이 시스템을 확장한 GP2Y1010AU 미세먼지측정 시스템 ”

coding art 2017. 4. 21. 13:49
728x90

미세먼지 PM(Particulate Matter) 예보가 매일의 기상예보에 있어서 온습도와 더불어 중요 예보 대상이 되어 버린 지도 이미 수년이 되었다. 따라서 DHT11 센서를 사용하는 온습도 측정 외에도 미세먼지센서 GP2Y1010AU를 이용한 아두이노  프로젝트 또한 그 중요성이 점차 부각되고 있다. 온습도 측정과 미세먼지 측정은 사용되는 센서의 종류가 다르기는 하지만 성격상 일기예보의 동일한 축으로 여겨지므로 일괄 측정하여 디스플레이 하면 좋을 듯하다.


다만 배선 상의 문제가 있을 수 있으나 사진의 사례를 참조하기 바란다. 즉 배선을 사진처럼 잘 정리한다면 아주 컴팩트하고 니트하게 조립할 수 있을 것이다.
 
배선에서 주의해야 할 점은 다음과 같다. 미세먼지 센서GP2Y1010AU의 배선에는 저항 1개와 콘덴서 1개 배선이 수반되므로 빵판 사용이 필수적이다.



아울러 미세먼지 센서, 온습도 센서 DHT11, FND 7 세그먼트는 각각 전원과 접지(GND) 를 필요로 한다. 즉 3개의 전원과 3개의 접지가 필요하다. 하지만 아두이노 우노에서 전원은 3V3 1개와 5V 2개로 구성되어 있다. 따라서 3V3은 온습도계 DHT11에 할당하기로 한다. 한편 빵 판에서 FND의 5V 전원을 미세먼지 센서의 전원과 합류 시킨 후 아두이노 5V 전원에 연결한다.

GND 연결에 있어서는 DHT11의 GND는 Power Pins 지역에 있는 GND를 사용하며 검은 선으로 표시하였다. 반면에 미세먼지 센서에서 필요한 2개의 GND는 빵 판에서 FND의 GND와 3개를 합류 시킨 후 아두이노 우노 뒤편  Digital I/O pins 지역 왼쪽에 있는 1개의 GND를 사용하기로 하며 하늘색 선으로 표시하였다.

각각의 센서들의 디지털 데이터 핀들의 배선은 DUHT11은 5번 FND 는 1번 미세먼지 센서는 2번을 할당하였으며 초록색 선으로 표시하였다.

배선도에 있어서 상대적으로 굵은 선으로 표시된 부분이 미세먼지 센서 배선이며 기존의 DHT11과 FND 의 배선은 보다 가는 선으로 표현되었다. 만약에 복잡하다고 느껴지면 DHT11 배선을 제거하는 것도 나쁘지 않다.

코딩 측면에서는 미세먼지센서 코딩이 완전히 끝나면 별도로 DHT11 온습도 센서 코딩과 합치는 게 좋을 듯하다.

미세먼지 센서의 출력 결과 디스플레이는 FND에서 M을 출력하지 못하므로 PM의 P 만을 표시하도록 하면 나머지 3자리를 미세먼지 값으로 편리하게 읽을 수 있다.
 

우선적으로 미세먼지 센서 부분만 먼저 코딩 작업을 하기로 한다. GP2Y1010A 센서 규격에 의하면  샘플타임 델타타임 및 슬립타임 최적치가 지정되어 있으므로 절대 바꾸지 말고 그대로 사용하면 된다.

정수형 변수 nav는 샘플 평균 계산을 위한 샘플 수를 뜻하며 실수형 변수 sum은 평균계산을 위해 누적 값을 계산하는 변수다. 지금으로서는 매번 샘플링의 값을 볼 수 있도록 nav = 1의 값을 설정하였다.

setup()에서 통신 속도는 반드시 9600으로 설정한다. 이는 7세그먼트 FND를 사용함에 있어서 필수적으로 요구되는 조건이다,
디지털 핀 2번에서 pinMode() 설정은 GP2Y1010A 센서 내부의 다이오드 on OFF 를 위해서 필요한 준비 작업이다.



for loop는 샘플링 수에 따른 평균치를 계산할 수 있도록 정수형 변수 nav를 사용한다. 평균치 계산이 필요 없다면 nav = 1로 설정하면 된다.


서브루틴 particleSensing()에서 미세먼지 데이타  센싱을 위한 시간 파라메터들이 설정 입력 되었다.

아날로그 입력 값을 0∼1023 범위의 정수 데이터로 읽은 후 5V기준 전압에 대해 환산하여 calcVoltage를 얻는다.

calcVoltage가 0,6V 이하이면 제작사에서 제공하는 데이터가 없는 범위이므로 제외시킨다.

제작사의 센서 특성표에 따라 미세먼지 밀도를
μg/m3 로 환산한다. 시간 지연을 190 ms 로 설정한다. 1회 샘플링에 10ms 가 소요되므로 200 ms 에 1회 데이터 출력이 가능해진다.
















시리얼 출력 결과를 살펴보면 의외로 데이터의 변동 폭이 큼을 알 수 있다. 이 미세먼지 데이터의 측성이 상당히 랜덤 함을 잘 보여 준다. 랜덤한 데이터의 경우 평균을 취하더라도 그 값 조차 랜덤하다면 그 경향성을 쉽게 파악하기 어렵다.









PM_sensor_avraging_02


/*
 Standalone Sketch to use with a Arduino UNO and a
 Sharp Optical Dust Sensor GP2Y1010AU0F
*/
int measurePin = 0; //Connect dust sensor to Arduino A0 pin
int ledPower = 2;   //Connect 3 led driver pins of dust sensor to Arduino D2
 
int samplingTime = 280;
int deltaTime = 40;
int sleepTime = 9680;
int nav = 1;
float sum = 0;
float voMeasured = 0;
float calcVoltage = 0;
float dustDensity = 0;
float dv = nav;
float average_dustDensity;


void setup(){
  Serial.begin(9600);
  pinMode(ledPower,OUTPUT);// 미세먼지 센서 내부 LED
}
 
void loop() {
  sum = 0.0;
  for ( int i = 0; i<nav; i++) {
  sum = sum + particleSensing();
  }//for loop end
  average_dustDensity = sum/dv;
//  Serial.print("average_dustDensity = ");
  Serial.print("P");
  Serial.println((int)average_dustDensity);
//  Serial.write((int)average_dustDensity);
 }

float particleSensing() {

  digitalWrite(ledPower,LOW); // power on the LED
  delayMicroseconds(samplingTime);
   voMeasured = analogRead(measurePin);
  delayMicroseconds(deltaTime);
  digitalWrite(ledPower,HIGH); // turn the LED off
  delayMicroseconds(sleepTime);
  
  // 0 - 5V mapped to 0 - 1023 integer values
  calcVoltage = voMeasured * (5.0 / 1024.0);
  if( calcVoltage > 0.6 ) {
  // linear eqn from http://www.howmuchsnow.com/arduino/airquality/
  dustDensity =1000.0*( 0.172 * calcVoltage - 0.1);
 
//  Serial.print("Digital Value(0-1023): ");
//  Serial.print(voMeasured);
 
//  Serial.print(" - V: ");
//  Serial.print(calcVoltage);
 
//  Serial.print(" - Density: ");
//  Serial.println(dustDensity); // unit: ug/m3
 
  delay(190);
  }
  return dustDensity;
}//프로그램 끝