Display Covid19 Data (Malaysia) on Dot Matrix Using ESP32

Grab Covid19 data and display it on Dot Matrix!

Introduction

Everyday we will got update from KKM (Kementerian Kesihatan Malaysia) regarding Covid19 data in Malaysia via social media like Facebook, Instagram, Twitter and Telegram. In this tutorial, we will try to improve this NTP clock so that it can grab the Covid19 data and display it on Dot Matrix. Before that, please read the following tutorial first.

Video

This video shows how to display Covid19 data (Malaysia) on dot matrix using ESP32.

Hardware Preparation

This is the list of items used in the video.

OR

Sample Program

This is the sample program to display Covid19 data (Malaysia) on dot matrix using ESP32. Before that, you need to install 3 libraries:

  1. MD_MAX72XX by majicDesigns Version 3.2.1 (Library Manager)
  2. MD_Parola by majicDesigns Version 3.3.0 (Library Manager)
  3. NTPClient by Fabrice Weinberg Version 3.1.0 (ZIP file)
/*
Tutorial: Covid19 Data (Malaysia) Display Using ESP32 and Dot Matrix
Hardware:
– Node32 Lite
https://my.cytron.io/p-node32-lite-wifi-and-bluetooth-development-kit?tracking=idris
– 4 In 1 MAX7219 Dot Matrix Display Module
https://my.cytron.io/p-4-in-1-max7219-dot-matrix-display-module?tracking=idris
External libraries:
– MD_MAX72XX by majicDesigns Version 3.2.1 (Library Manager)
– MD_Parola by majicDesigns Version 3.3.0 (Library Manager)
– NTPClient by Fabrice Weinberg Version 3.1.0 (https://github.com/taranais/NTPClient/archive/master.zip)
Created by:
27 Apr 2020 Idris Zainal Abidin, Cytron Technologies
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char ssid[] = "Your WiFi SSID";
const char password[] = "Your WiFi Password";
const char url[] = "https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/Coronavirus_2019_nCoV_Cases/FeatureServer/1/query?where=Country_Region%20%3D%20%27MALAYSIA%27&outFields=Confirmed,Recovered,Deaths&returnGeometry=false&outSR=4326&f=json";
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
#define MAX_DEVICES 4
#define CLK_PIN 25 // 18 or 25
#define DATA_PIN 27 // 16 or 27
#define CS_PIN 26 // 17 or 26
MD_Parola DotMatrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
#define LED 2
#define SW1 39
#define SW2 36
uint8_t scrollSpeed = 50; // default frame delay value
textEffect_t scrollEffect = PA_SCROLL_LEFT;
textPosition_t scrollAlign = PA_LEFT;
uint16_t scrollPause = 3000; // in milliseconds
long currentMillis = 0;
long previousMillis = 0;
int count, interval = 1000;
String formattedDate, timeStamp, covidText;
String hour, minute, second;
String year, month, date;
char covidTextBuffer[] = "";
enum {TIME, DATE, CONFIRM, RECOVER, DEATH};
int displayMode = TIME;
int confirmed, recovered, deaths;
boolean covidStatus = false;
void setup()
{
pinMode(LED, OUTPUT);
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
digitalWrite(LED, HIGH); // Turn off LED
Serial.begin(115200);
DotMatrix.begin();
DotMatrix.setIntensity(0);
DotMatrix.setTextAlignment(PA_CENTER);
DotMatrix.print("");
delay(2000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println(F(""));
Serial.println(F("WiFi connected."));
Serial.println(F("IP address: "));
Serial.println(WiFi.localIP());
timeClient.begin();
timeClient.setTimeOffset(28800); // Set offset time in seconds, GMT+8 = 28800
updateCovid();
displayMode = DEATH;
DotMatrix.displayClear();
DotMatrix.displayText("Covid Clock by Idris", scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}
void loop()
{
while (!timeClient.update()) {
timeClient.forceUpdate();
}
currentMillis = millis();
if (currentMillis – previousMillis > interval) {
previousMillis = millis();
if (displayMode == TIME) {
// The formattedDate comes with the following format:
// 2018-05-28T16:00:13Z
formattedDate = timeClient.getFormattedDate();
Serial.println(formattedDate);
// Extract time
hour = formattedDate.substring(11, 13);
minute = formattedDate.substring(14, 16);
second = formattedDate.substring(17, 19);
if (hour.toInt() == 0) {
hour = String(hour.toInt() + 12);
}
else if (hour.toInt() < 13) {
hour = String(hour.toInt());
}
else {
hour = String(hour.toInt() – 12);
}
Serial.println(hour + ":" + minute + ":" + second);
if (second.toInt() == 0) {
if (minute.toInt() == 0 ||
minute.toInt() == 10 ||
minute.toInt() == 20 ||
minute.toInt() == 30 ||
minute.toInt() == 40 ||
minute.toInt() == 50) {
covidStatus = true;
}
else {
// Extract date
// year = formattedDate.substring(0, 4);
// month = formattedDate.substring(5, 7);
// date = formattedDate.substring(8, 10);
timeStamp = formattedDate.substring(8, 10) + "" +
formattedDate.substring(5, 7);
displayMode = DATE;
}
}
else if (second.toInt() % 2) {
timeStamp = hour + ":" + minute;
}
else {
timeStamp = hour + " " + minute;
}
DotMatrix.setTextAlignment(PA_CENTER);
DotMatrix.print(timeStamp);
}
else if (displayMode == DATE) {
count++;
if (count == 5) {
count = 0;
displayMode = TIME;
}
}
}
if (digitalRead(SW1) == LOW || covidStatus == true) {
covidStatus = false;
DotMatrix.displayClear();
updateCovid();
covidText = "Confirmed: " + String(confirmed);
covidText.toCharArray(covidTextBuffer, covidText.length() + 1);
DotMatrix.displayText(covidTextBuffer, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
displayMode = CONFIRM;
}
if (displayMode == CONFIRM && DotMatrix.displayAnimate()) {
DotMatrix.displayReset();
covidText = "Recovered: " + String(recovered);
covidText.toCharArray(covidTextBuffer, covidText.length() + 1);
DotMatrix.displayText(covidTextBuffer, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
displayMode = RECOVER;
}
if (displayMode == RECOVER && DotMatrix.displayAnimate()) {
DotMatrix.displayReset();
covidText = "Deaths: " + String(deaths);
covidText.toCharArray(covidTextBuffer, covidText.length() + 1);
DotMatrix.displayText(covidTextBuffer, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
displayMode = DEATH;
}
if (displayMode == DEATH && DotMatrix.displayAnimate()) {
DotMatrix.displayReset();
displayMode = TIME;
}
}
void updateCovid()
{
Serial.println();
HTTPClient http;
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) { // Check for the returning code
String payload = http.getString();
char charBuf[500];
payload.toCharArray(charBuf, 500);
Serial.println(payload);
const size_t capacity = JSON_ARRAY_SIZE(1) +
JSON_ARRAY_SIZE(5) +
JSON_OBJECT_SIZE(1) +
2 * JSON_OBJECT_SIZE(2) +
JSON_OBJECT_SIZE(5) +
4 * JSON_OBJECT_SIZE(6) +
2 * JSON_OBJECT_SIZE(7) + 711;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, payload);
JsonArray fields = doc["fields"];
JsonObject attributes = doc["features"][0]["attributes"];
confirmed = attributes["Confirmed"];
recovered = attributes["Recovered"];
deaths = attributes["Deaths"];
Serial.println("Confirmed case: " + String(confirmed));
Serial.println("Recovered: " + String(recovered));
Serial.println("Deaths: " + String(deaths));
Serial.println();
digitalWrite(LED, LOW); // Turn on LED
}
else {
Serial.println();
Serial.println("Error on HTTP request");
digitalWrite(LED, HIGH); // Turn off LED
}
http.end();
}

Thank You

References:

Thanks for reading this tutorial. If you have any technical inquiries, please post at Cytron Technical Forum.

Please be reminded, this tutorial is prepared for you to try and learn.
You are encouraged to improve the code for better application.

Leave a Comment

Your email address will not be published.

Share this Tutorial

Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest
Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest

Latest Tutorial

BLTouch Installation for Ender 3 with 32-bit V4.2.2 Board
Pick and Send Random Meal’s Option and Locations through Telegram Bot Using Grove WiFi 8266 on micro:bit
DIY Automated Vacuum Cleaner Using REKA:BIT With Micro:bit
Rainbow Spark in Mini House using Maker Uno.
TinyML on Arduino using Edge Impulse
Tutorials of Cytron Technologies Scroll to Top