· 6 years ago · Oct 12, 2019, 09:06 AM
1#include <Adafruit_Sensor.h>
2#include <DHT.h>
3#include <DHT_U.h>
4#include <ESP8266WiFi.h>
5#include <ESP8266WebServer.h>
6#include <SDS011.h>
7#include <SoftwareSerial.h>
8
9
10
11#define SDS_RX D1
12#define SDS_TX D2
13
14#define DHTPIN D4
15#define DHTTYPE DHT22
16
17const char* ssid = "wifi-ssid";
18const char* password = "password";
19const char* host = "api.thingspeak.com";
20String apiKey = ""; // thingspeak.com api key goes here
21
22float p10,p25;
23int error;
24
25struct Air {
26 float pm25;
27 float pm10;
28 float humidity;
29 float temperature;
30};
31
32
33DHT_Unified dht(DHTPIN, DHTTYPE);
34ESP8266WebServer server(80);
35WiFiClient client;
36SDS011 sds;
37
38void setup() {
39 Serial.begin(9600);
40 sds.begin(SDS_RX,SDS_TX);
41 dht.begin();
42 connectToWiFi();
43}
44
45void loop() {
46 Air airData = readPolution();
47 if (client.connect(host,80) & airData.pm25 > 0.0) {
48 String postStr = apiKey;
49 postStr +="&field1=";
50 postStr += String(airData.pm25);
51 postStr +="&field2=";
52 postStr += String(airData.pm10);
53 postStr +="&field3=";
54 postStr += String(airData.humidity);
55 postStr +="&field4=";
56 postStr += String(airData.temperature);
57 postStr += "\r\n\r\n";
58
59 client.print("POST /update HTTP/1.1\n");
60 client.print("Host: api.thingspeak.com\n");
61 client.print("Connection: close\n");
62 client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
63 client.print("Content-Type: application/x-www-form-urlencoded\n");
64 client.print("Content-Length: ");
65 client.print(postStr.length());
66 client.print("\n\n");
67 client.print(postStr);
68 }
69 client.stop();
70 delay(15000);
71
72 server.handleClient();
73}
74
75void connectToWiFi(){
76 WiFi.mode(WIFI_STA);
77 WiFi.begin(ssid, password);
78
79 Serial.print("Connecting to ");
80 Serial.println(ssid);
81
82 while (WiFi.status() != WL_CONNECTED) {
83 delay(500);
84 Serial.print(".");
85 }
86
87 Serial.println("");
88 Serial.println("WiFi connected");
89 Serial.println("IP address: ");
90 Serial.println(WiFi.localIP());
91 startServer();
92}
93
94void startServer(){
95 server.on("/", handleRoot);
96 server.begin();
97 Serial.println("HTTP server started");
98}
99
100void handleRoot() {
101 Air airData = readPolution();
102 server.send(200, "text/plain", "PM2.5: " + String(airData.pm25) + " (" + String(calculatePolutionPM25(airData.pm25)) + "% normy) | PM10: " + String(airData.pm10) + " (" + String(calculatePolutionPM10(airData.pm10)) + "% normy) | Temperature: " + airData.temperature + " | Humidity: " + airData.humidity);
103}
104
105Air readPolution(){
106 float temperature, humidity;
107 error = sds.read(&p25,&p10);
108 if (!error) {
109 sensors_event_t event;
110 dht.temperature().getEvent(&event);
111 if (isnan(event.temperature)) {
112 Serial.println("Error reading temperature!");
113 } else {
114 temperature = event.temperature;
115 }
116
117 dht.humidity().getEvent(&event);
118 if (isnan(event.relative_humidity)) {
119 Serial.println("Error reading humidity!");
120 } else {
121 humidity = event.relative_humidity;
122 }
123
124 Air result = (Air){normalizePM25(p25/10, humidity), normalizePM10(p10/10, humidity), humidity, temperature};
125 return result;
126 } else {
127 Serial.println("Error reading SDS011");
128 return (Air){0.0, 0.0, 0.0, 0.0};
129 }
130}
131
132//Correction algorythm thanks to help of Zbyszek Kiliański (Krakow Zdroj)
133float normalizePM25(float pm25, float humidity){
134 return pm25/(1.0+0.48756*pow((humidity/100.0), 8.60068));
135}
136
137float normalizePM10(float pm10, float humidity){
138 return pm10/(1.0+0.81559*pow((humidity/100.0), 5.83411));
139}
140
141float calculatePolutionPM25(float pm25){
142 return pm25*100/25;
143}
144
145float calculatePolutionPM10(float pm10){
146 return pm10*100/50;
147}