#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <DHT.h>
#include <SPI.h>
#include <Wire.h>
#include "Font7Seg.h"
// Definições de Hardware para ESP32
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW // Geralmente FC16 para módulos comuns
#define MAX_DEVICES 4
// Pinos sugeridos para ESP32 (Hardware SPI)
#define CLK_PIN 18
#define DATA_PIN 23
#define CS_PIN 5
#define SPEED_TIME 75
#define PAUSE_TIME 0
#define MAX_MESG 20
// RTC DS1307
#define DS1307_ADDRESS 0x68
// DHT22
#define DHTPIN 4 // Alterado para GPIO 4
#define DHTTYPE DHT22
#define TIMEDHT 1000
// Variáveis globais
uint8_t wday, mday, month, year;
uint8_t hours, minutes, seconds;
char szTime[9];
char szMesg[MAX_MESG + 1] = "";
float humidity, celsius;
uint8_t degC[] = {6, 3, 3, 56, 68, 68, 68 };
uint8_t clear = 0x00;
uint32_t timerDHT = 0;
DHT dht(DHTPIN, DHTTYPE);
// No ESP32, usamos a assinatura simplificada para Hardware SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void beginDS1307() {
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(clear);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
if (Wire.available()) {
seconds = bcdToDec(Wire.read());
minutes = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read() & 0x3F); // Ajuste para formato 24h
wday = bcdToDec(Wire.read());
mday = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
}
}
uint8_t decToBcd(uint8_t value) { return ((value / 10 * 16) + (value % 10)); }
uint8_t bcdToDec(uint8_t value) { return ((value / 16 * 10) + (value % 16)); }
void getTime(char *psz, bool f = true) {
sprintf(psz, "%02d%c%02d", hours, (f?':': ' '), minutes);
}
void getDate(char *psz) {
char szBuf[10];
sprintf(psz, "%d %s %04d", mday, mon2str(month, szBuf, sizeof(szBuf) - 1), (year + 2000));
}
void getTemperature() {
if ((millis() - timerDHT) > TIMEDHT) {
timerDHT = millis();
humidity = dht.readHumidity();
celsius = dht.readTemperature();
if (isnan(humidity) || isnan(celsius)) {
Serial.println("Erro no DHT!");
}
}
}
// No ESP32, strings em flash funcionam de forma diferente. Simplificado:
const char* mon2str(uint8_t mon, char *psz, uint8_t len) {
const char* str[] = {"Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"};
strncpy(psz, str[mon - 1], len);
psz[len] = '\0';
return psz;
}
const char* dow2str(uint8_t code, char *psz, uint8_t len) {
const char* str[] = {"Domingo", "Segunda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado"};
strncpy(psz, str[code - 1], len);
psz[len] = '\0';
return psz;
}
void setup(void) {
Serial.begin(115200);
Wire.begin(21, 22); // SDA, SCL específicos do ESP32
P.begin();
P.setInvert(false);
P.addChar('$', degC);
// Zonas para o display
P.setZone(0, 0, MAX_DEVICES - 1);
dht.begin();
}
void loop(void) {
static uint32_t lastTime = 0;
static uint8_t display = 0;
static bool flasher = false;
beginDS1307();
getTemperature();
if (P.displayAnimate()) {
switch (display) {
case 0: // Temperatura
dtostrf(celsius, 3, 1, szMesg);
strcat(szMesg, "$");
P.displayText(szMesg, PA_CENTER, SPEED_TIME, 2000, PA_SCROLL_LEFT, PA_SCROLL_UP);
display++;
break;
case 1: // Umidade
dtostrf(humidity, 3, 0, szMesg);
strcat(szMesg, "%UR");
P.displayText(szMesg, PA_CENTER, SPEED_TIME, 2000, PA_SCROLL_DOWN, PA_SCROLL_LEFT);
display++;
break;
case 2: // Relógio
if ((millis() - lastTime) >= 1000) {
lastTime = millis();
getTime(szMesg, flasher);
flasher = !flasher;
}
P.setFont(numeric7Seg);
P.displayText(szMesg, PA_CENTER, 0, 5000, PA_PRINT, PA_NO_EFFECT);
if (seconds == 0) display++;
break;
case 3: // Dia da semana
P.setFont(nullptr);
dow2str(wday, szMesg, MAX_MESG);
P.displayText(szMesg, PA_CENTER, SPEED_TIME, 2000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display++;
break;
default: // Calendário
getDate(szMesg);
P.displayText(szMesg, PA_CENTER, SPEED_TIME, 2000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display = 0;
break;
}
}
}