/*********************************************************************
* LED MATRIX HODINY + SCROLL INFO
* DS3231 + 4× FC-16 (MAX7219)
*********************************************************************/
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
/* ---------- HARDVÉR ---------- */
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
MD_Parola display(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
RTC_DS3231 rtc;
/* ---------- ČASY ---------- */
const unsigned long TIME_DURATION = 15000UL;
/* ---------- PREMENNÉ ---------- */
unsigned long lastClockStart = 0;
unsigned long lastBlink = 0;
bool showClock = true;
bool colonOn = true;
char timeBuf[6]; // HH:MM
char scrollBuf[64]; // dátum + deň + teplota
/* ---------- DNI ---------- */
const char *weekdayName[] = {
"Nedela", "Pondelok", "Utorok",
"Streda", "Stvrtok", "Piatok", "Sobota"
};
/* ---------- ZOBRAZENIE ---------- */
void showClockText()
{
display.displayClear();
display.setTextAlignment(PA_CENTER);
display.displayText(timeBuf, PA_CENTER, 0, 0,
PA_PRINT, PA_NO_EFFECT);
display.displayReset();
}
void showScrollText()
{
display.displayClear();
display.setTextAlignment(PA_LEFT);
display.displayText(scrollBuf, PA_LEFT,
25, 1500,
PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display.displayReset();
}
/* ---------- SERIAL ---------- */
void checkSerial()
{
if (!Serial.available()) return;
String cmd = Serial.readStringUntil('\n');
cmd.trim();
int h, m, d, mo, y;
if (sscanf(cmd.c_str(), "TIME %d:%d", &h, &m) == 2) {
DateTime now = rtc.now();
rtc.adjust(DateTime(now.year(), now.month(), now.day(), h, m, 0));
}
else if (sscanf(cmd.c_str(), "DATE %d.%d.%d", &d, &mo, &y) == 3) {
if (y < 100) y += 2000;
DateTime now = rtc.now();
rtc.adjust(DateTime(y, mo, d, now.hour(), now.minute(), 0));
}
}
/* ---------- SETUP ---------- */
void setup()
{
Serial.begin(9600);
Wire.begin();
rtc.begin();
display.begin();
display.setIntensity(5);
display.displayClear();
DateTime now = rtc.now();
sprintf(timeBuf, "%02d:%02d", now.hour(), now.minute());
showClockText();
lastClockStart = millis();
lastBlink = millis();
}
/* ---------- LOOP ---------- */
void loop()
{
bool animFinished = display.displayAnimate();
checkSerial();
DateTime now = rtc.now();
/* ---------- BLIKANIE DVOJBODKY ---------- */
if (showClock && millis() - lastBlink >= 1000UL) {
lastBlink = millis();
colonOn = !colonOn;
timeBuf[2] = colonOn ? ':' : ' ';
display.displayReset();
}
/* ---------- PRECHOD NA SCROLL ---------- */
if (showClock && millis() - lastClockStart >= TIME_DURATION) {
showClock = false;
float temp = rtc.getTemperature();
sprintf(scrollBuf, "%02d/%02d/%02d %s %.1fC",
now.day(), now.month(), now.year() % 100,
weekdayName[now.dayOfTheWeek()],
temp);
showScrollText();
}
/* ---------- NÁVRAT NA HODINY ---------- */
if (!showClock && animFinished) {
showClock = true;
sprintf(timeBuf, "%02d:%02d", now.hour(), now.minute());
colonOn = true;
showClockText();
lastClockStart = millis();
}
}