martes, 30 de mayo de 2023

Programa del huerto domótico.

 Programa de huerto domótico.

El hardware adquirido no sirve de nada si no se monta adecuadamente y se dota a arduino de un programa que, como un director de orquesta, sea capaz de hacer que todo funcione como se desea.
En este caso el programa se ha realizado leyendo diferentes fuentes que muestran cómo se maneja cada uno de los sensores que ha sido necesario utilizar, y componiendo un programa que no solo es capaz de leer cada una de las variables necesarias de los diferentes sensores, sino que también trata esos datos para tomar la decisión de regar o no según las mismas.
La siguiente es una imagen del programa que se ha escrito.

El programa entero es el que sigue:
// Programa realizado por Diego Bote para domotizar el huerto
// del IES Carolina Coronado de Almendralejo.
// El programa se escribe tomando de aquí y de allí por internet,
// retocando y creando lo que ha sido neceesario.


#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWirePin = 5;
OneWire oneWireBus(oneWirePin);
DallasTemperature sensors(&oneWireBus);
DeviceAddress Thermometer0 = { 0x28, 0x96, 0x92, 0xC3, 0x0D, 0x00, 0x00, 0x88 }; // 0x28, 0x94, 0xE2, 0xDF, 0x02, 0x00, 0x00, 0xFE };
// DeviceAddress outsideThermometer = { 0x28, 0xF2, 0xCE, 0xC4, 0x0D, 0x00, 0x00, 0xA5 }; //0x28, 0x6B, 0xDF, 0xDF, 0x02, 0x00, 0x00, 0xC0 };
DeviceAddress Thermometer1 = { 0x28, 0xE6, 0xDF, 0xDE, 0x0D, 0x00, 0x00, 0xB0 }; 

#include <DHT.h>//Incluyo la librería del sensor DHT11 de humedad y temperatura.
#include <Wire.h> // Incluyo la librería para usar I2C, esto es SDA y SCL.
////////////////////////////////Para la pantalla LCD
#include <LiquidCrystal_I2C.h> // Debe descargar la Libreria que controla el I2C
LiquidCrystal_I2C lcd(0x27, 20, 4); //SI no va, se puede poner 0x20 para probar
//el modulo es de 16 por 2. el protocolo es 0x27. si no va, probar con 0x20

//Pines del módulo I2C
//VCC GND SON LA TENSIÓN Y LA TIERRA
//SDA VA AL A4
//SCL VA AL A5

//////////////////////////Configuro pines y variables
int sensor0 = 2;//Pin 2 para el valor del sensor DHT11 del huerto 0
int sensor1 = 3;//Pin 3 para el valor del sensor DHT11 del huerto 1
int temp0, humedad0;//Configuro las variables de temperatura y humedad del DHT11 del huerto 0.
int temp1, humedad1;//Configuro las variables de temperatura y humedad del DHT11 del huerto 1.

//int boton = 4;//Pin 4 para activar manualmente la bomba // Ese botón no está.
// const int nivel = 9; //Pin 9 para medir el nivel de agua // Que no hay medidor de nivel de agua.
const int bomba1 = 13; //Pin 13 para la bomba1
const int bomba0 = 12; //Pin 12 para la bomba0
const int resis1 = 11; //Pin 11 para la resistencia calefactora 1
const int resis0 = 10; //Pin 10 para la resistencia calefactora 0
const int humedadsuelo0 = A0; //A0 para la humedad del suelo del huerto 0
const int humedadsuelo1 = A1; //A1 para la humedad del suelo del huerto 1

const int dry = 625; // value for dry sensor
const int wet = 239; // value for wet sensor
int tempminimasuelo = 18;

float tempC; // temperatura del sensor de tierra solicitado

DHT dht0 (sensor0, DHT11);//Configuro el modelo de DHT. Es el DHT11 del huerto 0
DHT dht1 (sensor1, DHT11);//Configuro el modelo de DHT. Es el DHT11 del huerto 1
// int botonest = 0; //Inicializamos a 0 el estado del boton // El botón de riego manual no está.

///////////////////////////////Parte de humedad suelo y riego

void setup()
{
  Serial.begin(9600);//Arrancamos el puerto serie a 9600
   sensors.begin();
  sensors.setResolution(Thermometer0, 10);
  sensors.setResolution(Thermometer1, 10);
  dht0.begin();//Arranco el sensor DHT11
  dht1.begin();//Arranco el sensor DHT11

  //Configuramos entradas y salidas
  pinMode(humedadsuelo0, INPUT);//Configuro humedadsuelo0 como entrada
  pinMode(humedadsuelo1, INPUT);//Configuro humedadsuelo1 como entrada
  pinMode(bomba0, OUTPUT);//Configuro bomba0 como salida
  pinMode(bomba1, OUTPUT);//Configuro bomba1 como salida
  pinMode(resis0, OUTPUT);//Configuro resis0 como salida
  pinMode(resis1, OUTPUT);//Configuro resis1 como salida
//  pinMode(nivel, INPUT);//Configuro el nivel de agua como entrada // No hay sensor de nivel de agua.
//  pinMode(boton, INPUT);//Configuro el boton como entrada // No hay botón de riego manual

  //Para la pantalla LCD
  lcd.init(); //Inicializamos el LCD
  lcd.backlight(); //Activamos la luz de fondo
  lcd.clear(); //Limpiamos lo que haya en pantalla
  lcd.setCursor(0, 0); //Iniciamos el cursor en el punto 0,0
}

void printTemperature(DeviceAddress deviceAddress)
{
//  float tempC = sensors.getTempC(deviceAddress);
  tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print(tempC);
   Serial.println(" ºC");
  }
}

void loop()
{

Serial.println("Leyendo temperaturas");
  sensors.requestTemperatures();
  
  Serial.print("Temperatura del suelo del huerto 0: ");
  printTemperature(Thermometer0);
  //Serial.print(sensors.getTempCByIndex(0));
  Serial.print("Temperatura del suelo del huerto 1: ");
  printTemperature(Thermometer1);
  //Serial.print(sensors.getTempCByIndex(1));
  Serial.println("-------");
  //delay(2000);
  
  int SensorValue0 = analogRead(humedadsuelo0);//Leo el valor de la humedad y lo meto en SensorValue0
  int SensorValue1 = analogRead(humedadsuelo1);//Leo el valor de la humedad y lo meto en SensorValue1
//Serial.print("Humedad del suelo del huerto 0: ");
//Serial.println(SensorValue0);
//Serial.print("Humedad del suelo del huerto 1: ");
//Serial.print(SensorValue1);
//  int SensorNivel = digitalRead(nivel); //Leo lo que marca el nivel de agua, pero no hay sensor para ello.
//  int botonest = digitalRead(boton);//Leo lo que marca el boton que no está puesto
  // digitalWrite(bomba, HIGH);
  // delay(2000);
  // digitalWrite(bomba, LOW);


//Convertir la humedad en %.
//  int sensorVal0 = analogRead(A0);
   int percentageHumidity0 = map(SensorValue0, wet, dry, 100, 0); 
   Serial.print("valor del sensor de humedad0: ");
   Serial.println(SensorValue0);
   //Serial.println("%");
   Serial.print("valor de porcentaje de humedad0: ");
   Serial.print(percentageHumidity0);
   Serial.println("%");
//  int sensorVal = analogRead(A0);
   int percentageHumidity1 = map(SensorValue1, wet, dry, 100, 0); 
   Serial.print("valor del sensor de humedad1: ");
   Serial.println(SensorValue1);
   Serial.print("valor de porcentaje de humedad1: "); 
   Serial.print(percentageHumidity1);
   Serial.println("%");
   
   //delay(1000);   


  //Leo los DHT11 y meto los valores de temperatura y humedad en las variables temp y humedad
  humedad0 = dht0.readHumidity();
  temp0 = dht0.readTemperature();
  humedad1 = dht1.readHumidity();
  temp1 = dht1.readTemperature();
   if (isnan(humedad0) || isnan(temp0) || isnan(humedad1) || isnan(temp1)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
    }
    

 // Compute heat index in Fahrenheit (the default)
//  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
//  float hic = dht.computeHeatIndex(t, h, false);

  /////Puerto serie
  //Imprimo por el puerto serie los valores de temperatura y humedad del DHT11
  Serial.print("Temperatura en el huerto 0: "); Serial.print(temp0);
  Serial.print("ºC.  Humedad en el huerto 0: "); Serial.print(humedad0); Serial.println("%");
  Serial.print("Temperatura en el huerto 1: "); Serial.print(temp1);
  Serial.print("ºC Humedad en el huerto 1: "); Serial.print(humedad1); Serial.println("%");

  //Imprimo por el puerto serie el valor de la humedad del suelo
  Serial.print("Humedad del suelo del huerto 0: "); Serial.print(percentageHumidity0); Serial.println("%");
  Serial.print("Humedad del suelo del huerto 1: "); Serial.print(percentageHumidity1); Serial.println("%");
  //delay(5000);

  /////Para mostrarlo en el LCD

  lcd.init(); //Inicializamos el LCD
  lcd.backlight(); //Activamos la luz de fondo
  lcd.clear();//blanqueamos la pantalla
  lcd.setCursor(2, 0); //Posicion: columna 2 fila cero
  lcd.print("Carolina Coronado");
   lcd.setCursor(5, 2);
   lcd.print("Proyecto de");
   lcd.setCursor(3, 3);
   lcd.print("Huerto domotico");
   delay(4000);
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Temp.ambiente:");
   lcd.setCursor(0,1);
  lcd.print("DHT:H0:");
  lcd.print(temp0);
  lcd.print("C ");
  //lcd.setCursor(14, 0);
  lcd.print("H1:");
  lcd.print(temp1);
  lcd.print("C");
  lcd.setCursor(0, 2);
  lcd.print("Hum. ambiente:");
  lcd.setCursor(0,3);
  lcd.print("Hum.:H0:");
  lcd.print(humedad0);
  lcd.print("% ");
  //lcd.setCursor(14, 1);
  lcd.print("H1:");
  lcd.print(humedad1);
  lcd.print("%");
  delay(10000);
  lcd.clear();
  lcd.setCursor(0, 0); //Posicion: columna cero fila uno
  lcd.print("Humedad Suelo:");
  lcd.setCursor(0,1);
  lcd.print("H0:");
  //lcd.print(SensorValue0);
  lcd.print(percentageHumidity0);
  lcd.print("% ");
  //lcd.setCursor(15, 2); //Posicion: columna cero fila 
  //lcd.print(SensorValue1);
  lcd.print("H1:");
  lcd.print(percentageHumidity1);
  lcd.print("%");
  lcd.setCursor(0, 2);
  lcd.print("Temp. suelo:");
  lcd.setCursor(0,3);
  printTemperature(Thermometer0);
      lcd.print("H0:");
      lcd.print(tempC);
      lcd.print("C ");
      printTemperature(Thermometer1);
      lcd.print("H1:");
      lcd.print(tempC);
      lcd.print("C");
 // lcd.print("Imprimiendo esto.");
delay(10000);
  lcd.clear();

  /*
    //esto si quiero que la pantalla vaya de izquierda a derecha.
    for(int c=0;c<12;c++){ //hace una secuencia hacia la izquierda y luego hacia la derecha, por 12 pasos
    lcd.scrollDisplayLeft();
    delay(600);   }
    for(int c=0; c<12;c++){
    lcd.scrollDisplayRight();
    delay(600);   }
    lcd.clear();//blanqueamos la pantalla
  */

/*
  if (SensorNivel == 0 && botonest == 1)
  { Serial.println("Nivel bajo de Agua. Rellenar el tanque");
    lcd.setCursor(0, 0); //Posicion: columna cero fila cero
    lcd.print("Nivel bajo agua");
    lcd.setCursor(0, 1); //Posicion: columna cero fila cero
    lcd.print("Rellenar tanque");
    delay (2000);
    lcd.clear();//blanqueamos la pantalla
    lcd.setCursor(0, 0); //Posicion: columna cero fila cero
    lcd.print("DHT:");
    lcd.print(temp0);
    lcd.print("C/");
    lcd.print(humedad0);
    lcd.print("%");
    lcd.setCursor(0, 1); //Posicion: columna cero fila uno
    lcd.print("HS:");
    lcd.print(SensorValue0);
    lcd.print("%");
    delay (5000);
  }
*/

// Vamos a encender las resistencias necesarias para tener la tierra de las plantas a la temperatura adecuada.

//Huerto 0.
  printTemperature(Thermometer0);
  //if ( tempC < 28.0 )
  if ( int(tempC) < tempminimasuelo )
      {
      lcd.clear();//blanqueamos la pantalla
      lcd.setCursor(0, 0); //Posicion: columna cero fila cero
      lcd.print("Temp suelo H0");
      lcd.setCursor(0, 1); //Posicion: columna cero fila uno
      lcd.print(tempC);
      //lcd.print(SensorValue0);
      //lcd.print(percentageHumidity1);
      lcd.print(" C");
      lcd.setCursor(0, 2);
      lcd.print("Calefactando");
        digitalWrite(resis0, HIGH); // Enciende la resistencia del huerto 0.
        delay(4000); // La mantiene encendida durante 4 segundos.
        digitalWrite(resis0, LOW); //la vuelve a apagar.
        lcd.clear();
        }

//Huerto 1.
  printTemperature(Thermometer1);
  if ( int(tempC) < tempminimasuelo )
      {
        lcd.clear();//blanqueamos la pantalla
      lcd.setCursor(0, 0); //Posicion: columna cero fila cero
      lcd.print("Temp suelo H1");
      lcd.setCursor(0, 1); //Posicion: columna cero fila uno
      lcd.print(tempC);
      //lcd.print(SensorValue0);
      //lcd.print(percentageHumidity1);
      lcd.print(" C");
      lcd.setCursor(0, 2);
      lcd.print("Calefactando");
        digitalWrite(resis1, HIGH); // Enciende la resistencia del huerto 1.
        delay(4000); // La mantiene encendida durante 4 segundos.
        digitalWrite(resis1, LOW); //la vuelve a apagar.
        lcd.clear();
        }
/*
  if (SensorValue1 >= 700) // el valor que considero seco y hay que regar es de 700
    {
      // Si la tierra está seca, comenzara a regar
      // Riega durante 4 segundoS y espera a comprobar la humedad otro segundo
      Serial.println("La tierra del huerto 1 está seca, comienza el riego automático");
      lcd.clear();//blanqueamos la pantalla
      lcd.setCursor(0, 0); //Posicion: columna cero fila cero
      lcd.print("Riego automatico del huerto 1");
      lcd.setCursor(0, 1); //Posicion: columna cero fila uno
      lcd.print("HS:");
      //lcd.print(SensorValue0);
      lcd.print(percentageHumidity1);
      lcd.print("%");
      digitalWrite(bomba1, HIGH);
      delay(4000);
      digitalWrite(bomba1, LOW);
      delay(1000);
    */
/* mientras no haya botón puesto no tiene sentido este párrafo
      if (botonest == 0)
      { Serial.println("No se puede activar riego manual. Riego automático activo");
        lcd.clear();//blanqueamos la pantalla
        lcd.setCursor(0, 0); //Posicion: columna cero fila cero
        lcd.print("Regando automatico");
        lcd.setCursor(0, 1); //Posicion: columna cero fila cero
        lcd.print("NO MANUAL");
        delay(1000);
      }
      */
   // }



/*
  if (SensorNivel == 0 && botonest == 0)
  { Serial.println("Imposible regar, nivel bajo de agua. Debe rellenar el tanque");
    lcd.clear();//blanqueamos la pantalla
    lcd.setCursor(0, 0); //Posicion: columna cero fila cero
    lcd.print("IMPOSIBLE REGAR");
    lcd.setCursor(0, 1); //Posicion: columna cero fila cero
    lcd.print("Nivel bajo");
  }
*/


//  if (SensorNivel == 1)
//  {
//    Serial.println("Nivel de agua correcto, se puede regar");
// Regar o no el huerto 0.
    if (SensorValue0 >= dry) // el valor que considero seco y hay que regar es de 700
    {
      // Si la tierra está seca, comenzara a regar
      // Riega durante 2 segundoS y espera a comprobar la humedad otro segundo
      Serial.println("La tierra está seca, comienza el riego automático");
      lcd.clear();//blanqueamos la pantalla
      lcd.setCursor(0, 0); //Posicion: columna cero fila cero
      lcd.print("Riego automatico H0:");
      lcd.setCursor(0, 1); //Posicion: columna cero fila uno
      lcd.print("Humedad Suelo 0: ");
      //lcd.print(SensorValue0);
      lcd.print(percentageHumidity0);
      lcd.print("%");
      digitalWrite(bomba0, HIGH);
      delay(4000);
      digitalWrite(bomba0, LOW);
     // delay(1000);
    
/* mientras no haya botón puesto no tiene sentido este párrafo
      if (botonest == 0)
      { Serial.println("No se puede activar riego manual. Riego automático activo");
        lcd.clear();//blanqueamos la pantalla
        lcd.setCursor(0, 0); //Posicion: columna cero fila cero
        lcd.print("Regando automatico");
        lcd.setCursor(0, 1); //Posicion: columna cero fila cero
        lcd.print("NO MANUAL");
        delay(1000);
      }
      */
    }

/*    if (SensorValue0 < 700) //No es necesario el riego automático, pero se puede regar de forma manual
    {
      if (botonest == 0) {
        Serial.println("Regando de forma manual");
        lcd.clear();//blanqueamos la pantalla
        lcd.setCursor(0, 0); //Posicion: columna cero fila cero
        lcd.print("Riego manual");
        lcd.setCursor(0, 1); //Posicion: columna cero fila uno
        lcd.print("HS:");
        lcd.print(SensorValue0);
        lcd.print("%");
        digitalWrite(bomba0, HIGH);
      }
      if (botonest == 1) {
        digitalWrite(bomba0, LOW);
      }
    }
    */
    //Ahora el otro huerto, el 1.
     if (SensorValue1 >= dry) // el valor que considero seco y hay que regar es de 700
    {
      // Si la tierra está seca, comenzara a regar
      // Riega durante 4 segundoS y espera a comprobar la humedad otro segundo
      Serial.println("La tierra del huerto 1 está seca, comienza el riego automático");
      lcd.clear();//blanqueamos la pantalla
      lcd.setCursor(0, 0); //Posicion: columna cero fila cero
      lcd.print("Riego automatico H1:");
      lcd.setCursor(0, 1); //Posicion: columna cero fila uno
      lcd.print("Humedad Suelo 1: ");
      //lcd.print(SensorValue0);
      lcd.print(percentageHumidity1);
      lcd.print("%");
      digitalWrite(bomba1, HIGH);
      delay(4000);
      digitalWrite(bomba1, LOW);
      //delay(1000);
    
/* mientras no haya botón puesto no tiene sentido este párrafo
      if (botonest == 0)
      { Serial.println("No se puede activar riego manual. Riego automático activo");
        lcd.clear();//blanqueamos la pantalla
        lcd.setCursor(0, 0); //Posicion: columna cero fila cero
        lcd.print("Regando automatico");
        lcd.setCursor(0, 1); //Posicion: columna cero fila cero
        lcd.print("NO MANUAL");
        delay(1000);
      }
      */
    }

/*    if (SensorValue0 < 700) //No es necesario el riego automático, pero se puede regar de forma manual
    {
      if (botonest == 0) {
        Serial.println("Regando de forma manual");
        lcd.clear();//blanqueamos la pantalla
        lcd.setCursor(0, 0); //Posicion: columna cero fila cero
        lcd.print("Riego manual");
        lcd.setCursor(0, 1); //Posicion: columna cero fila uno
        lcd.print("HS:");
        lcd.print(SensorValue0);
        lcd.print("%");
        digitalWrite(bomba0, HIGH);
      }
      if (botonest == 1) {
        digitalWrite(bomba0, LOW);
      }
    }
    */
//    } // Esta llave va con el if de SensorNivel de más arriba para comprobar el niver de agua antes de regar. Hay que comprar un sensor de nivel de agua.
}

Que programado en arduino hace la magia de poner todo a funcionar. 

 

 

 

 El hardware de un huerto domótico.

Las primeras decisiones a tomar cuando se va a realizar un proyecto con arduino es cuales son los sensores que se van a usar así como los actuadores que darán respuesta a lo que dichos sensores detecten.

En un huerto es vital que se mantengan ciertos niveles de humedad y temperatura, tanto en el aire como en la tierra donde están las plantas, así que, precisamente esas son las variables que habrá que medir para, según los valores observados, y siguiendo los criterios del especialista, tomar las decisiones adecuadas.

Existen multitud de sensores en el mercado para medir esas y otras muchas variables, pero decidimos ajustarnos a un proyecto de unas dimensiones razonables.

Para la medición de la humedad y la temperatura ambiente se optó por el superconocido sensor DHT11, cuya imagen sigue estas líneas.

Éste sensor puede funcionar con 3,3 o 5 voltios, teniendo un rango de temperaturas medibles desde 0 hasta 50º C con un 5% de precisión, y por otro lado mide la humedad relativa desde el 20% hasta el 80%, teniendo igualmente una precisión del 5%. Es de destacar que se puede obtener una muestra por segundo.

Para la medición de la temperatura de la tierra se optó por el sensor DS18B20, en un formato que es bastante acertado para la labor que debe realizar. La presentación de este sensor es la que sigue estas líneas.

Es capaz de medir desde -55º hasta 125 ºC, sometido a unos voltajes de entre 3 y 5'5 voltios.

La humedad de la tierra se ha medido con el sensor cuya imagen sigue a este párrafo.
El sensor se alimenta con una corriente de entre 3 y 5'5 voltios.
Una vez elegidos los sensores para poder monitorizar las variables deseadas en este proyecto pasamos a decidir cómo se iba a actuar ante los posibles valores de los mismos, y la decisión a tomar es la de regar o no la zona monitorizada.
La forma de controlar las electroválvulas que se usan habitualmente en el huerto es a través de unos relés, que se disparan unsando la señal de arduino de 5v y que pueden controlar corrientes de 250V y altas potencias como las de las electroválvulas usadas. El módulo de relés usado es el siguiente.
Por último se adquirieron unas bombas de agua pequeñas para poder hacer un montaje a pequeña escala para controlas unas mesas de enraizado. Las bombas usadas son como las que siguen.













jueves, 18 de mayo de 2023

 La domoticación de un huerto es una de las tareas más bonitas, completas y útiles que se pueden llevar a cabo con cualquiera de los dispositivos electrónicos que permiten esta tarea.

El mantenimiento de un huerto consiste en buena parte en mantener controlados ciertos parámetros, a saber, la humedad y la temperatura tanto del ambiente como de la tierra, y esto requiere a su vez la monitorización de dichas variables en esos dos entornos, y por otro lado hay que ser capaz de tomar decisiones con los valores obtenidos en esas variables. Las decisiones de las que se habla son las de regar o no para tener controlada la humedad de la tierra, encender o no calentadores de tierra o de aire, e incluso abrir las ventanas de ventilación del invernadero.

Existe una amplia documentación en internet sobre el tema, utilizando diferentes dispositivos para tal fin, como Arduino, Raspberry PI, tarjetas ESP32, entre otras.

Nosotros nos hemos decantado por hacer la monitorización y el control con Arduino, por su amplia difusión, por su sencillez de programación, y la amplia y económica gama de sensores disponibles.



martes, 16 de mayo de 2023

Instalación de la Nueva Estación

 

Fecha: Mayo 2023.

Alumnos: Primer Curso del Grado Básico de Agrojardinería y Composiciones Florales.

Profesor: Cayetano Polo (CayetanoPolo22_23),DiegoBote22_23 y  Maite Orellana (Maite_22_23)

 

Hemos instalado la nueva estación meteorología del centro Froggit WH3000SE PRO en la caseta del invernadero combina la última tecnología de medición meteorológica con la última tecnología. Gracias al módulo WiFi integrado, sus datos meteorológicos locales se vuelven globales, ya que puede cargar sus datos meteorológicos a servidores meteorológicos como Weather Underground.

 






jueves, 4 de mayo de 2023

Flores con Geogebra

 Con la llegada de las flores en el IES Carolina los alumnos hacen fotografías

 a las flores del Instituto.Y con Geogebra desde Matemáticas y la belleza

 de las flores  crearan una representación visual de las proporciones en los

 pétalos de  una flor. Utilizando la herramienta de construccion de Geogebra

para crear en una flor un cierto numero de figuras geométricas. 

 

Fecha: Mayo 

Alumnos: 4 ESO