미세먼지 센서 GP2Y1010A 의 측정 신호의 변동성이 극히 높음을 예전에 지적하였다. 이러한 현상은 비단 먼지센서 뿐만 아니라 드론 제어를 위해 사용하는 MPU6050 가속도/자이로 센서나 L3G4200D 자이로센서도 마찬가지이다.
이와 같이 변동성이 극히 높은 센서의 측정값을 보다 안정적으로 관찰하기 위해서는 적절한 범위의 저주파 필터링 (Low Pass Filtering) 작업이 필수적이다.
아두이노나 호환 보드인 NodeMCU 또는 weMos 보드를 사용할 경우에는 아래와 같이 간단한 알고리듬으로 소프트웨어적인 디지털 저주파 필터링이 가능하다.
즉 미세먼지 신호 값 즉 dustDensity를 측정하여 사용한 후에 이 값을 previous_dustDensity 로 두어 위의 공식에서처럼 가중 평균하여 사용하는 것이다. 이미 드론에서 검증된 0.2에서 0.3 사이의 α 값을 사용해 본 결과 적절한 저주파 필터링이 이루어진다고 판단되며 미세먼지에서도 0.8을 사용하여 출력한 결과가 상기 그래프이다.
Webserver_html_svg_realtime_PM_LF_01
#include <ESP8266WiFi.h>
#include <DHT11.h>
const char* ssid = "android1234";//무선 공유기 id로 수정
const char* password = "dddddddddd";//무선 공유기 비빌번호
int ledPin = 2; //빌트인
int pin = D5; //온습도센서 GPIO 14번
int measurePin = 0; //Connect PM sensor to Arduino A0 pin
int ledPower = 16; //GPIO 16번
int samplingTime = 280;
int deltaTime = 40;
int sleepTime = 9680;
float voMeasured = 0;
float calcVoltage = 0;
float previous_dustDensity = 0;
float dustDensity = 0;
float alpha =0.8;
WiFiServer server(80);
DHT11 dht11(pin);
void setup() {
Serial.begin(115200);
delay(10);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
pinMode(ledPower,OUTPUT);// 미세먼지 센서 내부 LED
// Set WiFi to station mode and disconnect from an AP
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
Serial.println("Setup done");
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
//미세먼지 루틴
dustDensity = particleSensing();
Serial.print("P ");
Serial.println((int)dustDensity);
// Temperature & Humidity Sensing
int err;
float temp, humi;
if((err=dht11.read(humi, temp))==0)
{
// Serial.print("temperature:");
Serial.print("C ");
Serial.println((int)temp);
// Serial.print(" humidity:");
Serial.print("H ");
Serial.print((int)humi);
Serial.println();
}
else
{
Serial.println();
Serial.print("Error No :");
Serial.print(err);
Serial.println();
}
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
// Match the request
int value = LOW;
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, LOW);
value = HIGH;
}
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
//배경 색 문자 색 사이즈 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println("body {");
client.println("background-color: yellow;");
client.println("}");
client.println("p {");
client.println("color:red;");
client.println("font-size:150%;");
client.println("}");
client.println("</style>");
client.println("<title>Page Title</title>");
client.println("<h2> Arduino WiFi PM Scope</h2>");
client.println("</head>");
client.println("<body>");
client.println("<p>");
client.print(" Temperature = ");
client.print((int)temp);
client.print(" C ");
client.println("<br>");
client.print(" Humidity = ");
client.print((int)humi);
client.println(" % ");
client.println("</p>");
client.println("</body>");
client.println("<body>");
client.println("<svg height='300' width='500'>");
client.println("<rect height='300' width='500' style='fill:rgb(120,250,40);stroke-width:8;stroke:rgb(0,0,0)' />");
client.println("<rect height='250' width='500' style='fill:rgb(0,220,230);stroke-width:8;stroke:rgb(0,0,0)' />");
int val = (1.0-alpha)*previous_dustDensity+alpha*dustDensity;
int y1 = 300-val;
for(int i=2;i<500;i++){
int x1 = (i-1);
int x2 = i;
dustDensity = particleSensing();
if( dustDensity > 300.0 ) {
dustDensity = 300.0;
}
val = (1.0-alpha)*previous_dustDensity+alpha*dustDensity;
int y2 = 300-val;
client.println("<line x1='");
client.println(x1);
client.println("' y1='");
client.println(y1);
client.println("' x2='");
client.println(x2);
client.println("' y2='");
client.println(y2);
client.println("'");
client.println("' style='stroke:rgb(255,0,0);stroke-width:2' />");
client.println("Sorry, your browser does not support inline SVG.");
y1 = y2;
client.println("<rect height='40' width='70' style='fill:rgb(0,220,230);stroke-width:2;stroke:rgb(255,255,255)' />");
client.print("<text x='15' y='29' font-size='150%' fill='black' > ");
client.print(val);
client.print("</text>");
}
client.println("</svg>");
client.flush();
client.println("<br><br>");
//버튼 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println(".button {");
// client.println("background-color: #4CAF50;");
client.println("background-color: green;");
client.println("border: none;");
client.println("color: white;");
client.println("padding: 15px 32px;");
client.println("text-align: center;");
client.println("text-decoration: none;");
client.println("display: inline-block;");
client.println("font-size: 10px;");
client.println("margin: 14px 20px;");
client.println("cursor: pointer;");
client.println("}");
client.println("</style>");
client.println("</head>");
// client.println("<a href=\"/on\"\"><button>Data Refresh </button></a><br />");
client.println("<a href=\"/on\"\" class='button'>Data Refresh </button></a>");
client.println("</body>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}//loop문 끝
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 ) {
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(1000);
delay(190);
}
return dustDensity;
}//끝
'아두이노프로세싱 프로그래밍' 카테고리의 다른 글
초보자를 위한 아두이노 lcd 와이어링과 Hellow World!코딩 (0) | 2017.11.28 |
---|---|
weMos의 LED 및 DHT11 사물인터넷 와이파이 제어를 위한 HTML 코딩 (0) | 2017.11.22 |
ESP8266WiFi.h ZIP (0) | 2017.10.10 |
L239D 모터쉴드 DC모터 구동 RC카 앱 인벤터 블루투스 제어 아두이노 코드 (0) | 2017.10.09 |
L239D 모터쉴드 DC모터 구동 RC카 앱 인벤터 블루투스 제어 (0) | 2017.10.09 |