Código:
#include <DHT11.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define sensorLl 4
#define sensorHR 5
#define bomba 9 //TIENE LOGICA NEGADA, CON UN CERO LO HAGO CONMUTAR AL RELE.
#define ventilador 10 //TIENE LOGICA NEGADA, CON UN CERO LO HAGO CONMUTAR AL RELE.
#define rojo 11
#define verde 12
#define azul 13
volatile bool situacion1 = LOW;
volatile bool situacion2 = LOW;
unsigned long tiempo = 0;
boolean comprobacion; //PARA VER SI ESTA O NO LLOVIENDO.
unsigned int humedadSuelo;
float temp;
DHT11 dht11(sensorHR);
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); //Dirección del LCD para usarse en el protocolo I2C y números que indican que pines debe usar la librería para el LCD.
//SCL -> A5
//SDA -> A4
byte grado[8] = //Array para añadir el caracter 'º' en el LCD.
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
void setup() {
//DECLARACIÓN DE INTERRUPCIÓN PARA LOS DOS PULSADORES:
attachInterrupt(0, lecturaPulsador2, RISING); //SE DISPARA CUANDO PASO DE LOW A HIGH, ES DECIR, CUANDO PULSO. INTERRUPCION CERO QUE CORRESPONDE AL PIN 2
attachInterrupt(1, lecturaPulsador1, RISING); //SE DISPARA CUANDO PASO DE LOW A HIGH, ES DECIR, CUANDO PULSO. INTERRUPCION CERO QUE CORRESPONDE AL PIN 3
//NO DEFINIMOS EL PIN 3 COMO ENTRADA PUESTO QUE EN EL DATA SHEET VEMOS QUE EL PIN DATA DEL SENSOR ES BIDIRECCIONAL, PUESTO QUE ES EL MICRO QUIEN DA LA SEÑAL CUANDO HAY ERROR.
//Entradas:
pinMode(A2, INPUT); //Leeré LDR.
pinMode(A1, INPUT); //Leeré el sensor de Humedad del Suelo.
pinMode(A0, INPUT); //Leeré el LM35
pinMode(sensorLl, INPUT);
//bomba:
pinMode(bomba, OUTPUT);
//Ventilador:
pinMode(ventilador, OUTPUT);
//RGB:
pinMode(rojo, OUTPUT);
pinMode(verde, OUTPUT);
pinMode(azul, OUTPUT);
Serial.begin(9600);
//INICIALIZACIÖN DEL LCD:
lcd.begin (16,2); // Inicializar el display con 16 caraceres 2 lineas
lcd.clear(); //Borramos lo que pueda haber anteriormente.
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH); //Estas dos últimas líneas son para darle luz a la pantalla.
lcd.createChar(1, grado); //Para el caracter grado.
}
void loop() {
lcd.clear(); //Para limpiar lo que estaba antes y no se escriba lo nuevo a mostrar encima de lo que estaba..
//Pulsador 1: //VOY A HACERLO CON UNA INTERRUPCIÓN, PUESTO QUE EL CAMBIO ES BASTANTE MÁS RÁPIDO.
//Pulsador 2: //ESTE PULSADOR TIENE PRIORIDAD, PUESTO QUE CON EL VAMOS A REALIZAR UNA PARADA DEL SISTEMA.
//Ventilador:
LM35();
if (temp >= 25) digitalWrite(ventilador, LOW);
else digitalWrite(ventilador, HIGH);
//Comprobamos si esta lloviendo y vemos que si esta lloviendo es seguro que desactivo la bomba. Si no llueve la activaré dependiendo del valor de la humedad del suelo.
HSuelo();
if ((comprobacion == HIGH) && (humedadSuelo <= 50)) digitalWrite(bomba, LOW); //SI NO ESTA LLOVIENDO Y LA HUMEDAD ES INFERIOR AL 50%, ACTIVO LA BOMBA.
else digitalWrite(bomba, HIGH);
if (situacion2 == LOW){
if (situacion1 == LOW){ //Si no pulso pulsador 1, comenzaré mostrando la temperatura.
//Ya hice la llamda a la función LM_35() arriba.
lcd.setCursor ( 0, 0 );
lcd.print("Temp:"); //Por defecto escribo en la columna 0, fila 0
lcd.setCursor ( 6, 0 ); //Columna 0, fila 1.
lcd.print(temp);
lcd.setCursor ( 11, 0 );
lcd.write(1);
lcd.print("C");
//Ahora muestro el porcentaje de humedad relativa del aire en el LCD.
Luminosidad();
}
else {
//Simplemente vamos a mostrar los valores.
HumedadRelativa();
//Para representar la humedad del suelo en el LCD:
lcd.setCursor (0, 1);
lcd.print("HumedadSuelo: ");
lcd.setCursor (13, 1);
lcd.print(humedadSuelo);
lcd.setCursor(15, 1);
lcd.print("%");
}
}
else { //EN ESTA SITUACION TENGO QUE PARAR LOS ACTUADORES.
lcd.setCursor ( 3, 0 );
lcd.print("SOLUCIONAR"); //ESTO NO ES NECESARIO QUE LO META DENTRO DEL WHILE PORQUE MIENTRAS NO LIMPIE LA PANTALLA DEL LCD SE QUEDA LO ULTIMO MOSTRADO.
lcd.setCursor ( 3, 1);
lcd.print("EMERGENCIA");
digitalWrite(bomba, HIGH); //LO APAGO POR SI EN EL MOMENTO DE PULSAR EL BOTÓN DE EMERGENCIA ESTABA ENCENDIDO.
digitalWrite(ventilador, HIGH);
while (situacion2 == HIGH){RGB();} //MIENTRAS ESTÉ EN LA SITUACIÓN DE EMERGENCIA NO QUIERO RECOGER EL ESTADO DEL PULSADOR 1, ASÍ CUANDO SALGA DE LA EMERGENCIA SEGUIRE MOSTRANDO LO QUE ESTABA EN EL LCD ANTES DE PRODUCIRSE AUNQUE MIENTRAS TANTO PULSE P1.
}
delay(1000);
}
void lecturaPulsador1() {
if ( millis() > tiempo + 250){
situacion1 = !situacion1;
tiempo = millis();
}
}
void lecturaPulsador2() { //RUTINA DE SERVICIO DE INTERRUPCION. CUANDO PULSO EL BOTON DE EMERGENCIA ES CUANDO ENTRO.
if ( millis() > tiempo + 250){
situacion2 = !situacion2;
tiempo = millis();
}
}
void LM35() {
unsigned int lectura = analogRead(A0); //Leo entre 0 y 1023.
float voltaje = ((lectura * 5.0) / 1023) * 1000; //lectura en mV
temp = voltaje / 10; //En grados centígrados.
//VISUALIZACIÓN POR EL MONITOR SERIE:
Serial.print("Temperatura: ");
Serial.print(temp);
Serial.println();
}
void HumedadRelativa(){
float humedad, temperatura;
int error = dht11.read(humedad, temperatura); //La lectura será correcta cuando el error sea cero.
unsigned long HR = humedad; //LO HAGO ASI PARA QUITARME LA PARTE DECIMAL QUE SON TODO CEROS.
if (error == 0){
//LCD:
lcd.setCursor(0, 0);
lcd.print("HumedadAire: "); //Por defecto escribo en la columna 0, fila 0
lcd.setCursor ( 13, 0 ); //Columna 0, fila 1.
lcd.print(HR);
lcd.setCursor ( 15, 0 );
lcd.print("%");
//Puerto Serie:
//Serial.print("Temperatura: ");
//Serial.println(temperatura);
Serial.print("Humedad Aire: ");
Serial.println(humedad);
}
else Serial.println("Error en la medicion");
}
void Luminosidad(){ //DIVISOR DE TENSION CON RESISTENCIA PULL DOWN.
unsigned int LDR = analogRead(A2);
float porcentaje = (LDR * 100.0) / 1023;
//LCD:
lcd.setCursor(0, 1);
lcd.print("Lux: "); //Por defecto escribo en la columna 0, fila 0
lcd.setCursor ( 5, 1 ); //Columna 0, fila 1.
lcd.print(porcentaje);
lcd.setCursor ( 9, 1 );
lcd.print("%");
//Puerto Serie:
Serial.print("Porcentaje: ");
Serial.print(porcentaje);
Serial.println("%");
}
void sensorLluvia(){
comprobacion = digitalRead(sensorLl); //TIENE LÓGICA INVERSA. DA LOW CUANDO DETECTA LLUVIA.
if (comprobacion == LOW) Serial.println("Está lloviendo");
else Serial.println("No está lloviendo");
}
void HSuelo(){
sensorLluvia(); //HAGO LA LLAMADA AQUI PORQUE LA ACTIVACIÓN DE LA BOMBA ME DEPENDERÁ DE SI ESTA LLOVIENDO O NO, Y EN FUNCION DEL VALOR DE LA HUMEDAD.
//SI EL SUELO ESTA COMPLETAMENTE SECO, LA LECTURA ES DE 1023. SI ESTA COMPLETAMENTE MOJADO, LA LECTURA ES DE 0.
unsigned int leido = analogRead(A1);
//VAMOS A DAR EL PORCENTAJE DE HUMEDAD DEL SUELO:
humedadSuelo = (100.0 * leido) / 1023;
humedadSuelo = 100 - humedadSuelo; //LO HAGO ASÍ PORQUE ME INTERESA EL PORCENTAJE DE HUMEDAD, NO DE SEQUEDAD.
Serial.print("Humedad del suelo: ");
Serial.print(humedadSuelo);
Serial.println("%");
}
void RGB(){
digitalWrite(rojo, HIGH);
delay(500);
digitalWrite(rojo, LOW);
digitalWrite(verde, HIGH);
delay(500);
digitalWrite(verde, LOW);
digitalWrite(azul, HIGH);
delay(500);
digitalWrite(azul, LOW);
}