// Proyecto 1 Control Eléctrico
// Control Automatico de Sistema de Aire Acondicionado
// Grupo XX : Jose Macías , Jennifer Jones, Alexander López, Iván Moya
//Instalar las librerias
#include <DHT.h> // importa la Librerias DHT
#include <DHT_U.h>
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 RTC;
//Entradas y Declaracion de Variables
int SENSOR = 4; // pin DATA de DHT22 a pin digital 2
int TEMPERATURA;
int HUMEDAD;
DHT dht(SENSOR, DHT22); // creacion del objeto, cambiar segundo parametro
// por DHT11 si se utiliza en lugar del DHT22
bool ocuparAire = false;
int horaActivacion = 0; // Hora de activación del aire
int Aforo=0; //Ocupación de la Oficina
const int Entradas[2]={2,3}; // 2 Para Entrada, 3 Para Salida
boolean Compuertas[5]={false,false,false, false, false};
const int Salidas[8]={5,6,7,8,9,10,11,12};// Para el control del motor a pasos
boolean Hay_Personas = false;
boolean NoHay_Personas = false;
bool temperatureHigh = false;
//Comienza
void setup () {
Serial.begin(9600); // Establece la velocidad de datos del puerto serie
Wire.begin(); // Inicia el puerto I2C
RTC.begin(); // Inicia la comunicación con el RTC
// RTC.adjust(DateTime(__DATE__, __TIME__)); // Comentado para evitar configuración automática de hora
lcd.init();
lcd.backlight();
lcd.clear();
dht.begin(); // inicializacion de sensor
//Declarar Entradas y Salidas
for (int i=0; i<2; i++){
pinMode(Entradas[i], INPUT);
}
for(int i=0; i<8; i++){
pinMode(Salidas[i],OUTPUT);
}
// Preguntar al usuario si desea ocupar el aire
Serial.println("¿Desea ocupar el aire hoy? (responda 'si' o 'no')");
while (!Serial.available()); // Esperar respuesta del usuario
String respuesta = Serial.readStringUntil('\n');
if (respuesta == "si") {
ocuparAire = true;
Serial.println("¿A qué hora desea activar el aire? (en formato 24 horas, ej. 14:30)");
while (!Serial.available()); // Esperar respuesta del usuario
String horaStr = Serial.readStringUntil('\n');
// Convertir la hora ingresada en formato HH:MM a entero
int hora = horaStr.substring(0, 2).toInt();
int minuto = horaStr.substring(3).toInt();
horaActivacion = hora * 60 + minuto;
}
}
void loop(){
DateTime now = RTC.now(); // Obtiene la fecha y hora del RTC
Serial.print(now.year(), DEC); // Año
Serial.print('/');
Serial.print(now.month(), DEC); // Mes
Serial.print('/');
Serial.print(now.day(), DEC); // Día
Serial.print(' ');
Serial.print(now.hour(), DEC); // Horas
Serial.print(':');
Serial.print(now.minute(), DEC); // Minutos
Serial.print(':');
Serial.print(now.second(), DEC); // Segundos
Serial.println();
lcd.setCursor(0,0);
lcd.print("D:");
lcd.print(now.year(), DEC);
lcd.print("/");
lcd.print(now.month(), DEC);
lcd.print("/");
lcd.print(now.day(), DEC);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("T: ");
lcd.print(now.hour(), DEC);
lcd.print(":");
lcd.print(now.minute(), DEC);
lcd.print(":");
lcd.print(now.second(), DEC);
lcd.setCursor(12,0);
lcd.print("T(C):");
lcd.print(TEMPERATURA);
lcd.setCursor(12,1);
lcd.print("HR(%):");
lcd.print(HUMEDAD);
lcd.setCursor(12,2);
lcd.print("Aforo:");
lcd.print(Aforo);
// Funciones y Comandos
TEMPERATURA = dht.readTemperature();
temperatureHigh = TEMPERATURA >= 23; // obtencion de valor de temperatura
HUMEDAD = dht.readHumidity(); // obtencion de valor de humedad
Serial.print("Temperatura: "); // escritura en monitor serial de los valores
Serial.print(TEMPERATURA);
Serial.print(" Humedad: ");
Serial.println(HUMEDAD);
// Verifica si se ha detectado la entrada de una persona
if (digitalRead(Entradas[0]) == HIGH) {
Persona_Entra();
}
// Verifica si se ha detectado una salida
if (digitalRead(Entradas[1]) == HIGH) {
Persona_Sale();
}
Compuertas[0]=AND(Entradas[0],temperatureHigh);
digitalWrite(Salidas[2], Compuertas[0]);
Compuertas[1]=XOR(Entradas[0],temperatureHigh);
digitalWrite(Salidas[3],Compuertas[1]);
Compuertas[2]=NOR(Entradas[0], temperatureHigh);
digitalWrite(Salidas[4],Compuertas[2]);
if (ocuparAire) {
// Si se va a ocupar el aire, verificar si estamos a menos de 10 minutos de la hora de activación
int horaActual = now.hour() * 60 + now.minute();
if (horaActivacion - horaActual <= 10 && horaActivacion > horaActual) {
Serial.println("Apunto de Ocupar");
lcd.setCursor(0, 2);
lcd.print("Apunto de Ocupar");
Compuertas[3]=JK(Compuertas[1],Compuertas[2],Compuertas[3]);
digitalWrite(Salidas[5], Compuertas[3]);
} else if (horaActual == horaActivacion) {
Serial.println("Ocupado");
lcd.setCursor(0, 2);
lcd.print("Ocupado");
} else {
Serial.println("En espera");
lcd.setCursor(0, 2);
lcd.print("En espera");
}
} else {
Serial.println("En espera");
lcd.setCursor(0, 2);
lcd.print("En espera");
}
Compuertas[4]=OR(Compuertas[0],Compuertas[3]);// Este es un 1 logico para activar el motor
digitalWrite(Salidas[6],Compuertas[4]);
delay(100); // La información se actualiza cada 1 segundo
}
//Funciones
void Persona_Entra() {
if (Aforo < 30) { // Verifica que no se haya alcanzado el límite máximo
Aforo = Contador(true, false, Aforo); // Incrementa el contador
digitalWrite(Salidas[0],HIGH);
// Actualizar el valor de Aforo en la pantalla LCD
lcd.setCursor(12, 2); // Suponiendo que es la tercera línea (índice 2)
lcd.print("Aforo:");
lcd.print(Aforo);
} else {
Serial.println("Aula llena, no se permite la entrada.");
}
}
void Persona_Sale() {
if (Aforo > 0) { // Verifica que haya personas presentes para permitir la salida
Aforo = Contador(false, true, Aforo); // Decrementa el contador
digitalWrite(Salidas[1],HIGH);
// Actualizar el valor de Aforo en la pantalla LCD
lcd.setCursor(12, 2); // Suponiendo que es la tercera línea (índice 2)
lcd.print("Aforo:");
lcd.print(Aforo);
} else {
Serial.println("No hay personas en el aula, no se permite la salida.");
}
}
//Funciones Logicas
bool AND( bool C, bool T){
return C&&T;
}
bool OR (bool X, bool Y){
return X||Y;
}
bool NOR( bool X, bool Y){
return !(X||Y);
}
bool XOR(bool X, bool Y){
if(X^Y){
return true;
}
else {
return false;
}
}
int Contador(bool Sube, bool Baja, int Valor) {
if (Sube && Valor < 30) {
Valor++;
}
if (Baja && Valor > 0) {
Valor--;
}
return Valor;
}
bool JK(bool J, bool K, bool Q) {
return (J && !Q) || (!K && Q);
}