Sharp GP2Y1010AU0F 센서로 정밀 공기질 모니터 만들기
부품 및 소모품
| 부품 | 수량 |
| Arduino Nano R3 | 1 |
| 220µF 커패시터 | 1 |
| 150Ω 관통형 저항 | 1 |
필요한 도구 및 장비
앱 및 온라인 서비스
- Arduino IDE
- Processing (The Processing Foundation)
프로젝트 개요
Sharp 광학 먼지 센서(GP2Y1010AU0F)는 담배 연기 같은 초미세 입자 감지에 특히 효과적이며, 공기청정기 시스템에 널리 사용됩니다. 적외선 발광 다이오드와 포토트랜지스터가 대각선으로 배치되어 공기 중 먼지의 반사광을 감지합니다.
이전에는 DSM501A와 PPD42NS 센서 기반 공기질 모니터를 소개했었는데, 이번엔 약 $5로 매우 저렴한 Sharp GP2Y1010AU0F 기반 장치를 만듭니다. 회로는 매우 간단하며 센서 소비 전류가 최대 20mA(일반 11mA)로 아두이노에서 직접 전원 공급 가능합니다. 출력은 아날로그 전압으로 먼지 밀도에 비례하며 감도는 0.5V/0.1mg/m³입니다.
DFRobot 샘플 코드를 수정해 µg/m³ 단위로 읽도록 했고, Processing의 'meter' 라이브러리로 PC 모니터에 대형 아날로그 계기판 형태로 시각화했습니다.
세 센서 비교 (DSM501A, PPD42NS, Sharp GP2Y1010AU0F)
세 센서 모두 몇 달러면 구매 가능한 저가형입니다. 동일 조건 테스트 결과 Sharp GP2Y1010AU0F가 가장 우수했습니다.
- 매우 낮은 농도에도 높은 감도
- 소비 전력이 매우 낮아 아두이노 직접 구동 가능
- 아두이노 코드가 단순하고 커스터마이징 용이
- 아날로그 출력으로 별도 전자회로 없이 측정 기기 직접 연결 가능
구매 링크: 알리익스프레스
코드
아두이노 코드
/* Standalone Sketch for Arduino UNO + Sharp GP2Y1010AU0F */
int measurePin = 0; // 먼지 센서 → 아두이노 A0
int ledPower = 2; // 센서 LED 드라이버 핀 → 아두이노 D2
int samplingTime = 280;
int deltaTime = 40;
int sleepTime = 9680;
float voMeasured = 0;
float calcVoltage = 0;
float dustDensity = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPower, OUTPUT);
}
void loop() {
digitalWrite(ledPower, LOW); // LED 켜기 (Active LOW)
delayMicroseconds(samplingTime);
voMeasured = analogRead(measurePin); // 먼지 값 읽기
delayMicroseconds(deltaTime);
digitalWrite(ledPower, HIGH); // LED 끄기
delayMicroseconds(sleepTime);
// 0-5V → 0-1023 매핑
calcVoltage = voMeasured * (5.0 / 1024.0);
// Chris Nafis (c) 2012 공식
dustDensity = 170 * calcVoltage - 0.1;
Serial.println(dustDensity); // 단위: µg/m³
delay(1000);
}
Processing 코드 (PC 시각화)
/* Meter 라이브러리 활용 아날로그 계기판 표시 */
import processing.serial.*;
import meter.*;
Serial port;
String[] list;
Meter m;
void setup() {
size(1150, 910);
background(255, 255, 200);
port = new Serial(this, "COM4", 9600); // 포트 번호 확인 필요
m = new Meter(this, 125, 25, true);
m.setMeterWidth(850);
m.setFrameColor(color(100, 0, 0));
m.setTitleFontColor(color(0, 200, 0));
m.setPivotPointColor(color(255, 0, 0));
m.setArcColor(color(0, 0, 200));
m.setScaleFontColor(color(200, 100, 0));
m.setTicMarkColor(color(217, 22, 247));
m.setArcMinDegrees(90.0);
m.setArcMaxDegrees(360.0);
m.setArcThickness(5);
m.setNeedleThickness(4);
m.setMinScaleValue(0.0);
m.setMaxScaleValue(800.0);
m.setInputSignalOutOfRangeFontColor(color(0, 255, 0));
m.setMinInputSignal(0);
m.setMaxInputSignal(800);
m.setHighSensorWarningActive(true);
m.setHighSensorWarningValue(200.0);
String[] scaleLabelsA = {"0", "100", "200", "300", "400", "500", "600", "700", "800"};
m.setScaleLabels(scaleLabelsA);
m.setTitle("Airquality (µg/m³)");
m.setDisplayDigitalMeterValue(true);
}
void draw() {
if (port.available() > 0) {
String val = port.readString();
list = split(val, ',');
float air = float(list[0]);
println("Airquality: " + air + " µg/m³");
m.updateMeter(int(air));
}
}
회로도
