Arduino Dust Sensor with ESP8266

The ESP8266 comes in various packages (e.g. ESP-12, ESP-07) but I bought the (pretty) bare package for less than US$2.50. For this price, the ESP8266 (ESP-01) has got 80 MHz CPU, 512KB program storage space, WiFi and 2 GPIOs. This tiny Arduino board is very suitable for Internet-of-Things (IoT) implementations.
With this, I decided to rebuild my previous Arduino-based Dust Sensor. The codes for the ESP8266 is as follow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /**********************************************/ /* Building Arduino Dust Sensor using: */ /* - ESP8266 ESP-01 */ /* - 3.3-to-5v Logic Level Converter */ /* - Shinyei PPD42NS */ /* http://www.sca-shinyei.com/pdf/PPD42NS.pdf */ /* */ /* Author: shadowandy[dot]sg[at]gmail[dot]com */ /* Web: www.shadowandy.net */ /* */ /* Wiring Instruction: */ /* - PPD42NS Pin 1 => GND */ /* - PPD42NS Pin 2 => GPIO0 */ /* - PPD42NS Pin 3 => 5V */ /* - PPD42NS Pin 4 => GPIO2 */ /**********************************************/ #include <ESP8266WiFi.h> const char ssid[] = "fill in your wireless SSID"; const char pass[] = "fill in your wireless pass"; const char thingSpeakAddress[] = "api.thingspeak.com"; const char thingSpeakAPIKey[] = "fill in your thingspeak API write key"; #define PM25 0 #define PM10 1 int pin[] = {2, 0}; unsigned long starttime; unsigned long sampletime_ms = 30000; unsigned long triggerOn[2]; unsigned long triggerOff[2]; unsigned long lowpulseoccupancy[] = {0, 0}; float ratio[] = {0, 0}; float count[] = {0, 0}; boolean value[] = {HIGH, HIGH}; boolean trigger[] = {false, false}; void setup() { connectWiFi(); pinMode(pin[PM25], INPUT); //Listen at the designated PIN pinMode(pin[PM10], INPUT); //Listen at the designated PIN starttime = millis(); //Fetching the current time ESP.wdtEnable(WDTO_8S); // Enabling Watchdog } void loop() { value[PM25] = digitalRead(pin[PM25]); value[PM10] = digitalRead(pin[PM10]); if (value[PM25] == LOW && trigger[PM25] == false) { trigger[PM25] = true; triggerOn[PM25] = micros(); } if (value[PM25] == HIGH && trigger[PM25] == true) { triggerOff[PM25] = micros(); lowpulseoccupancy[PM25] += (triggerOff[PM25] - triggerOn[PM25]); trigger[PM25] = false; } if (value[PM10] == LOW && trigger[PM10] == false) { trigger[PM10] = true; triggerOn[PM10] = micros(); } if (value[PM10] == HIGH && trigger[PM10] == true) { triggerOff[PM10] = micros(); lowpulseoccupancy[PM10] += (triggerOff[PM10] - triggerOn[PM10]); trigger[PM10] = false; } ESP.wdtFeed(); // Reset the WatchDog if ((millis() - starttime) > sampletime_ms) //Checking if it is time to sample { ratio[PM25] = lowpulseoccupancy[PM25] / (sampletime_ms * 10.0); count[PM25] = 1.1 * pow(ratio[PM25], 3) - 3.8 * pow(ratio[PM25], 2) + 520 * ratio[PM25] + 0.62; ratio[PM10] = lowpulseoccupancy[PM10] / (sampletime_ms * 10.0); count[PM10] = 1.1 * pow(ratio[PM10], 3) - 3.8 * pow(ratio[PM10], 2) + 520 * ratio[PM10] + 0.62; count[PM25] -= count[PM10]; ESP.wdtFeed(); // Reset the WatchDog // Begin mass concentration calculation float concentration[] = {0, 0}; double pi = 3.14159; double density = 1.65 * pow(10, 12); double K = 3531.5; ESP.wdtFeed(); // Reset the WatchDog // PM10 double r10 = 2.6 * pow(10, -6); double vol10 = (4 / 3) * pi * pow(r10, 3); double mass10 = density * vol10; concentration[PM10] = (count[PM10]) * K * mass10; ESP.wdtFeed(); // Reset the WatchDog // PM2.5 double r25 = 0.44 * pow(10, -6); double vol25 = (4 / 3) * pi * pow(r25, 3); double mass25 = density * vol25; concentration[PM25] = (count[PM25]) * K * mass25; // End of mass concentration calculation ESP.wdtFeed(); // Reset the WatchDog connectWiFi(); updateThingSpeak("1=" + String(concentration[PM10], DEC) + "&2=" + String(count[PM10], DEC) + "&3=" + String(concentration[PM25], DEC) + "&4=" + String(count[PM25], DEC)); // Resetting for next sampling lowpulseoccupancy[PM25] = 0; lowpulseoccupancy[PM10] = 0; starttime = millis(); ESP.wdtFeed(); // Reset the WatchDog } } void connectWiFi() { if (WiFi.status() == WL_CONNECTED) { return; } WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void updateThingSpeak(String tsData) { WiFiClient client; if (!client.connect(thingSpeakAddress, 80)) { return; } client.print(F("GET /update?key=")); client.print(thingSpeakAPIKey); client.print(F("&")); client.print(tsData); client.print(F(" HTTP/1.1\r\nHost: api.thingspeak.com\r\n\r\n")); client.println(); } |
The periodically updated codes can be found on Github – Arduino Dust Sensor.