#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4
#define CS_PIN 10
#define DHTPIN A0 // Pin donde está conectado el DHT22
#define DHTTYPE DHT22 // DHT 22 (AM2302)
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastTimeUpdate = 0;
unsigned long lastTempUpdate = 0;
const unsigned long timeInterval = 1000; // Actualizar la hora cada 1 segundo
const unsigned long tempInterval = 3000; // Actualizar la temperatura cada 3 segundos
void setup() {
Serial.begin(9600);
mx.begin();
mx.control(MD_MAX72XX::INTENSITY, 0); // Ajustar la intensidad del display (0-15)
mx.clear(); // Limpiar el display
// Iniciar RTC
if (!rtc.begin()) {
Serial.println("No se pudo encontrar RTC");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC no está funcionando, ajustando la hora...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Iniciar DHT
dht.begin();
}
void loop() {
// Recibe y muestra la información por el puerto serie
receiveSerialData();
// Actualizar la hora cada `timeInterval`
if (millis() - lastTimeUpdate >= timeInterval) {
lastTimeUpdate = millis();
DisplayTime();
}
// Actualizar la temperatura cada `tempInterval`
if (millis() - lastTempUpdate >= tempInterval) {
lastTempUpdate = millis();
DisplayTemperature();
}
}
void DisplayTime() {
mx.clear();
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
char buffer[6];
snprintf(buffer, sizeof(buffer), "%02d%02d", hour, minute); // Sin dos puntos para ahorrar espacio
// Desplegar caracteres con tamaño reducido
for (int i = 0; i < 4; i++) {
printSmallChar(i * 6, buffer[i]);
}
mx.update();
Serial.print("Hora actual: ");
Serial.println(buffer);
}
void DisplayTemperature() {
mx.clear();
float temperature = dht.readTemperature();
Serial.print("Temperatura leída: ");
Serial.println(temperature);
if (isnan(temperature)) {
const char *errorText = "Err";
for (int i = 0; i < 3; i++) {
printSmallChar(i * 6, errorText[i]);
}
} else {
char buffer[6];
snprintf(buffer, sizeof(buffer), "%4.1f", temperature); // No incluimos "C" para ahorrar espacio
for (int i = 0; i < 4; i++) {
printSmallChar(i * 6, buffer[i]);
}
}
mx.update();
}
void printSmallChar(int offset, char c) {
// Definición de caracteres pequeños
static const uint8_t smallNumbers[][3] = {
{0x3E, 0x51, 0x3E}, // 0
{0x00, 0x7F, 0x00}, // 1
{0x4E, 0x51, 0x31}, // 2
{0x49, 0x49, 0x36}, // 3
{0x78, 0x08, 0x7F}, // 4
{0x79, 0x49, 0x4F}, // 5
{0x3E, 0x49, 0x4F}, // 6
{0x60, 0x1F, 0x00}, // 7
{0x36, 0x49, 0x36}, // 8
{0x70, 0x49, 0x3E} // 9
};
if (c >= '0' && c <= '9') {
for (int i = 0; i < 3; i++) {
mx.setColumn(offset + i, smallNumbers[c - '0'][i]);
}
} else if (c == '.') {
mx.setColumn(offset, 0x80); // Punto
} else if (c == 'C') {
mx.setColumn(offset, 0x39); // C para Celsius (letra simplificada)
} else if (c == '-') {
mx.setColumn(offset, 0x40); // Guion (-)
}
}
void receiveSerialData() {
if (Serial.available()) {
char startChar = Serial.read();
if (startChar == '>') {
int hour = Serial.parseInt();
int minute = Serial.parseInt();
float temperature = Serial.parseFloat();
int receivedChecksum = Serial.parseInt();
char endChar = Serial.read();
int calculatedChecksum = (int)('>') + hour + minute + (int)temperature;
Serial.print("Calculado: ");
Serial.println(calculatedChecksum);
Serial.print("Recibido: ");
Serial.println(receivedChecksum);
if (endChar == '<' && receivedChecksum == calculatedChecksum) {
Serial.println("Datos recibidos correctamente:");
Serial.print("Hora: ");
Serial.println(hour);
Serial.print("Minuto: ");
Serial.println(minute);
Serial.print("Temperatura: ");
Serial.println(temperature);
Serial.print("Checksum: ");
Serial.println(receivedChecksum);
Serial.println("------");
} else {
Serial.println("Error en la recepción de datos.");
}
}
}
}