본문 바로가기
아두이노 센서

[센서/먼지센서] PM7003 plantower 먼지센서

by 작동미학 2020. 7. 11.
반응형

Maker들의 표준 먼지센서가 되고 있는 PM7003 platower 먼지센서를 아두이노와 연결하여 안정되게 작동할 수 있다..

 

▶ 이 가이드를 따라하면

- PM1.0, PM2.5, PM10 입자에 대한 미세먼지 농도를 아두이노로 구할 수 있다.

 

▶ 부품 설명 및 회로 구성

시중에 다양한 먼지 센서가 존재하고, 기존에 GP2Y1010AU 센서도 소개한 바가 있는데(https://bbangpan.tistory.com/51 ), 아마도 먼지 센서가 저가형 중에서는(PMS7003도 대략 2만원 내외수준) 가장 정확하지 않나 싶다. 사실은 먼지 센서 외에도 개를 보유하고 있는데 값들이 도무지 믿을 없거나 별도의 calibration을 해야하기도 한다.

 출시된지 몇년 되지 않은 이 센서는, 경쟁 센서에 비해 필요한 납땜이나 별도 연결해야하는 저항 같은 부품도 없고, 센서값을 단순 읽기만 할때는 VCC,GND,TX 3개의 핀만 연결하면 된다. 별도의 기능(passive mode 존재)을 사용한다 해도 RX 1개 핀이 추가된 4 충분하다.

 주의할 것은 기본 센서의 핀 크기가 아두이노 연결에는 맞지 않아, 연결 어댑터가 같이 있는 것을 구매해야 한다는 점이다. 아니면 애매한 납땜작업을 해야할 있다. 4개의 일반 연결 핀이 있는 어댑터 모듈이 포함되어 있는지  확인하자.

[PLANTOWERPMS7003 먼지센서와 아두이노 연결을 위한 케이블 어댑터, GND/VCC/TX/RX 4개 핀만 연결하면 된다]

[센서의 왼쪽 하단 작은 구멍으로 팬이 돌면서 공기가 유입되어 미세먼지가 측정된다]

배선은 설명한대로 매우 간단하다. 아래와 같이 연결하면 된다.

[VCC->5V, GND->GND, RX->D6, TX->D7 으로 연결한다. 읽기만 할 때면 RX->D6도 필요없다.]

[다른 각도에서 찍어보자]

 이 PMS7003 센서는 미세먼지 PM1.0, PM2.5, PM10 크기 입자의 농도를 알려주는데, 다른 센서처럼 애매하게 알려주지 않고, 정확히 농도 숫자 값을 던져주는게 장점이다. 이 센서를 쓰고나면 다른 센서들이 모두 고생덩어리였다는 것을 알게 된다. 참조로 PM1.0등의 숫자는 입자의 크기를 나타내는데 PM1.01.0 μm(마이크로미터) 수준의 입자로, PM2.5 이하이면 미세먼지라고 한다. 유입된 공기에 레이저를 투사해 빛의 변화를 통해 측정한다고 알려져있다.

 이 센서는 기본적으로 계속 측정값을 알려주는 모드(기본 모드)와 필요에 따라 측정을 요청하여 처리하는 두가지 모드(Active/Passive)가 존재하는데, 아래 소스는 기본모드인 계속 측정값을 알려주는 Active모드만을 다룬다. Passive 모드를 사용하려면 RX 핀도 연결되어야 하고 라이브러리도 쓰는게 나아 보인다. URL (https://kwonkyo.tistory.com/130)을 참고하면 된다.

 센서와의 통신은 Serial으로 수행(9600 baud rate사용)하고, 32 bytes의 전송된 데이터를 조금만 가공하면 각 입자크기별 미세먼지 농도를 구할 수 있다.

 잠깐 소스를 설명해보면, 32 bytes를 SoftwareSerial을 통해 입력받되, 맨 처음 2 bytes가 지정된 헤더인지 우선 확인을 한다(잘못해서 중간 바이트부터 전송받으면 값이 깨지게 된다. 시중의 간단한 소스들도 특이 문제가 없으나 일단은 이상한 값을 간혹가다 만나게 되겠다.). 그리고 29 번 인덱스를 지니는 byte는 에러코드를 주는데, 0인지를 확인해서 정상임이 판정되면 각기 10,11bytes 12,13bytes, 14,16bytes를 두개씩 합쳐서 각각의 먼지농도(μg/m^3)값을 알아낸다. bit 연산자가 사용되었는데 A값*256 + B값의 또다른 표현 정도로 생각하면 된다. 아래 혹시나 익숙하지 않은 분들을 위해 간단히 나타내보았다.

예> pms[10] = 0x23, pms[11] = 0x84

     PM1.0농도값 = pms[10]<<8 + pms[11] = pms[10]*256(=0x2300) + pms[11](=0x84) = 0x2384

 

아래 실제 소스를 참조한다. github에서 바로 다운로드 받을 수도 있다.

https://github.com/bbangpan/bbangpan.com/blob/master/neibc_pms7003/neibc_pms7003.uno

 

/* Originally posted on www.bbangpan.com

   Program Description: PMS7003 dust sensor, plantower

   Tested on : Arduino 1.8.5, Arduino UNO

  

   Copyright (c) 2020 www.bbangpan.com. All rights reserved.

   This program can be used for any non-commercial purpose freely.   */

 

#include <SoftwareSerial.h>

 

// VCC to V5, GND to GND, RX(PMS7003) to D6(Arduino), TX(PMS7003) to D7(Arduino)

#define PIN_TX_PMS7003 7  // PIN matched with TX of PMS7003 

#define PIX_RX_PMS7003 6  // PIN matched with RX of PMS7003 

 

#define HEAD_1 0x42

#define HEAD_2 0x4d

 

#define PMS7003_BAUD_RATE 9600 // Serial Speed of PMS7003

 

SoftwareSerial pmsSerial(PIN_TX_PMS7003,PIX_RX_PMS7003); // RX, TX of Arduino UNO

unsigned char pmsbytes[32]; // array for 32 bytes stream from PMS7003

 

void setup() {

  Serial.begin(115200); // Serial Monitor baud to 115200 on Arduino IDE

  pmsSerial.begin(PMS7003_BAUD_RATE);

}

 

void loop() {

  if(pmsSerial.available()>=32){

    int i=0;

 

    //initialize first two bytes with 0x00

    pmsbytes[0] = 0x00;

    pmsbytes[1] = 0x00;

   

    for(i=0; i<32 ; i++){

      pmsbytes[i] = pmsSerial.read();

 

      //check first two bytes - HEAD_1 and HEAD_2, exit when it's not normal and read again from the start

      if( (i==0 && pmsbytes[0] != HEAD_1) || (i==1 && pmsbytes[1] != HEAD_2) ) {

        break;

      }

    }

 

    if(i>2) { // only when first two stream bytes are normal

      if(pmsbytes[29] == 0x00) {  // only when stream error code is 0

        int PM1_0_val = (pmsbytes[10]<<8) | pmsbytes[11]; // pmsbytes[10]:HighByte + pmsbytes[11]:LowByte => two bytes

        int PM2_5_val = (pmsbytes[12]<<8) | pmsbytes[13]; // pmsbytes[12]:HighByte + pmsbytes[13]:LowByte => two bytes

        int PM10_val = (pmsbytes[14]<<8) | pmsbytes[15]; // pmsbytes[14]:HighByte + pmsbytes[15]:LowByte => two bytes

       

        Serial.print("PMS7003 sensor - PM1.0 : ");

        Serial.print(PM1_0_val);

        Serial.print(" ug/m^3,  PM2.5 : ");

        Serial.print(PM2_5_val);

        Serial.print(" ug/m^3,  PM10 : ");

        Serial.print(PM10_val);

        Serial.println(" ug/m^3");

      } else {

        Serial.println("Error skipped..");

      }

    } else {

      Serial.println("Bad stream format error");

    }

  }

}

 

실제 컴파일하여 구동해보면 첨부와 같이 시리얼 모니터를 통해 미세먼지 농도를 구할 수 있다. 농도값이 올라가는 것이 보고 싶다면 수건이나 옷을 가까이에서 털어보면 해당 값이 상승하는 것을 볼 수 있다.

[소스를 컴파일하여 업로드하자. 라이브러리는 없이 가능하다]

[시리얼 모니터를 통해 확인된다. 먼지를 털어보면 소폭 수치가 올라간다]

 PMS5003도 포맷이 같다고 했으니, 위 코드 그대로 응용할 수 있지 않을까 생각된다. 위 먼지농도 값을 읽어다가 OLED에 출력하거나 해서 활용할 수 있겠다. 참고로 소스안의 ug은 μg(마이크로그램)을 나타낸다.

▶ 구매 가이드

PMS7003 : https://www.aliexpress.com/af/pms7003-cable.html?d=y&origin=n&SearchText=pms7003+cable&catId=0&initiative_id=SB_20200710074522 ($18전후)

 

강의 키워드

PMS5003, PMS7003 Plantower 먼지센서, 미세먼지, 아두이노

반응형