Control de Aforo y Temperatura
Autores: Iván Acebedo Herrera, Daniel Requena Garrido y Alejandro Valor Cano.
Introducción
La idea surgió dada la situación actual de pandemia debido al COVID, y la cantidad de restricciones y controles que se han implantado desde el comienzo de la misma.
Por tanto, se nos ocurrió que nuestro proyecto podía ir enfocado por ese camino, y así construir un sistema de control de aforo y de temperatura, que pudiese instalarse en cualquier espacio, recinto, o aula, y que además fuese lo suficientemente económico para poder llegar a muchos espacios.
Funcionalidades
- Detección de movimiento de entrada y salida
- Detección de temperatura y humedad (esta última no está implementada, aunque el sensor lo permite)
- Mostrar información por pantalla
- Estado del aforo y de la temperatura mediante leds y un zumbador
Componentes
- 3 x Protoboards
- 1 x Placa Arduino UNO
- 3 x Leds rojos, amarillos y verdes
- Cables: 6,49€
- 1 x Pantalla LCD
- 1 x Sensor de temperatura y humedad (DHT11): 6,99€
- 1 x Sensor de movimiento PIR (HC-SR04): 9,99€
- 1 x Zumbador
- Caja
- 3 x Resistencias de 1KΩ
Precio total = 70€
Coste, sin contar los materiales que han sido prestado por la URJC y materiales reciclados que encontramos por casa = 23,47€
Hardware
En cuanto a la parte Hardware, para hacerlo más sencillo, lo hemos dividido en tres secciones, por tanto, en tres protoplacas. Las tres tienen su propio positivo y negativo, para así intentar simplificar el circuito, y no tener que utilizar cables muy largos. Comentar que las placas van pegadas a la base de la caja, para así evitar que se muevan al desplazar la caja, y por tanto, evitar que se desconecten cables o incluso se dañen componentes.
A continuación se muestra una imagen general del circuito:
En la parte superior, se han decidido colocar tanto el zumbador, como el sensor de temperatura y humedad, como los leds de colores (3 leds rojos, 3 leds amarillos y 3 leds verdes), como también uno de los sensores de movimiento PIR, con sus correspondientes resistencias, con el objetivo de proteger los componentes a largo plazo.
Los leds, así como la pantalla LCD, se pegaron a la tapa superior de la caja con cinta. Otra opción más resistente y fiable hubiera sido pegarlos con silicona caliente, pero al ser materiales que se nos proporcionaban desde la ETSII no queríamos dañarlos, por eso finalmente empleamos la cinta.
En la parte central, únicamente se han conectado el positivo y negativo provenientes de la placa Arduino, y el otro sensor de movimiento PIR.
Los sensores PIR se pegaron también con cinta a los laterales de la caja para asegurar que quedaban bien fijos, además de tener un agujero a medida para que entrasen a presión. Además, se cubrió estos con un pequeño tubo de cartón, para evitar que los sensores detectasen movimientos no deseados por los extremos, y sólo detectasen movimiento delante de ellos.
Además, algunos cables también fueron encintados a la caja para evitar que se movieran y se desconectasen.
Por último, en la parte inferior y en la tercera protoplaca se han realizado todas las conexiones necesarias para la pantalla LCD, que mostrará los datos sobre aforo y temperatura actuales.
Software
El código a usar en este caso es un lenguaje propio de Arduino, que está basado en C++. En nuestro caso, el código es el siguiente:
#include <LiquidCrystal.h>
#include <DHT.h>
//Crear el objeto LCD con los números correspondientes (rs, en, d4, d5, d6, d7)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
byte sensorpir1=11; //Pin del salida del sensor 1 que está como salida.
byte sensorpir2=12; //Pin del salida del sensor 2 que está como salida.
byte ledv=14; //LED VERDE
byte leda=15; //LED AMARILLO
byte ledr=16; //LED ROJO
int altavoz=19; // analogico
int contador=0;
int calibrationTime = 60;
//El momento en que el sensor emite un impulso bajo
long unsigned int lowIn1;
long unsigned int lowIn2;
//Cantidad de milisegundos que el sensor tiene que ser baja
//antes de asumir que todo el movimiento se ha detenido
long unsigned int pause = 5000;
boolean lockLow1 = true;
boolean lockLow2 = true;
boolean takeLowTime1;
boolean takeLowTime2;
float sinVal;
int toneVal;
void setup(){
Serial.begin(9600); //Configuramos la velocidad del monitor serial
pinMode(altavoz, OUTPUT);
// Inicializar el LCD con el número de columnas y filas del LCD
lcd.begin(16, 2);
// Escribimos el Mensaje en el LCD.
pinMode(sensorpir1, INPUT); //Declaramos pines E/S
pinMode(sensorpir2, INPUT); //Declaramos pines E/S
pinMode(ledv, OUTPUT);
pinMode(ledr, OUTPUT);
pinMode(leda, OUTPUT);
dht.begin(); // Comenzamos el sensor DHT
digitalWrite(sensorpir1, LOW);
digitalWrite(sensorpir2, LOW);
lcd.print("CALIBRANDO...");
// Tiempo de calibrado del sensor
for(int i = 0; i < calibrationTime; i++) {
delay(1000);
}
lcd.clear();
lcd.print("CALIBRADO!!");
delay(2000);
lcd.clear();
}
void loop(){
lcd.clear();
// Ubicamos el cursor en la primera posición(columna:0) de la primera línea(fila:0)
lcd.setCursor(0,0);
lcd.print("CONTADOR: ");
lcd.print(contador);
// Leemos la temperatura en grados centígrados
float temp = dht.readTemperature();
lcd.setCursor(0,1);
lcd.print("TEMP: ");
lcd.print(temp);
lcd.print((char)223);
lcd.print("C");
if(digitalRead(sensorpir1) == HIGH){
Serial.println("Movimiento 1 detectado");
contador++;
//lcd.clear();
if(lockLow1){ // Se asegura que esperamos una transición a LOW antes de cualquier salida adicional:
lockLow1 = false;
delay(50);
}
takeLowTime1 = true;
}
else if(digitalRead(sensorpir1) == LOW){
if(takeLowTime1){
lowIn1 = millis(); // guarda el tiempo de la transición de HIGH a LOW
takeLowTime1 = false; // asegurar que esto se hace solamente al inicio de una fase de baja
}
// Si el sensor es bajo por más de la pausa dada,
// suponemos que hay más movimientos que van a suceder
if(!lockLow1 && millis() - lowIn1 > pause){
lockLow1 = true;
delay(50);
}
}
if(digitalRead(sensorpir2) == HIGH){
Serial.println("Movimiento 2 detectado");
if(contador>0){
contador--;
}
//lcd.clear();
if(lockLow2){ // Se asegura que esperamos una transición a LOW antes de cualquier salida adicional:
lockLow2 = false;
delay(50);
}
takeLowTime2 = true;
}
else if(digitalRead(sensorpir2) == LOW){
if(takeLowTime2){
lowIn2 = millis(); // guarda el tiempo de la transición de HIGH a LOW
takeLowTime2 = false; // asegurar que esto se hace solamente al inicio de una fase de baja
}
// Si el sensor es bajo por más de la pausa dada,
// suponemos que hay más movimientos que van a suceder
if(!lockLow2 && millis() - lowIn2 > pause){
lockLow2 = true;
delay(50);
}
}
if(temp<26){
noTone(altavoz);
if(contador<3){
digitalWrite(ledv, HIGH);
digitalWrite(ledr, LOW);
digitalWrite(leda, LOW);
}
else if(contador>=3 && contador<5){
digitalWrite(ledv, LOW);
digitalWrite(ledr, LOW);
digitalWrite(leda, HIGH);
}
else{
for(int x=0;x<180;x++){
// convert degrees to radians then obtain sin value
sinVal = (sin(x*(3.1412/180)));
// generate a frequency from the sin value
toneVal = 2000+(int(sinVal*1000));
tone(altavoz, toneVal);
delay(2);
}
digitalWrite(ledr, HIGH);
digitalWrite(ledv, LOW);
digitalWrite(leda, LOW);
}
}
else {
tone(altavoz,2000);
digitalWrite(ledr, HIGH);
digitalWrite(ledv, LOW);
digitalWrite(leda, LOW);
}
// 2 segundo de delay
delay(2000);
}
Importante resaltar que, dentro de la parte de setup, además de hacerse las inicializaciones correspondientes, también se deja un tiempo (en este caso 1 minuto) para que los sensores se calibren correctamente. Esta información fue extraída del propio datasheet del componente.
Además, ya en la parte del loop, tras detectar algún movimiento por parte de los sensores, se procede a asegurar que se espera el tiempo adecuado para que la señal HIGH del sensor que ha detectado dicho movimiento, vuelve otra vez a LOW, y así poder empezar otra vez con el bucle. Si no se hiciese esto, podría ocurrir que el sensor, tras detectar movimiento, deja unos segundos la señal en HIGH, y si volviese a empezar de nuevo la parte de loop, daría lugar a detecciones «fantasma» o erróneas, puesto que la señal en HIGH correspondería al anterior movimiento y no a ninguno actual.
Por último, lo único que queda por hacer es activar las salidas de los leds o del zumbador, dependiendo el caso de uso en el que nos encontremos.
Casos de Uso
Destacar que dentro de todos los casos de uso siempre tiene prioridad la temperatura, es decir, si la temperatura supera el umbral que hemos establecido, da igual el aforo porque se activará el caso de uso de la temperatura por encima del umbral.
- Los sensores están calibrados y la temperatura está por debajo de la temperatura umbral. Además, el número de personas está muy por debajo del límite de aforo à En este caso se encienden los leds verdes.
- Los sensores están calibrados y la temperatura está por debajo de la temperatura umbral. Además, el número de personas está cercano al límite que se ha establecido à Se encienden los leds amarillos.
- Los sensores están calibrados y la temperatura está por debajo de la temperatura umbral. Además, el número de personas es igual o superior al límite establecido à Se encienden los leds rojos y el zumbador emite un sonido de alarma.
- Los sensores están calibrados y la temperatura está por encima de la temperatura umbral. En este caso, da igual el número de personas, que se activan los leds rojos y el zumbador emite un sonido de alarma distinto al de superar el límite de aforo.
Problemas encontrados
- Sensores de movimiento: Estos han causado algunos problemas en cuanto a precisión. Aún calibrándolos según el tiempo establecido en el datasheet del componente, no son del todo precisos y además tienen un delay considerable.
- Consistencia y fijación de los cables macho-hembra: Al tener algunos componentes como la pantalla LCD y los leds en la parte superior de la caja, hemos tenido que usar cables macho-hembra para llevarlos desde la base de la caja donde están las protoplacas, hasta dichos componentes.
Futuras funcionalidades
- Sistema de ventilación vinculado a la temperatura: Podría vincularse a un sistema de ventilación o refrigeración como un aire acondicionado, y así activar este en caso de superar una temperatura umbral.
- Información de estado a través de una página web: Podría también crearse una interfaz que diera soporte a una web o app móvil, desde la cual poder acceder a los datos de aforo y temperatura en tiempo real.
Vídeo del proyecto
En este vídeo se explica todo el proyecto en general, pasando por todos los apartados que hemos visto en este blog. Además, se muestran en vídeo los casos de uso que se han detallado anteriormente.