I demonstrated Using a bicolour LED with an NodeMCU in an earlier blog.
We now extend that code and instead of having a single LED, we have two. One LED will indicate the current levels of PM2.5, and the other LED will indicate the current levels of PM10. To do this we need to connect to the internet and download these levels from the Clean Air Eastbourne API. The API returns a single float as a string with the current value in µg/m3.
The wiring is very similar to the previous blog post, except we include an extra LED connected to D3 and D4 on the NodeMCU.
The code
The NodeMCU has support for WiFi built in thanks to it’s ESP8266 chip, so it’s very easy to go online in our in setup()
loop() function we poll for values every 30 seconds. We turn these values into floats and compare our snapshot against the WHO annual guidelines limits, and UK annual legal limits. If we’re below WHO and UK limits, we show green. If we’re above WHO limits, but below UK limits, we show amber. If we’re above both WHO and UK limits, we show red.
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> // Wifi connection details const char* ssid = "Wifi Network"; const char* password = "Wifi Password"; // Poll URLs const char* PM10_URL = "http://api.eastbourneair.com/readings/906088-pm10"; const char* PM25_URL = "http://api.eastbourneair.com/readings/906088-pm25"; // How often to poll the website for updates (in microseconds) const int POLL_DELAY = 30000; // Limits for particulates from the WHO and UK. // These are annual limits. const float WHO_PM10 = 20.0; const float WHO_PM25 = 10.0; const float UK_PM10 = 40.0; const float UK_PM25 = 25.0; // The TriColour LEDs are wired to the following pins int redPinPM10 = D2, greenPinPM10 = D1; int redPinPM25 = D3, greenPinPM25 = D4; void setup () { pinMode(redPinPM10, OUTPUT); pinMode(redPinPM25, OUTPUT); pinMode(greenPinPM10, OUTPUT); pinMode(greenPinPM25, OUTPUT); Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to Wifi..."); } } void loop() { if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status HTTPClient http; //Declare an object of class HTTPClient Serial.println("Getting PM10 data..."); http.begin(PM10_URL); //Specify request destination int httpCode = http.GET(); //Send the request if (httpCode > 0) { //Check the returning code String payload = http.getString(); //Get the request response payload Serial.println(payload); //Print the response payload int reading = payload.toFloat(); digitalWrite(redPinPM10, LOW); digitalWrite(greenPinPM10, LOW); if (reading >= WHO_PM10 && reading < UK_PM10) { // turn the LED if over WHO limits, but under UK Serial.println("Over WHO guidelines "); digitalWrite(redPinPM10, HIGH); digitalWrite(greenPinPM10, HIGH); } else if (reading >= UK_PM10) { // turn the LED on if over UK limits Serial.println("Over UK limits"); digitalWrite(redPinPM10, HIGH); } else { Serial.println("under limit"); digitalWrite(greenPinPM10, HIGH); } } else { Serial.println("Unable to get data from API"); } http.end(); //Close connection Serial.println("Getting PM2.5 data..."); http.begin(PM25_URL); //Specify request destination httpCode = http.GET(); //Send the request if (httpCode > 0) { //Check the returning code String payload = http.getString(); //Get the request response payload Serial.println(payload); //Print the response payload int reading = payload.toFloat(); digitalWrite(redPinPM25, LOW); digitalWrite(greenPinPM25, LOW); if (reading >= WHO_PM25 && reading < UK_PM25) { // turn the LED if over WHO limits, but under UK Serial.println("Over WHO guidelines "); digitalWrite(redPinPM25, HIGH); digitalWrite(greenPinPM25, HIGH); } else if (reading >= UK_PM25) { // turn the LED on if over UK limts Serial.println("Over UK limits"); digitalWrite(redPinPM25, HIGH); } else { Serial.println("under limit"); digitalWrite(greenPinPM25, HIGH); } } else { Serial.println("Unable to get data from API"); } http.end(); //Close connection } else { Serial.println("Not connected to Wifi"); } delay(POLL_DELAY); // wait before we poll again. }