ESP8266 Real-time COVID-19 Datamonitor
|
Als je dan toch thuis moet zitten door COVID-19, dan is er tijd genoeg om te knutselen. De vorige keer gingen we aan de slag met een ESP32, deze keer experimenteren we met een ESP8266 microcontroller. Deze ESP8266 Real-time COVID-19 datamonitor is vergelijkbaar met de ESP32 COVID-19 CORONA Tracker. Wederom maken we gebruik van de data van de Coronavirus Disease (COVID-19) GIS Hub en programmeren we een kleine “sketch” in de Arduino IDE. In dit artikel gebruik ik de ESP-WROOM-02 (van VNGSystems in Gouda) maar je kunt natuurlijk elk ander ESP8266-ontwikkelbord gebruiken.


Arduino IDE & Arduino core for ESP8266
Allereerst moet de Arduino IDE op je computer geïnstalleerd zijn. Heb je dat nog niet gedaan, lees dan het artikel “De Arduino IDE installeren op Windows 10”. Gebruik je Linux, kees dan “Installeer of upgrade nieuwste Arduino IDE op Linux”.
Eveneens moet de “Arduino core for ESP8266 WiFi chip” geïnstalleerd zijn. Zie het hoofdstuk “De ESP8266 Arduino core installeren” in de blog “ESP8266 NodeMcu met Arduino IDE op Linux“. De procedure is voor Linux en Windows hetzelfde.
ESP8266 Real-time COVID-19 datamonitor met ESP-WROOM-02
Gebruik je ook de ESP-WROOM-02 voor dit project, lees dan het artikel “WEMOS D1 Esp-Wroom-02 met Arduino IDE“. Hierin kun je lezen hoe je naast het bovenstaande ook de ThingPulse ESP8266 OLED SSD1306 library en de Brzo I2C Library kunt installeren voor het display.
ArduinoJson library
Als laatste heb je nog de ArduinoJson-library nodig. Die kun je installeren met de library manager in de Arduino IDE.
Coronavirus Disease (COVID-19) GIS Hub API
Vervolgens hebben we natuurlijk de gegevens nodig. Die zijn bijvoorbeeld te vinden op de website Coronavirus Disease (COVID-19) GIS Hub. Door middel van de API-Explorer op die website kun je de juiste query-URL voor de REST-API samenstellen. Hoe je dit kunt doen kun je lezen in de blog COVID-19 CORONA Tracker: ESP32 & Arduino IDE.


Het resultaat is een URL zoals deze:
https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/Coronavirus_2019_nCoV_Cases/FeatureServer/1/query?where=Country_Region%20like%20'%25SWEDEN%25'&outFields=Last_Update,Confirmed,Deaths,Recovered&returnGeometry=false&outSR=4326&f=json
Dat levert dan de volgende JSON-data op:
{ "objectIdFieldName": "OBJECTID", "uniqueIdField": { "name": "OBJECTID", "isSystemMaintained": true }, "globalIdFieldName": "", "geometryType": "esriGeometryPoint", "spatialReference": { "wkid": 4326, "latestWkid": 4326 }, "fields": [ { "name": "Last_Update", "type": "esriFieldTypeDate", "alias": "Last Update", "sqlType": "sqlTypeOther", "length": 8, "domain": null, "defaultValue": null }, { "name": "Confirmed", "type": "esriFieldTypeInteger", "alias": "Confirmed", "sqlType": "sqlTypeOther", "domain": null, "defaultValue": null }, { "name": "Deaths", "type": "esriFieldTypeInteger", "alias": "Deaths", "sqlType": "sqlTypeOther", "domain": null, "defaultValue": null }, { "name": "Recovered", "type": "esriFieldTypeInteger", "alias": "Recovered", "sqlType": "sqlTypeOther", "domain": null, "defaultValue": null } ], "features": [ { "attributes": { "Last_Update": 1585416253000, "Confirmed": 3069, "Deaths": 105, "Recovered": 16 } } ] }
ArduinoJson Assistant code generator
De code die nodig is om de JSON-data in te lezen kunnen we genereren met de online “ArduinoJson Assistant“. Plak de JSON-data die we hierboven gegenereerd hebben in de Assistant, en de website genereert de programmacode.


Van die code nemen we de noodzakelijke regels over, en de regel met “deserializeJson” passen we aan, zoals hieronder aangegeven:
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 3 * JSON_OBJECT_SIZE(6) + 2 * JSON_OBJECT_SIZE(7) + 690; DynamicJsonDocument doc(capacity); deserializeJson(doc, payload); JsonArray fields = doc["fields"]; JsonObject features_0_attributes = doc["features"][0]["attributes"];
Deze code is verwerkt in onderstaande sketch.
Certificate fingerprint
Als laatste hebben we nog de certificate fingerprint van se website nodig om een https-verbinding op te kunnen bouwen met de ESP8288. Voor de Google Chrome browser op Windows 10 kun je die als volgt vinden. Klik eerst op het slotje naast de URL. Kies dan in het dropdown-menu voor “Certificaat”.


Daarna klik je in het volgende venster op tabblad “Details” en scroll je naar beneden, naar “Vingerafdruk”. In het vak eronder zie je nu de vingerafdruk die je naar de sketch kunt knippen-plakken.


In de sketch ziet het er dan zo uit:
const char fingerprint[] PROGMEM = "70580e780c9d727550619d3e4efdb21d64d1e91e"; //SHA1 finger print
Deze regel zul je in onderstaande sketch terugvinden.
ESP8266 Real-time COVID-19 datamonitor Sketch
Al het bovenstaande wordt uiteindelijk in onderstaande sketch samengevoegd. Zoals gebruikelijk op dit blog, is dit slechts een voorbeeld. Gebruik het in je eigen project en maak er iets moois van!
Je kunt deze code ook van GitHub downloaden: https://github.com/oneguyoneblog/COVID-19-Corona-ESP8266
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <ESP8266HTTPClient.h> #include "SSD1306Brzo.h" #include <ArduinoJson.h> SSD1306Brzo display(0x3c, 5, 4); // Initialize OLED display const char* ssid = "yournetworkname"; const char* password = "yournetworkpassword"; const char* host = "services1.arcgis.com"; String request = "/0MSEUqKaxRlEPj5g/arcgis/rest/services/Coronavirus_2019_nCoV_Cases/FeatureServer/1/query?where=Country_Region%20like%20'%25SWEDEN%25'&outFields=Last_Update,Confirmed,Deaths,Recovered&returnGeometry=false&outSR=4326&f=json"; const int httpsPort = 443; const char fingerprint[] PROGMEM = "70580e780c9d727550619d3e4efdb21d64d1e91e"; //SHA1 finger print void setup() { Serial.begin(115200); Serial.print("Connecting"); delay(1000); WiFi.mode(WIFI_OFF); //Prevents reconnection issue delay(1000); WiFi.mode(WIFI_STA); //Station mode WiFi.begin(ssid, password); //Connect to WiFi display.init(); // Initialise the display display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont(ArialMT_Plain_16); display.drawString(0, 0, "Connecting"); display.display(); // Write the buffer to the display while (WiFi.status() != WL_CONNECTED) { // Wait for connection delay(500); Serial.print("."); } Serial.println(""); //If connection successful show IP address of ESP8266 in serial monitor Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { WiFiClientSecure httpsClient; //Declare object of class WiFiClient Serial.println(host); Serial.printf("Using fingerprint '%s'n", fingerprint); httpsClient.setFingerprint(fingerprint); httpsClient.setTimeout(15000); // 15 Seconds delay(1000); Serial.println("HTTPS Connecting"); int r = 0; //retry counter while ((!httpsClient.connect(host, httpsPort)) && (r < 30)) { delay(100); Serial.print("."); r++; } if (r == 30) { Serial.println("Connection failed"); } else { Serial.println("Connected"); } Serial.print("Requesting: "); Serial.println(host + request); httpsClient.print(String("GET ") + request + " HTTP/1.1rn" + "Host: " + host + "rn" + "Connection: closernrn"); Serial.println("Request sent"); while (httpsClient.connected()) { String line = httpsClient.readStringUntil('n'); if (line == "r") { Serial.println("Headers received"); break; } } Serial.println("Payload received:"); String payload; while (httpsClient.available()) { payload = httpsClient.readStringUntil('n'); //Read Line by Line Serial.println(payload); //Print response } Serial.println("Closing connection"); char charBuf[500]; payload.toCharArray(charBuf, 500); const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 3 * JSON_OBJECT_SIZE(6) + 2 * JSON_OBJECT_SIZE(7) + 690; DynamicJsonDocument doc(capacity); deserializeJson(doc, payload); JsonArray fields = doc["fields"]; JsonObject features_0_attributes = doc["features"][0]["attributes"]; String Confirmed = features_0_attributes["Confirmed"]; String Deaths = features_0_attributes["Deaths"]; String Recovered = features_0_attributes["Recovered"]; long Last_Update = features_0_attributes["Last_Update"]; // not used yet display.clear(); // Clear OLED display display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont(ArialMT_Plain_16); display.drawString(0, 0, "Conf: " + Confirmed); display.drawString(0, 24, "Dead: " + Deaths); display.drawString(0, 48, "Recv: " + Recovered); display.display(); // Write the buffer to the display delay(60000); }
Ook zonder
1 const char fingerprint[] PROGMEM = “70580e780c9…”
2 Serial.printf(“Using fingerprint ‘%s’n”, fingerprint);
3 httpsClient.setFingerprint(fingerprint);
werkt het gewoon. Dat fingerprintgedoe is overbodig, probeer maar. 🙂