Thingspeak 로 먼지센서 모니터링하기

by 임성국 | 2016-08-30 18:24
wearable 디자인씽킹포트폴리오 라즈베려파이 미세먼지 아두이노



Thingspeak 로 먼지센서 모니터링하기


기획실장의 글에서 PMS7003 을 사용하여 시리얼통신으로 미세먼지 데이터가 가져오는 것을 확인하였고[PMS7003 테스트 소스코드], 이후에 thingspeak 라는 IOT 서비스를 사용하여 아두이노에서 thingspeak 로 데이터를 업로드하는 것을 확인하였다[Thingspeak 사용 기초]. 


여기서는 PMS7003 에서 가져온 데이터를 Thingspeak 에 올리는 작업을 진행한다. 기존 소스코드를 그대로 사용하려 하였으나 메모리 부족현상이 일어나 불필요한 부분과 디버깅에 관련된 부분(시리얼 모니터링부분)을 상당부분 제거하였다.


또한 아두이노 우노와 이더넷 실드는 핀 10,11,12,13 번을 사용하므로 기존 예제에서 소프트웨어 시리얼로 사용했던 10,11번을 8,9번으로 변경하였다.




기본 소스는 PMS7003 테스트 소스코드에 있는 예제와 아두이노에 Thingspeak 라이브러리를 설치하면 나오는 예제에서 WriteMultipleVoltages 를 참고하였다. 


변경(축소)된 소스는 아래에 적어두었다. 

소스에서 당장 필요하지 않은 부분은 과감히 삭제했으나, 세부적인 부분까지 아직 살피지 못한 관계로 아직 더 삭제할 부분이 남아있을 것으로 보인다.



// SoftSerial useing pin 8,9

// Ethernet Shield using pin pin 10, 11, 12, 13 

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

/*

    IOT : Ethernet Shield 

    MCU : Arduino UNO

    Dust Sensor : PMS7003      

      Using pins : SoftwareSerial =[ 8,9 ], Ethernet Shield =[ 10,11,12,13 ]

      more information : http://wemakers.tistory.com/50

*/

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


#include <SoftwareSerial.h> 

#include <SPI.h>

#include <Ethernet.h>

#include "ThingSpeak.h"



byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x48};

EthernetClient client;


unsigned long myChannelNumber = 149242;

const char * myWriteAPIKey = "ZKRW1PLJU8CEWNJ8";


SoftwareSerial Serial1(8, 9); // RX, TX

 

int incomingByte = 0; // for incoming serial data

int nowPM1_0, nowPM2_5, nowPM10_0;


const int MAX_FRAME_LEN = 64;

char frameBuf[MAX_FRAME_LEN];

int detectOff = 0;

int frameLen = MAX_FRAME_LEN;

bool inFrame = false;

const bool DEBUG = false;

uint16_t calcChecksum = 0;


struct PMS7003_framestruct {

    uint8_t  frameHeader[2];

    uint16_t frameLen = MAX_FRAME_LEN;

    uint16_t concPM1_0_CF1;

    uint16_t concPM2_5_CF1;

    uint16_t concPM10_0_CF1;

    uint16_t concPM1_0_amb;

    uint16_t concPM2_5_amb;

    uint16_t concPM10_0_amb;

    uint16_t rawGt0_3um;

    uint16_t rawGt0_5um;

    uint16_t rawGt1_0um;

    uint16_t rawGt2_5um;

    uint16_t rawGt5_0um;

    uint16_t rawGt10_0um;

    uint8_t  version;

    uint8_t  errorCode;

    uint16_t checksum;

} thisFrame;



void setup() {

    Ethernet.begin(mac);

    ThingSpeak.begin(client);

    delay(1000);    

}


bool pms7003_read() {

    Serial1.begin(9600);

    bool packetReceived = false;

    while (!packetReceived) {

        if (Serial1.available() > 32) {

            int drain = Serial1.available();

            for (int i = drain; i > 0; i--) {

                Serial1.read();

            }

        }

        if (Serial1.available() > 0) {

            incomingByte = Serial1.read();

            if (!inFrame) {

                if (incomingByte == 0x42 && detectOff == 0) {

                    frameBuf[detectOff] = incomingByte;

                    thisFrame.frameHeader[0] = incomingByte;

                    calcChecksum = incomingByte; // Checksum init!

                    detectOff++;

                }

                else if (incomingByte == 0x4D && detectOff == 1) {

                    frameBuf[detectOff] = incomingByte;

                    thisFrame.frameHeader[1] = incomingByte;

                    calcChecksum += incomingByte;

                    inFrame = true;

                    detectOff++;

                }

            }

            else {

                frameBuf[detectOff] = incomingByte;

                calcChecksum += incomingByte;

                detectOff++;

                uint16_t val = frameBuf[detectOff-1]+(frameBuf[detectOff-2]<<8);

                switch (detectOff) {

                    case 6:

                        nowPM1_0 = thisFrame.concPM1_0_CF1 = val;

                        break;

                    case 8:

                        nowPM2_5 = thisFrame.concPM2_5_CF1 = val;

                        break;

                    case 10:

                        nowPM10_0 = thisFrame.concPM10_0_CF1 = val;

                        break;

                    case 29:

                        val = frameBuf[detectOff-1];

                        thisFrame.version = val;

                        break;

                    case 30:

                        val = frameBuf[detectOff-1];

                        thisFrame.errorCode = val;

                        break;

                    case 32:

                        thisFrame.checksum = val;

                        calcChecksum -= ((val>>8)+(val&0xFF));

                        break;

                    default:

                        break;

                }

    

                if (detectOff >= frameLen) {

                    packetReceived = true;

                    detectOff = 0;

                    calcChecksum = 0;

                    inFrame = false;

                }

            }

        }

    }

    Serial1.end();

    return (calcChecksum == thisFrame.checksum);

}



void loop () {

    if (!pms7003_read()) {

        ThingSpeak.setField(1,nowPM1_0);

        ThingSpeak.setField(2,nowPM2_5);

        ThingSpeak.setField(3,nowPM10_0);

        ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  

        delay(20000); // ThingSpeak will only accept updates every 15 seconds. 

    }

}



마지막으로 스마트폰앱으로 thingspeak 를 검색하면 관련 앱들이 나온다. ThingView Free 앱을 설치하고 화면을 캡춰한 사진이다.





댓글 0

MADE BY

임성국

c언어, iot, pcb제작, 라즈베리파이, 스크래치, 아두이노, 인벤터, 회로설계