#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <SPI.h>
#include <SD.h>
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
#define GAS_PIN A0
#define RL_VALUE 5.0
#define RO_CLEAN_AIR_FACTOR 9.83
const int greenLedPin = 4; // Pin para el LED verde
const int yellowLedPin = 5; // Pin para el LED amarillo
const int redLedPin = 6; // Pin para el LED rojo
File dataFile;
const int SD_CS_PIN = 10;
void setup() {
Serial.begin(9600);
dht.begin();
lcd.begin(16, 2);
lcd.backlight();
pinMode(greenLedPin, OUTPUT);
pinMode(yellowLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
if (!rtc.begin()) {
Serial.println("No se pudo encontrar el módulo RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC perdió poder, ajustando la hora!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Inicializa la tarjeta SD utilizando los pines por defecto
if (SD.begin(SD_CS_PIN)) {
Serial.println("Tarjeta SD lista.");
} else {
Serial.println("Error al iniciar la tarjeta SD.");
while (1);
}
}
void loop() {
float temperatura = dht.readTemperature();
float humedad = dht.readHumidity();
int gasValue = obtenerNivelGas();
DateTime now = rtc.now();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(int(temperatura));
lcd.print("C H:");
lcd.print(int(humedad));
lcd.print("% G:");
lcd.print(gasValue);
// Centra la fecha y la hora en 16 columnas
lcd.setCursor(5 / 2, 1);
lcd.print(now.timestamp(DateTime::TIMESTAMP_TIME));
lcd.print(" ");
lcd.print(now.day());
lcd.print("/");
lcd.print(now.month());
// Controlar LEDs según el nivel de gas
controlarLeds(gasValue);
Serial.print(now.timestamp(DateTime::TIMESTAMP_FULL));
Serial.print(", Temp: ");
Serial.print(temperatura);
Serial.print("C, Humedad: ");
Serial.print(humedad);
Serial.print("%, Gas: ");
Serial.print(gasValue);
Serial.println();
guardarDatosEnSD(now, temperatura, humedad, gasValue);
delay(100);
}
int obtenerNivelGas() {
int rawValue = analogRead(GAS_PIN);
float voltage = rawValue * (5.0 / 1023.0); // Convertir a voltios (típicamente 5V)
// Ajustar la fórmula según las características del MQ-7
float ratio = voltage / 5.0; // Relación entre el voltaje y la alimentación
float ppm = (ratio - 0.1) / 0.3 * 10000.0; // Fórmula típica para MQ-7, ajustar según la documentación
// Ajustar el rango a 0-31 para la matriz LED
return constrain(map(int(ppm), 0, 10000, 0, 31), 0, 31);
}
void controlarLeds(int gasValue) {
// Ajusta estos valores según el umbral deseado para cambiar de color
int umbralAmarillo = 15;
int umbralRojo = 30;
if (gasValue < umbralAmarillo) {
digitalWrite(greenLedPin, HIGH);
digitalWrite(yellowLedPin, LOW);
digitalWrite(redLedPin, LOW);
} else if (gasValue >= umbralAmarillo && gasValue < umbralRojo) {
digitalWrite(greenLedPin, LOW);
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
} else {
digitalWrite(greenLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
digitalWrite(redLedPin, HIGH);
}
}
void guardarDatosEnSD(DateTime timestamp, float temperatura, float humedad, int gasValue) {
dataFile = SD.open("datos.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(timestamp.timestamp(DateTime::TIMESTAMP_FULL));
dataFile.print(", Temp: ");
dataFile.print(temperatura);
dataFile.print("C, Humedad: ");
dataFile.print(humedad);
dataFile.print("%, Gas: ");
dataFile.print(gasValue);
dataFile.println();
dataFile.close();
} else {
Serial.println("Error al abrir el archivo en la tarjeta SD.");
}
}