#include <WiFi.h>
#include <time.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
// #include <SPI.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// #include <ESPAsyncWebServer.h>
#include "font.h"
#define NTP_SERVER "europe.pool.ntp.org"
#define UTC_OFFSET 3600
#define UTC_OFFSET_DST 3600
#define ARDUINOJSON_DECODE_UNICODE 1
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
// #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
// #define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW
// #define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
// Define the number of devices we have in the chain and the hardware interface
#define MAX_DEVICES 4
#define CLK_PIN 18
#define DATA_PIN 23
#define CS_PIN 5
// HARDWARE SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// SOFTWARE SPI
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
// const char* ssid = "girusnet";
// const char* pass = "gnet9419";
char cas[10];
char date[30];
char weather[40];
char meniny[40];
char clouds[20];
uint8_t scrollSpeed = 30; // default frame delay value
textEffect_t scrollEffect = PA_NO_EFFECT;
// PA_SCROLL_LEFT PA_NO_EFFECT;
textPosition_t scrollAlign = PA_CENTER;
uint16_t scrollPause = 0; // in milliseconds
static uint32_t lastTime = 0;
uint32_t interval = 10000;
uint32_t led = 7;
static uint32_t dataTime = 0;
static uint16_t display = 0; // current display mode
static uint16_t msg = 0; // current msg mode
// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE 100
char curMessage[BUF_SIZE] = { "clock" };
void setup() {
Serial.begin(115200);
P.begin();
loadFont();
P.setIntensity(15);
// P.setInvert(true);
// P.setCharSpacing(0);
Serial.println("Connecting to WiFi");
// while (!makeWLAN()) {
// Serial.println("Cannot connect :(");
// delay(1000);
// }
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
Serial.print("#");
delay(250);
}
Serial.println("Connected");
Serial.println("Updating time...");
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
Serial.print("\n[Parola Matrix Display Clock]\n");
P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
// InitServer();
getData();
}
void loop() {
setLocalTime();
P.displayAnimate();
if (P.getZoneStatus(0)) {
switch (display) {
case 0: // Welcome
P.displayClear();
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
strcpy(curMessage, "Matrix Display Clock");
display++;
break;
case 1:
P.displayClear();
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
switch (msg) {
case 0: // Welcome
strcpy(curMessage, date);
msg++;
break;
case 1: // Welcome
strcpy(curMessage, meniny);
msg++;
break;
case 2: // Welcome
strcpy(curMessage, weather);
msg++;
break;
case 3: // Welcome
strcpy(curMessage, clouds);
msg++;
break;
}
display++;
break;
default: // Clock
P.setTextEffect(0, PA_NO_EFFECT, PA_NO_EFFECT);
strcpy(curMessage, cas);
display++;
break;
}
P.displayReset(0);
}
if (msg > 3) msg = 0;
// Serial.println(msg);
if (millis() - lastTime > interval) {
if (display > 2) display = 1;
lastTime = millis();
P.displayReset(0);
}
if (millis() - dataTime > 20 * 60 * 1000) {
dataTime = millis();
getData();
}
}
void setLocalTime() {
struct tm ti;
if (!getLocalTime(&ti)) {
Serial.println("Connection Error");
return;
}
static const char wday_name[][9] = {
"Nedela", "Pondelok", "Utorok", "Streda", "Stvrtok", "Piatok", "Sobota"
};
static const char mon_name[][10] = {
"Januar", "Februar", "Marec", "April", "Maj", "Jun",
"Jul", "August", "September", "Oktober", "November", "December"
};
// Serial.println(&ti, "%H:%M:%S %d.%m.%Y %Z");
// sprintf(cas, "%s %i.%s %.2i:%.2i", wday_name[ti.tm_wday], ti.tm_mday, mon_name[ti.tm_mon], ti.tm_hour, ti.tm_min);
sprintf(date, "%s %i.%s %i", wday_name[ti.tm_wday], ti.tm_mday, mon_name[ti.tm_mon], ti.tm_year + 1900);
if (ti.tm_sec % 2 == 0) {
sprintf(cas, "%.2i:%.2i.%.2i", ti.tm_hour, ti.tm_min, ti.tm_sec);
} else {
sprintf(cas, "%.2i %.2i.%.2i", ti.tm_hour, ti.tm_min, ti.tm_sec);
}
// Serial.println(cas);
}
void getData() {
HTTPClient http;
http.begin("http://girus.5xs.sk/jsonbox.php?lat=49.29&lon=21.26"); //HTTP
int httpCode = http.GET(); // httpCode will be negative on error
if (httpCode > 0) { // HTTP header has been send and Server response header has been handled
// Serial.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server
if (httpCode == HTTP_CODE_OK) {
String json = http.getString();
Serial.println(json);
StaticJsonDocument<20> obj;
DeserializationError error = deserializeJson(obj, json);
if (error) {
Serial.println("DeserializationError");
return;
}
String mes = obj["mes"];
String poc = obj["poc"];
float tep = obj["tep"];
const char *mnn = "********************";
mnn = obj["mnn"];
String ob1 = obj["ob1"];
sprintf(weather, "%s: %s %.1f $", mes, poc, tep);
sprintf(meniny, "Meniny: %s", mnn);
sprintf(clouds, "Oblacnost: %s", ob1);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
void loadFont() {
P.addChar('0', nula);
P.addChar('1', jeden);
P.addChar('2', dva);
P.addChar('3', tri);
P.addChar('4', styri);
P.addChar('5', pat);
P.addChar('6', sest);
P.addChar('7', sedem);
P.addChar('8', osem);
P.addChar('9', devet);
P.addChar(':', dbtka);
P.addChar('.', bdka);
P.addChar(' ', spc);
P.addChar('!', vnk);
P.addChar('$', degC);
P.addChar('&', degF);
}