#include <DHT.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
// === CONFIGURACIÓN DE PINES ===
#define DHTPIN 2
#define DHTTYPE DHT22
#define LDR1_PIN A0
#define LDR2_PIN A1
#define SERVO_PIN 9
#define LED_START_PIN 4
#define NUM_LEDS 8
#define IR_RECEIVER_PIN 11
#define BOTON_PIN 12
// === OBJETOS ===
DHT dht(DHTPIN, DHTTYPE);
Servo servo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
IRrecv receiver(IR_RECEIVER_PIN);
// === ESTADO DEL SISTEMA ===
bool sistemaActivo = true;
bool modoTest = false;
float tempDeseada = 25.0;
int zonaMuerta = 2;
int umbralLuz = 600;
void setup() {
Serial.begin(9600);
dht.begin();
servo.attach(SERVO_PIN);
pinMode(BOTON_PIN, INPUT_PULLUP);
receiver.enableIRIn(); // <-- ACTIVAMOS EL RECEPTOR IR COMO EN TU EJEMPLO
lcd.begin(16, 2);
lcd.backlight();
lcd.print("Iniciando...");
for (int i = 0; i < NUM_LEDS; i++) {
pinMode(LED_START_PIN + i, OUTPUT);
}
delay(2000);
lcd.clear();
}
void loop() {
if (digitalRead(BOTON_PIN) == LOW) {
sistemaActivo = !sistemaActivo;
delay(500);
}
// === RECEPCIÓN IR COMO TU EJEMPLO ===
if (receiver.decode()) {
manejarBotonIR(receiver.decodedIRData.command);
receiver.resume(); // ← prepara próxima lectura
}
if (!sistemaActivo) {
modoStandby();
return;
}
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int luz1 = analogRead(LDR1_PIN);
int luz2 = analogRead(LDR2_PIN);
int diff = abs(luz1 - luz2);
// Reintento de lectura DHT si da NaN
if (isnan(temp) || isnan(hum)) {
delay(2000);
temp = dht.readTemperature();
hum = dht.readHumidity();
}
if (isnan(temp) || isnan(hum)) {
errorLCD("Fallo DHT");
return;
}
if (diff > 200) {
errorLCD("LDR desync");
return;
}
// Control servo
if (temp < tempDeseada - zonaMuerta) {
servo.write(0);
} else if (temp > tempDeseada + zonaMuerta) {
servo.write(180);
} else {
servo.write(90);
}
if (modoTest) {
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(LED_START_PIN + i, (i % 2 == 0) ? HIGH : LOW);
}
delay(500);
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(LED_START_PIN + i, (i % 2 != 0) ? HIGH : LOW);
}
delay(500);
return;
}
int luz = map(luz1, 0, 1023, 0, 100);
int ledsEnc = map(luz, 0, 100, NUM_LEDS, 0);
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(LED_START_PIN + i, (i < ledsEnc) ? HIGH : LOW);
}
// Mostrar en LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp, 1);
lcd.print("C H:");
lcd.print(hum, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Luz:");
lcd.print(luz);
lcd.print("%");
// Serial simula monitoreo IP
Serial.print("DATA|T:");
Serial.print(temp);
Serial.print("|H:");
Serial.print(hum);
Serial.print("|L:");
Serial.println(luz);
}
// === GESTIÓN DE COMANDOS IR (Basado en tu ejemplo funcional) ===
void manejarBotonIR(uint8_t cmd) {
switch (cmd) {
case 162: // POWER
sistemaActivo = !sistemaActivo;
Serial.println("IR: POWER → Sistema ON/OFF");
break;
case 2: // PLUS
umbralLuz += 50;
Serial.print("IR: PLUS → Umbral luz: ");
Serial.println(umbralLuz);
break;
case 152: // MINUS
umbralLuz -= 50;
Serial.print("IR: MINUS → Umbral luz: ");
Serial.println(umbralLuz);
break;
case 34: // TEST
modoTest = !modoTest;
Serial.println("IR: TEST → Modo test ON/OFF");
break;
default:
Serial.print("IR: Botón no asignado. Código: ");
Serial.println(cmd);
}
}
// === FUNCIONES AUXILIARES ===
void modoStandby() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo STANDBY");
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(LED_START_PIN + i, LOW);
}
servo.write(90);
}
void errorLCD(String msg) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("! ERROR !");
lcd.setCursor(0, 1);
lcd.print(msg);
Serial.println("ERROR| " + msg);
delay(3000);
}