martes, 12 de noviembre de 2024

Automatización de un invernadero

Trabajo de investigación de bachillerato

El curso 2023-2024 cuatro alumnos del Instituto Can Planas, Zhangxia Yan, Jesús Castarnado, Hug Niubó y Manel García, realizaron un proyecto en torno a la automatización de un invernadero para el control de sus condiciones de temperatura y humedad. 

Como sensores utilizaron el sensor de luz UV LTR 390 de Adafruit con comunicación por I2C, el sensor digital de temperatura y humedad DHT22 y un sensor de humedad del suelo Gravity Capacitive soil moisture sensor v1.0.


Para el control de las condiciones ambientales del invernadero utilizaron tres actuadores: una tira de leds UV para aumentar la iluminación cundo el sensor detecta iluminación baja, una bomba de agua para el riego cuando la humedad del suelo es baja y un ventilador para aumentar el flujo de aire cuando la temperatura en el interior del invernadero es alta. Los tres actuadores los controlaron a través de relés con lógica inversa. Esto quiere decir que se activan con una señal LOW del microcontrolador Arduino y se desactivan con una señal HIGH. Por esta razón en la parte de configuración del programa (void setup) se sitúan los tres pines que controlan estos relés (3,4,5) en posición HIGH, para que queden desactivados.

El programa para el controlador Arduino es el siguiente:





El sensor LTR 390 de Adafruit se comunica con Arduino mediante un puerto I2C que tiene cuatro cables, dos para la alimentación eléctrica (rojo y negro), uno para el pin  SCL (amarillo) y otro para el pin SDA (azul).



Reconstrucción del invernadero

Con los materiales de este proyecto posteriormente hemos diseñado un modelo de invernadero más pequeño y manejable para realizar prácticas de programación. Los elementos impresos en 3D se pueden encontrar en Thingiverse.



El servo mueve un eje que atraviesa la ventanilla situada en la parte superior del tejado.



A continuación se puede ver el soporte para los dos sensores de luz e infrarrojos y de de temperatura y humedad.


Debajo de Arduino se han colocado los tres relés para accionar el ventilador, que funciona a 12 voltios, y la tira de leds.


El ventilador se encuentra situado sobre la pared opuesta a la puerta de entrada al invernadero.


A continuación se puede ver el nuevo soporte para el sensor de luz e infrarrojos.



Sensor de temperatura y humedad DHT22

A continuación podemos ver un programa creado para comprobar el funcionamiento del sensor DHT22 conectado en el pin 2.


El programa listado es el siguiente:

#include "DHT.h"

#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin (9600);
  dht.begin();
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  
}

Sensor de luz e infrarrojos LTR390

Configuración para medir nivel de infrarrojos

Ahora vamos a añadir un poco más de código para incluir el sensor LTR390uint32_t indica el tipo de variable de ltr_index. Esta variable ocupa 4 bytes en un número entero entre 0 y 4294967295.

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "Adafruit_LTR390.h"
Adafruit_LTR390 ltr = Adafruit_LTR390 ();

void setup() {
  Serial.begin (9600);
  dht.begin();
  ltr.begin();
  ltr.setMode(LTR390_MODE_UVS);
  ltr.setGain(LTR390_GAIN_3);
  ltr.setResolution(LTR390_RESOLUTION_16BIT);
  ltr.setThresholds (100, 1000);
  ltr.configInterrupt(true, LTR390_MODE_UVS);
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  
  uint32_t   ltr_index = ltr.readUVS();
  Serial.print("Valor UVS: ");
  Serial.println(ltr.readUVS());
  Serial.print("UV Index: ");
  Serial.println(ltr_index);
}

Con el programa anterior en la pantalla del ordenador el monitor del puerto serie nos muestra lo siguiente, cambiando cada dos segundos impuestos por el comando delay:

Temperatura: 19.30 ºC 
Humedad 52.60 %
Valor UVS: 0
UV Index: 0
Temperatura: 19.30 ºC 
Humedad 52.60 %
Valor UVS: 0
UV Index: 0
Temperatura: 19.30 ºC 
Humedad 52.50 %
Valor UVS: 0
UV Index: 0

Si retiramos en el sensor uno de los cables del puerto serie Arduino no puede identificar la información que no le llega y nos proporciona un mensaje de error, el número 4294967295. Nos devuelve el mismo valor de error si quitamos uno de los cables de alimentación (VIN o GND). 

Temperatura: 19.20 ºC 
Humedad 52.60 %
Valor UVS: 4294967295
UV Index: 4294967295
Temperatura: 19.20 ºC 
Humedad 52.60 %
Valor UVS: 4294967295
UV Index: 4294967295 

Si en el programa retiramos la línea ltr.begin(); nos vuelve a enviar el valor 4294967295 al no poner en marcha el sensor LTR390.

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "Adafruit_LTR390.h"
Adafruit_LTR390 ltr = Adafruit_LTR390 ();

void setup() {
  Serial.begin (9600);
  dht.begin();
  ltr.setMode(LTR390_MODE_UVS);
  ltr.setGain(LTR390_GAIN_3);
  ltr.setResolution(LTR390_RESOLUTION_16BIT);
  ltr.setThresholds (100, 1000);
  ltr.configInterrupt(true, LTR390_MODE_UVS);
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  
  uint32_t   ltr_index = ltr.readUVS();
  Serial.print("Valor UVS: ");
  Serial.println(ltr.readUVS());
  Serial.print("UV Index: ");
  Serial.println(ltr_index);
}

Ahora lo que obtenemos en el monitor del puerto serie también es:

Temperatura: 19.20 ºC 
Humedad 52.60 %
Valor UVS: 4294967295
UV Index: 4294967295
Temperatura: 19.20 ºC 
Humedad 52.60 %
Valor UVS: 4294967295
UV Index: 4294967295 

En el siguiente programa el condicional existente en el setup inicializa el sensor LTR390 y si no lo encuentra envía al monitor del puerto serie un mensaje indicando este particular.

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "Adafruit_LTR390.h"
Adafruit_LTR390 ltr = Adafruit_LTR390 ();

void setup() {
  Serial.begin (9600);
  dht.begin();
 
 if (!ltr.begin()) {
 Serial.println("El sensor LTR390 no está conectado");
  }

  ltr.setMode(LTR390_MODE_UVS);
  ltr.setGain(LTR390_GAIN_3);
  ltr.setResolution(LTR390_RESOLUTION_16BIT);
  ltr.setThresholds (100, 1000);
  ltr.configInterrupt(true, LTR390_MODE_UVS);
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  

  uint32_t   ltr_index = ltr.readUVS();
  Serial.print("Valor UVS: ");
  Serial.println(ltr.readUVS());
  Serial.print("UV Index: ");
  Serial.println(ltr_index);
}

En el caso de que el sensor LTR390 tenga algún problema veremos esto en el monitor del puerto serie:

El sensor LTR390 no está conectado
Temperatura: 19.50 ºC 
Humedad 50.40 %
Valor UVS: 4294967295
UV Index: 4294967295
Temperatura: 19.50 ºC 
Humedad 50.40 %
Valor UVS: 4294967295
UV Index: 4294967295

Configuración para medir nivel de luz

En la configuración del sensor LTR390 se ha de elegir el modo ALS que mide el nivel de luz del ambiente. Para medirlo se ha de usar el comando readALS.

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "Adafruit_LTR390.h"
Adafruit_LTR390 ltr = Adafruit_LTR390 ();

void setup() {
  Serial.begin (9600);
  dht.begin();
 
 if (!ltr.begin()) {
 Serial.println("El sensor LTR390 no está conectado");
  }

  ltr.setMode(LTR390_MODE_ALS);
  ltr.setGain(LTR390_GAIN_3);
  ltr.setResolution(LTR390_RESOLUTION_16BIT);
  ltr.setThresholds (100, 1000);
  ltr.configInterrupt(true, LTR390_MODE_UVS);
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  

  uint32_t   ltr_index = ltr.readALS();
  Serial.print("Valor ALS: ");
  Serial.println(ltr.readALS());
  Serial.print("ALS Index: ");
  Serial.println(ltr_index);
}

En el monitor del puerto serie se puede ver algo similar a esto:

Temperatura: 19.90 ºC 
Humedad 56.20 %
Valor ALS: 10
UV Index: 10
Temperatura: 19.90 ºC 
Humedad 56.20 %
Valor ALS: 15
ALS Index: 15

Programa para medir nivel de luz y de infrarrojos

En el siguiente programa se ha eliminado gran parte de la configuración del LTR390 y nos devuelve información del nivel de luz y de infrarrojos.

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "Adafruit_LTR390.h"
Adafruit_LTR390 ltr = Adafruit_LTR390 ();

void setup() {
  Serial.begin (9600);
  dht.begin();
  ltr.begin();
}

void loop() {
  delay(2000);
  float t = dht.readTemperature ();
  float h = dht.readHumidity();
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" ºC ");
  Serial.print("Humedad ");
  Serial.print(h);
  Serial.println(" %");  

  Serial.print("Valor LUZ: ");
  Serial.println(ltr.readALS());
  Serial.print("Valor UV: ");
  Serial.println(ltr.readUVS());
}

En el monitor del puerto serie se puede ver algo similar a esto:

Temperatura: 20.40 ºC 
Humedad 55.70 %
Valor LUZ: 21
Valor UV: 0
Temperatura: 20.40 ºC 
Humedad 55.70 %
Valor LUZ: 21
Valor UV: 0

Manejo del servo

Para abrir y cerrar la ventana situada en la parte superior del tejado se utiliza un servo conectado al pin 9 de Arduino.

Para probar el funcionamiento del servo se puede utilizar el siguiente programa que continuamente está moviendo el servo entre las posiciones 0, 90 y 180 con una espera de de un segundo entre cada posición:

#include <Servo.h>
Servo servoMotor;
 
void setup() {
  servoMotor.attach(9);
}
 
void loop() {
  servoMotor.write(0);
  delay(1000);
  servoMotor.write(90);
  delay(1000);
  servoMotor.write(180);
  delay(1000);
}

Utilización del interruptor

El interruptor de palanca está conectado al pin 8 de Arduino. Con el siguiente programa se puede conseguir que la secuencia de  movimientos del servo solamente se realice si está accionado el interruptor.

#include <Servo.h>
Servo servoMotor;
 
void setup() {
  pinMode(8, INPUT);
  servoMotor.attach(9);
}
 
void loop() {
  if(digitalRead(8)==HIGH){
  servoMotor.write(0);
  delay(1000);
  servoMotor.write(90);
  delay(1000);
  servoMotor.write(180);
  delay(1000);
  }
}

Uso de los relés

Ese modelo de relé utiliza lógica inversa, se activa cuando recibe una señal LOW de Arduino. Los tres relés de izquierda a derecha están conectados a los pines 6, 5 y 7.

El siguiente programa permite encender y apagar la tira de leds, conectada al relé accionado por el pin 5 de Arduino y el ventilador conectado por el relé accionado por el pin 7.

void setup() {
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop() {
  digitalWrite(5, LOW);
  delay(3000);
  digitalWrite(5, HIGH);
  delay(3000);
  digitalWrite(7, LOW);
  delay(3000);
  digitalWrite(7, HIGH);
  delay(3000);
}

Programas en Arduino Blocks

Mover el servo con el interruptor

El siguiente programa mueve el servo entre 0º y 180º cuando se acciona el interruptor.


En el momento de cargar el programa surgió una dificultad. El programa que tenía cargado Arduino anteriormente era el del apartado anterior de accionamiento de los relés y parece que al estar en funcionamiento estos impedía la carga del nuevo programa desde Arduino Blocks. Para resolverlo cargué un nuevo programa desde el IDE de Arduino en donde no hubiese nada en funcionamiento. Después de esto se cargó sin problemas el programa desde Arduino Blocks.

Medida de la temperatura y la humedad

El siguiente programa toma los datos de temperatura y humedad del detector DHT-22 y los envía por el puerto serie para poderlos ver en la pantalla del ordenador.


Control del servo con la temperatura

El siguiente programa toma los datos de temperatura y humedad del detector DHT-22 y los envía por el puerto serie para poderlos ver en la pantalla del ordenador. A su vez una estructura condicional mueve el servo de la aleta de ventilación entre dos posiciones en función de si la temperatura sobrepasa o no los 24º.









No hay comentarios: