Introduction
Purpose
The aim of this project is to use PMS7003 sensor to measure air quality and visualize the result with Google Chart API. Air quality measurement data is presented in gauge type. We can check current status via web browser using WiFi connection.
This project is based on our previous project named "ESP8266-based air quality monitoring system using PMS7003 sensor". It adds web server functionality to offer web-based user interface, which is based on Google Chart API to visualize measured air quality data. For web server, we use ESPAsyncWebServer library and it is available at github. Additionally, we need to install EPS8266 Sketch Data Upload to upload web server related files to Wemos. For example, in this project, we use HTML, CSS files under data directory. In other words, we need to upload sketch and web related files separately.
Features
This project is based on our previous project named "ESP8266-based air quality monitoring system using PMS7003 sensor". It adds web server functionality to offer web-based user interface, which is based on Google Chart API to visualize measured air quality data. For web server, we use ESPAsyncWebServer library and it is available at github. Additionally, we need to install EPS8266 Sketch Data Upload to upload web server related files to Wemos. For example, in this project, we use HTML, CSS files under data directory. In other words, we need to upload sketch and web related files separately.
Prerequisites
- ESP8266 package for Arduino IDE
- EPS8266 Sketch Data Upload
- ESPAsyncTCP Library
- ESPAsyncWebServer Library
Hardware
-Wemos D1 mini : US$1.77 on Aliexpress
-PMS7003 air quality sensor : US$16.80 on Aliexpress
Step 1. Setup hardware
PMS7003 sensor comes with a small breakout board, which has TX, RX, VCC, GND pins. Connect TX of PMS7003 to D5 of Wemos, RX to D6, VCC to 5V, and GND to G. Finally, connect micro usb to Wemos for uploading firmware, and check serial monitor and serial plotter in Android IDE to make sure the sensor works correctly.
Step 2. Upload sketch to Wemos D1 mini
This step is to upload sketch to Wemos as usual. In the following sketch, two values need to be modified with your own.
- WIFI_SSID : Name of WiFi router
- WIFI_PASS : Password of WiFi router
Step 3. Upload data to Wemos D1 mini
This step is to upload web server related files (HTML, CSS) to Wemos. These files are located in directory named data. Click "ESP8266 Sketch Data Upload" under Tools menu in Arduino IDE to upload these files to Wemos. Once it shows the measurement data, it will refresh every 3 seconds automatically.
HTML file
The size of gauge is defined in width, height of options variable. Just change these values to customize chart size. And if you want to modify refresh rate, change the value of 30000 in setInterval function to other value.
CSS file
After uploading firmware, Wemos restarts itself automatically. Once Wemos D1 mini has restarted, serial monitor shows welcome message as below. Remember IP address of Wemos to connect it via web browser.
Use web browser to connect to the device, then it will show current time and visualized information, which is based on Google Chart API. It will refresh itself every 3 seconds automatically.
- EPS8266 Sketch Data Upload
- ESPAsyncTCP Library
- ESPAsyncWebServer Library
Requirements
-Wemos D1 mini : US$1.77 on Aliexpress
-PMS7003 air quality sensor : US$16.80 on Aliexpress
Instructions
PMS7003 sensor comes with a small breakout board, which has TX, RX, VCC, GND pins. Connect TX of PMS7003 to D5 of Wemos, RX to D6, VCC to 5V, and GND to G. Finally, connect micro usb to Wemos for uploading firmware, and check serial monitor and serial plotter in Android IDE to make sure the sensor works correctly.
Step 2. Upload sketch to Wemos D1 mini
This step is to upload sketch to Wemos as usual. In the following sketch, two values need to be modified with your own.
- WIFI_SSID : Name of WiFi router
- WIFI_PASS : Password of WiFi router
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Air quality monitoring system using PMS7003 sensor with WIFI, WEBSERVER | |
* | |
* Hardware : Wemos D1 mini, PMS7003 | |
* Software : Arduino IDE, EPS8266 Sketch Data Upload | |
* Library : ESPAsyncTCP, ESPAsyncWebServer | |
* | |
* January 2020. Brian Kim | |
*/ | |
#include <SoftwareSerial.h> | |
#include <ESP8266WiFi.h> | |
#include <ESPAsyncTCP.h> | |
#include <ESPAsyncWebServer.h> | |
#include <FS.h> | |
/** | |
* WiFi credentials | |
*/ | |
#define WIFI_SSID "your-ssid" | |
#define WIFI_PASS "your-password" | |
/** | |
* PMS7003 sensor pin map and packet header | |
*/ | |
#define PMS7003_TX D5 // GPIO12 | |
#define PMS7003_RX D6 // GPIO14 | |
#define PMS7003_PREAMBLE_1 0x42 // From PMS7003 datasheet | |
#define PMS7003_PREAMBLE_2 0x4D | |
#define PMS7003_DATA_LENGTH 31 | |
/** | |
* Wemos serial RX - TX PMS7003 | |
* TX - RX | |
*/ | |
SoftwareSerial _serial(PMS7003_TX, PMS7003_RX); // RX, TX | |
AsyncWebServer server(80); | |
int _pm1, _pm25, _pm10; | |
void connectWifi() { | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(WIFI_SSID, WIFI_PASS); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
String readSensor() { | |
int checksum = 0; | |
unsigned char pms[32] = {0,}; | |
String ret; | |
/** | |
* Search preamble for Packet | |
* Solve trouble caused by delay function | |
*/ | |
while( _serial.available() && | |
_serial.read() != PMS7003_PREAMBLE_1 && | |
_serial.peek() != PMS7003_PREAMBLE_2 ) { | |
} | |
if( _serial.available() >= PMS7003_DATA_LENGTH ){ | |
pms[0] = PMS7003_PREAMBLE_1; | |
checksum += pms[0]; | |
for(int j=1; j<32 ; j++){ | |
pms[j] = _serial.read(); | |
if(j < 30) | |
checksum += pms[j]; | |
} | |
_serial.flush(); | |
if( pms[30] != (unsigned char)(checksum>>8) | |
|| pms[31]!= (unsigned char)(checksum) ){ | |
Serial.println("Checksum error"); | |
ret = String(_pm1) + " " + String(_pm25) + " " + String(_pm10); | |
return ret; | |
} | |
if( pms[0]!=0x42 || pms[1]!=0x4d ) { | |
Serial.println("Packet error"); | |
ret = String(_pm1) + " " + String(_pm25) + " " + String(_pm10); | |
return ret; | |
} | |
_pm1 = makeWord(pms[10],pms[11]); | |
_pm25 = makeWord(pms[12],pms[13]); | |
_pm10 = makeWord(pms[14],pms[15]); | |
ret = String(_pm1) + " " + String(_pm25) + " " + String(_pm10); | |
return ret; | |
} | |
} | |
void setup() | |
{ | |
Serial.begin(115200); // For debugging | |
_serial.begin(9600); // For communicating with PMS7003 sensor | |
Serial.printf("\nAir quality monitoring system using PMS7003 sensor with WIFI, WEBSERVER\n"); | |
// Initialize filesystem | |
if(!SPIFFS.begin()){ | |
Serial.println("ERROR SPIFFS failed"); | |
return; | |
} | |
connectWifi(); // Connect to WiFi | |
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ | |
// request->send(SPIFFS, "/index.html", String(), false, templateHandler); | |
request->send(SPIFFS, "/index.html", "text/html"); | |
}); | |
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ | |
request->send(SPIFFS, "/style.css", "text/css"); | |
}); | |
/** | |
* Send measured data(PM1.0, PM2.5, PM10.0) back to client | |
* Data format : Each value is separated by white space | |
* Example : 11 22 33 | |
*/ | |
server.on("/updatesensorreading", HTTP_GET, [](AsyncWebServerRequest *request){ | |
request->send_P(200, "text/plain", readSensor().c_str()); | |
}); | |
server.begin(); | |
} | |
void loop() | |
{ | |
} |
This step is to upload web server related files (HTML, CSS) to Wemos. These files are located in directory named data. Click "ESP8266 Sketch Data Upload" under Tools menu in Arduino IDE to upload these files to Wemos. Once it shows the measurement data, it will refresh every 3 seconds automatically.
HTML file
The size of gauge is defined in width, height of options variable. Just change these values to customize chart size. And if you want to modify refresh rate, change the value of 30000 in setInterval function to other value.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Air quality monitoring system using PMS7003 sensor with WIFI, WEBSERVER | |
Hardware : Wemos D1 mini, PMS7003 | |
Software : Arduino IDE, EPS8266 Sketch Data Upload | |
Library : ESPAsyncTCP, ESPAsyncWebServer --> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Air quality monitor</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<meta name="mobile-web-app-capable" content="yes"> | |
<link rel="stylesheet" type="text/css" href="style.css"> | |
<script src="https://www.gstatic.com/charts/loader.js"></script> | |
<script> | |
google.charts.load('current', {'packages':['gauge','corechart']}); | |
// Display clock above air quality gauge | |
function startClock() { | |
var now = new Date(); | |
var hour = now.getHours(); | |
var minute = now.getMinutes(); | |
var second = now.getSeconds(); | |
minute = minute < 10 ? "0" + minute : minute; | |
second = second < 10 ? "0" + second : second; | |
document.getElementById("clock_div").innerHTML = | |
hour + ":" + minute + ":" + second; | |
var tmp = setTimeout(startClock, 500); | |
} | |
</script> | |
</head> | |
<body onload="startClock()"> | |
<h1>Air quality monitor</h1> | |
<div id="clock_div"></div> | |
<div id="chart_div"></div> | |
<script> | |
google.charts.setOnLoadCallback(drawChart); | |
function drawChart() { | |
var data = google.visualization.arrayToDataTable([ | |
['Label', 'Value'], | |
['PM1.0', 0], | |
['PM2.5', 0], | |
['PM10', 0] | |
]); | |
var options = { | |
width: 800, height: 240, | |
redFrom: 90, redTo: 100, | |
yellowFrom:75, yellowTo: 90, | |
minorTicks: 5 | |
}; | |
var chart = new google.visualization.Gauge(document.getElementById('chart_div')); | |
chart.draw(data, options); | |
setInterval(function ( ) { | |
var xhttp = new XMLHttpRequest(); | |
xhttp.onreadystatechange = function() { | |
if (this.readyState == 4 && this.status == 200) { | |
var pms = this.responseText.split(" "); | |
data.setValue(0, 1, pms[0]); | |
data.setValue(1, 1, pms[1]); | |
data.setValue(2, 1, pms[2]); | |
chart.draw(data, options); | |
} | |
}; | |
xhttp.open("GET", "/updatesensorreading", true); | |
xhttp.send(); | |
}, 3000 ); | |
} | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Air quality monitoring system using PMS7003 sensor with WIFI, WEBSERVER | |
Hardware : Wemos D1 mini, PMS7003 | |
Software : Arduino IDE, EPS8266 Sketch Data Upload | |
Library : ESPAsyncTCP, ESPAsyncWebServer */ | |
html { | |
font-family: monospace; | |
} | |
h1 { | |
font-size:45px; | |
} | |
body { | |
text-align: center; | |
} | |
div { | |
display: table; | |
margin: 0 auto; | |
} | |
#clock_div { | |
font-size:27px; | |
} |
Results
Use web browser to connect to the device, then it will show current time and visualized information, which is based on Google Chart API. It will refresh itself every 3 seconds automatically.
References
- IoT Laboratory: ESP8266-based air quality monitoring system using PMS7003 sensor
- IoT Laboratory: ESP8266-based WiFi MQTT air quality monitoring system using PMS7003 sensor
- IoT Laboratory: ESP8266-based WiFi MQTT air quality monitoring system using PMS7003 sensor
- PMS7003 sensor : http://www.plantower.com/en/content/?110.html
- PMS7003 datasheet pdf
- Arduino WiFiClient
- EPS8266 Sketch Data Upload
- ESPAsyncTCP Library
- ESPAsyncWebServer Library
- Google Chart : Gauge
Source codes at github- Arduino WiFiClient
- EPS8266 Sketch Data Upload
- ESPAsyncTCP Library
- ESPAsyncWebServer Library
- Google Chart : Gauge
No comments:
Post a Comment