// Learn about the ESP32 WiFi simulation in
// https://docs.wokwi.com/guides/esp32-wifi
#include <WiFi.h>
#include <MD_Parola.h>
#include <Ticker.h>
#include <sys/time.h> // struct timeval
#include <time.h> // time() ctime()
#include <map>
#include <memory>
constexpr auto updateInterval { 500 };
// ---- GPIO Pins ----
std::map<const char*, uint8_t> gpio{
{"SCLK", 18}, // GPIO 18
{"csPin", 5}, // GPIO 5
{"MOSI", 23}, // GPIO 23
};
// ---- LED Matrix Display ----
// GPIO NodeMCU Name | MAX7219
// ===================================
// 12 D6 MISO | CS
// 13 D7 MOSI | DIN
// 15 D8 SS | Not connected
// 14 D5 SCK | CLK
constexpr auto hardwareType { MD_MAX72XX::PAROLA_HW };
constexpr uint8_t numDevices { 4 };
uint8_t slimColonChar[] { 1, 36 };
uint8_t slimSpaceChar[] { 1, 0 };
uint8_t serifedOneChar[] { 3, 66, 127, 64 };
uint8_t niceSevenChar[]{ 5, 1, 1, 121, 5, 3 };
uint8_t niceZeroChar[]{ 5, 62, 65, 65, 65, 62 };
// Hardware SPI connection
MD_Parola display { MD_Parola{ hardwareType, gpio["csPin"], numDevices} };
constexpr uint8_t scrollSpeed { 30 }; // default frame delay value
constexpr textEffect_t scrollEffect { PA_SCROLL_LEFT };
constexpr textPosition_t scrollAlign { PA_LEFT };
constexpr uint16_t scrollPause { 1 * 1000 }; // in milliseconds
// ---- Setup ----
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println(F("--- Starting ---"));
display.begin();
// the destructor will stop the ticker when it goes out of scope
Ticker animateTicker;
animateTicker.attach_ms(10, []() {
if (display.displayAnimate()) {
display.displayReset();
}
});
char scrollText[60] { "Connecting" };
display.displayText(scrollText, scrollAlign, scrollSpeed, scrollPause,
scrollEffect, scrollEffect);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
configTime(0, 0, "pool.ntp.org");
setenv("TZ"," <+07>-7",1);
tzset();
Serial.println(F("Starting Clock"));
display.setTextAlignment(PA_CENTER);
display.addChar(149, slimColonChar);
display.addChar(150, slimColonChar);
display.addChar(151, slimSpaceChar);
display.addChar(152, slimSpaceChar);
display.addChar('1', serifedOneChar);
display.addChar('7', niceSevenChar);
display.addChar('0', niceZeroChar);
static Ticker clockTicker;
clockTicker.attach_ms(updateInterval, []() {
static uint32_t blink { 0 };
const auto now = time(nullptr);
const auto tm = localtime(&now);
constexpr char slimColon{149}, nbSpace{151};
uint32_t hour = ((tm->tm_hour % 12) != 0) ? tm->tm_hour % 12 : 12;
char timeStr[24]; // large because of the lack of width for hour
sprintf(timeStr, "%d%c%02d", hour, slimColon + blink, tm->tm_min);
strncat(timeStr, &nbSpace, 1);
strcat(timeStr, (tm->tm_hour < 12) ? "A" : "P");
display.print(timeStr);
blink = (blink+ 1) % 4;
});
}
void loop() {
}