#include <DHT.h>
#include <SD.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 17, 2);

int MantaPin = 3;
int VentiladorPin = 4;
int humidPin = 5;

int tempMin = 15;
int tempMax = 30;
int humMin = 60;
int humMax = 80;

long d=1; long horas=0;
long mes=1; long mins=0;
long a=2023; long segs=0;

const int chipSelect = A0;  // Pin CS conectado a A0
File dataFile;
// Define los pines del teclado matricial y la matriz de caracteres para las teclas del teclado
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {A3, A2, A1, 10};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);


unsigned long previousTDPVHMillis = 0;
unsigned long previousFyHMillis = 0; 
unsigned long previousSDMillis = 0;
const long intervalTDPVH = 10000;
const long intervalFyH = 5000;
const long intervalSD = 60000*30 ;
bool showFyH = true;  

void setup() {
  pinMode(MantaPin, OUTPUT);
  pinMode(VentiladorPin, OUTPUT);
  pinMode(humidPin, OUTPUT);
  dht.begin();
  Serial.begin(9600);
  while (!Serial) {
    ;  // Esperar a que el puerto serie se abra
  }
  Serial.println("Iniciando tarjeta SD...");

  // Verificar si la tarjeta SD está presente y se puede inicializar:
  if (!SD.begin(chipSelect)) {
    Serial.println("La tarjeta SD no se pudo inicializar");
    return;
  }
  Serial.println("Tarjeta SD lista.");
  lcd.init();                      // Inicializa la pantalla
  lcd.backlight();                 // Enciende la retroiluminación
}

void loop() {
  unsigned long currentMillis = millis(); // obtiene el tiempo actual en milisegundos
  if (currentMillis - previousTDPVHMillis >= intervalTDPVH) { // comprueba si ha pasado el intervalo de tiempo
    previousTDPVHMillis = currentMillis; // actualiza el tiempo transcurrido
   

    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();
    float DPV= (611 * pow(2.718281828, (17.27 * temperature) / (237.3 + temperature)) - ((((611 * pow(2.718281828, (17.27 * temperature) / (237.3 + temperature))) * humidity) / 100)));
    String maxymin =String(tempMin) + "  " + String(tempMax) + "    " + String(humMin) + "  " + String(humMax);
    String TDPVH = " " + String(temperature,1) + " " + String(DPV,0) + "  " + String(humidity,1) + "  ";
    
    if (!isnan(temperature) && !isnan(humidity)) { // comprueba si los valores son válidos
     digitalWrite(MantaPin, temperature > tempMin ? HIGH : LOW);
     digitalWrite(VentiladorPin, temperature <= tempMax && humidity < humMax ? HIGH : LOW);
     digitalWrite(humidPin, humidity > humMin ? HIGH : LOW);
    }
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(maxymin);

    lcd.setCursor(0, 1);
    lcd.print(TDPVH);
        
  }
 
 if (currentMillis - previousFyHMillis >= intervalFyH) {
    previousFyHMillis = currentMillis;
    
    segs=segs+(intervalFyH/1000);
    if(segs>=56)    {mins= mins + 1;     segs = 0;}
    if (mins>=60)   {horas = horas + 1;  mins = 0;}
    if (horas>=24)  {d = d + 1;          horas = 0;}
    if (d>30)       {mes = mes + 1;      d = 0;}
    if (mes>12)     {a = a + 1;          mes = 1;  d = 1;}

    // Alterna la variable para mostrar o no mostrar el mensaje "Hola"
    if (showFyH) {
    String FechayHora =String(d) + "/" + String(mes) + "/" + String(a) + " " + String(horas) + ":" + String(mins) + ":" +String(segs);    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Fecha y Hora");
    lcd.setCursor(0, 1);
    lcd.print(FechayHora);
    } 
    showFyH = !showFyH;
  }
    
  if (currentMillis - previousSDMillis >= intervalSD) { // comprueba si ha pasado el intervalo de tiempo
    previousSDMillis = currentMillis; // actualiza el tiempo transcurrido
   
    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();
    float DPV= (611 * pow(2.718281828, (17.27 * temperature) / (237.3 + temperature)) - ((((611 * pow(2.718281828, (17.27 * temperature) / (237.3 + temperature))) * humidity) / 100)));
    String maxymin =String(tempMin) + "  " + String(tempMax) + "    " + String(humMin) + "  " + String(humMax);
    String FechayHora =String(d) + "/" + String(mes) + "/" + String(a) + "  " + String(horas) + ":" + String(mins) + ":" +String(segs);    
   
    dataFile = SD.open("datos.txt", FILE_WRITE);
    if (dataFile) {
     dataFile.print(FechayHora);
     dataFile.print(",");
     dataFile.print(temperature);
     dataFile.print(",");
     dataFile.print(humidity);
     dataFile.print(",");
     dataFile.print(DPV);
     dataFile.print(",");
     dataFile.print(DPV/10);
     dataFile.print(",");
     dataFile.println(maxymin);
     
     Serial.print(FechayHora);
     Serial.print(",");
     Serial.print(temperature);
     Serial.print(",");
     Serial.print(humidity);
     Serial.print(",");
     Serial.print(DPV);
     Serial.print(",");
     Serial.print(DPV/10);
     Serial.print(",");
     Serial.println(maxymin);
     dataFile.close();
     //Serial.println("Datos escritos en la tarjeta SD.");
    } else {
     Serial.println("Error al escribir en la tarjeta SD.");
    }
  }
  // Lee las entradas del teclado matricial
 char key = keypad.getKey();
 if (key != NO_KEY) {
 switch (key) {
   case '1':
    tempMin--;
    break;
   case '2':
    tempMin++;
    break;
   case '3':
    tempMax--;
    break;
   case 'A':
    tempMax++;
    break;
   case '4':
    humMin--;
    break;
   case '5':
    humMin++;
    break;
   case '6':
    humMax--;
    break;
   case 'B':
    humMax++;
    break;
   case '7':
    d++;
    break;
   case '8':
    mes++; 
    break;
   case '9':
    a++;
    break;
   case 'C':
    horas++;
    break;
   case '*':
    mins++;
    break;
   case '0':
    segs=0;
    break;
  }
  }
}
$abcdeabcde151015202530354045505560fghijfghij