printf("ho_tari\n");

프로젝트 - 미세먼지 측정기 본문

대학교 2학년 1학기/전자공학 SW 실험 1

프로젝트 - 미세먼지 측정기

호타리 2023. 9. 4. 12:19

1. 주제

아두이노 uno와 미세먼지 센서, RGB LED, 커패시터를 이용하여 미세먼지 측정기를 만들고 Arduino 프로그램과 Matlab의 시리얼 통신을 이용해 아두이노로부터 매트랩으로 미세먼지 측정값을 받아 edit text에 출력하고 측정값의 기준을 정해 기준마다 RGB LED의 색을 다르게 출력시킴과 동시에 axes에 다른 이미지들을 불러온다.

 

2. 구성

- 실험도구 : 아두이노 uno, 브레드보드, 미세먼지 센서(PM2.5 GP2Y1014AU), 점퍼 와이어, RGB LED, 커패시터

- 회로도

3. 동작 원리

<ARDUINO>

- RGB LED가 미세먼지 측정값의 크기에 따라 색이 변함

- 미세먼지 센서 안에 적외선 센서가 포함되어 있어 적외선 수신기와 송신기가 먼지에 의해 반사되는 빛의 양을 파악해 입자를 감지하여 대기 중의 미세먼지를 측정함

- 측정한 미세먼지 농도 수치를 시리얼 통신을 통해 Matlab으로 보냄

- 미세먼지 농도 수치의 크기에 따라 RGB LED 색이 변하고 Matlab GUI에 숫자 크기별로 다른 이미지를 불러옴

 

<Matlab GUI>

- GUI를 실행시킴

- CONNECT 버튼을 이용해 아두이노와 시리얼 통신 시작

- START 버튼을 누르면 측정 시작하고 측정값을 edit text에 실시간으로 출력

- 측정값의 크기에 따라 정해진 이미지들 불러오기

 

4. 코딩 분석

<아두이노 코드>

int dust_sensor = A0;   // 미세먼지 핀 번호
int rgb_red = 5;    // rgb 핀 빨간색 핀
int rgb_green = 6;  // rgb핀 녹색 핀
int rgb_blue = 7;  // rgb핀 파란색 핀
 
float dust_value = 0;  // 센서에서 입력 받은 미세먼지 값
float dustDensityug=0;  // ug/m^3 값을 계산
 
int sensor_led = 12;      // 미세먼지 센서 안에 있는 적외선 led 핀 번호
int sampling = 280;    // 적외선 led를 키고, 센서값을 읽어 들여 미세먼지를 측정하는 샘플링 시간
int waiting = 40;    
int stop_time = 9680;   // 센서를 구동하지 않는 시간
 
void setup(){
  Serial.begin(9600);   // 시리얼 모니터 시작, 속도는 9600
  pinMode(sensor_led,OUTPUT); // 미세먼지 적외선 led를 출력으로 설정
  pinMode(4, OUTPUT);
 
  pinMode(rgb_red, OUTPUT);     // 3색 LED 모듈 출력으로 설정, 붉은색
  pinMode(rgb_green, OUTPUT);   // 녹색
  pinMode(rgb_blue, OUTPUT);    // 파란색
}
 
void loop(){
  digitalWrite(sensor_led, LOW);    // LED 켜기
  delayMicroseconds(sampling);   // 샘플링해주는 시간. 
 
  dust_value = analogRead(dust_sensor); // 센서값 읽어오기
  
  delayMicroseconds(waiting);  // 너무 많은 데이터 입력을 피해주기 위해 잠시 멈춰주는 시간. 
 
  digitalWrite(sensor_led, HIGH); // LED 끄기
  delayMicroseconds(stop_time);   // LED 끄고 대기  
 
  dustDensityug = (0.17 * (dust_value * (5.0 / 1024)) - 0.1) * 1000;    // 미세먼지 값 계산           
  Serial.println(dustDensityug);          // 시리얼 모니터에 미세먼지 값 출력
  
  if(dustDensityug <= 30){       // 대기 중 미세먼지가 좋음일 때 파란색 출력
     analogWrite(rgb_red, 0);
     analogWrite(rgb_green, 0);
     analogWrite(rgb_blue, 255);
  }
  else if(30.0 < dustDensityug && dustDensityug <= 80.0)  // 대기 중 미세먼지가 보통일 때 녹색 출력
  {   
      analogWrite(rgb_red, 0);
      analogWrite(rgb_green, 255);
      analogWrite(rgb_blue, 0);   
   }
  else if (80.0 < dustDensityug && dustDensityug <= 150.0) // 대기 중 미세먼지가 나쁨일 때 노란색 출력
  {
     analogWrite(rgb_red, 255);
     analogWrite(rgb_green, 155);
     analogWrite(rgb_blue, 0);       
  }
  else                                                    // 대기 중 미세먼지가 매우 나쁨일 때 빨간색 출력
  {                                                    
     analogWrite(rgb_red, 255);
     analogWrite(rgb_green, 0);
     analogWrite(rgb_blue, 0);    
   }
   delay(2000);
}

 

<MATLAB 코드>

function CONNECT_Callback(hObject, eventdata, handles)
disp('Connecting...');           % command window에 “Connecting...” 출력
s1 = serial('COM3');            % 아두이노 프로그램과 Matlab 시리얼 통신 코드
set(s1,'BaudRate',9600);
fopen(s1);                      % 아두이노 프로그램과 Matlab 시리얼 통신 시작 코드
handles.s1 = s1;
disp('Connected');              % command window에 “Connected” 출력
guidata(hObject, handles);    

function DISCONNECT_Callback(hObject, eventdata, handles)
fclose(instrfind);                 % 아두이노 프로그램과 Matlab 시리얼 통신 중단
disp('Disconnected...');           % command window에 “Disconnected” 출력 
guidata(hObject, handles);
clear all;                         % 저장되어 있는 변수들을 모두 삭제
function START_Callback(hObject, eventdata, handles)
k = 0; intK = 0.1;          % while문에서 사용할 변수 지정
while(1)
    k = k + intK;
    dustDensityug = str2double(fscanf(handles.s1));
    set(handles.DUST,'String',dustDensityug);  % DUST라고 tag한 edit text에 dustDensityug의 측정값 표시
    if dustDensityug <= 30          % dustDensityug가 30보다 작거나 같으면
        axes(handles.axes1);
        imshow('C:\Users\erics\OneDrive\바탕 화면\good.jpg');       % axes에 이미지(good.jpg) 불러오기
    elseif dustDensityug <= 80     % dustDensityug가 80보다 작거나 같으면
        axes(handles.axes1);
        imshow('C:\Users\erics\OneDrive\바탕 화면\normal.jpg');     % axes에 이미지(normal.jpg) 불러오기
    elseif dustDensityug <= 150     % dustDensityug가 150보다 작거나 같으면
        axes(handles.axes1);
        imshow('C:\Users\erics\OneDrive\바탕 화면\bad.jpg');        % axes에 이미지(bad.jpg) 불러오기
    else     % dustDensityug가 150보다 크면
        axes(handles.axes1);
        imshow('C:\Users\erics\OneDrive\바탕 화면\worst.jpg');      % axes에 이미지(worst.jpg) 불러오기
    end
    pause(intK);
end
guidata(hObject, handles);

<결과>

 

 

6. 고찰

처음 프로젝트를 계획할 때 수업시간에 배운 내용들을 활용하면서도 우리 실생활에서도 도움이 될 아이디어로 무엇이 있을지 정말 많은 고민을 했었다. 그러다가 우연히 학술정보원 앞 미세먼지 측정기를 보게 되었고 미세먼지가 단순하고 가볍게 넘어가는 문제는 아니라고 생각하며 아두이노를 이용해 미세먼지 측정기를 만들어보자라는 생각을 하게 되었다. 처음 미세먼지 센서로 회로를 만들 때에는 정확한 미세먼지 측정기에 대한 많은 기대를 가졌었다. 하지만 이 프로젝트를 준비하면서 힘들었던 부분은 미세먼지 센서가 생각보다 성능이 우수하지 않았다는 점이다. 센서의 결선상태가 조금이라도 좋지 않으면 미세먼지 측정값이 정확하지 않은 것이 준비하는 과정에서 아쉽고 힘든 점이었다. 그래도 이번 프로젝트를 준비하면서 아두이노와 매트랩과 관련하여 다양하고 깊이 있게 공부해 보는 시간을 가질 수 있어 너무 뿌듯했다.