Como crear un sistema de riego automático basado en ESP

Puede ver el código del programa aquí:

#include <DNSServer.h>

#include <ESP8266WiFi.h> //Llibreria per al ESP8266

void updateValue(String sensor, String value); //Funció per a actualitzar els c¡valors de humetat

const int sensorPin1 = 15; //Declaració del sensor de la zona 1 al pin 15
const int sensorPin2 = 16; //Declaració del sensor de la zona 2 al pin 16
const int sensorPin3 = 2; //Declaració del sensor de la zona 3 al pin 2
const int sensorPin4 = 14; //Declaració del sensor de la zona 4 al pin 14
const int sensorPin5 = 12; //Declaració del sensor de la zona 5 al pin 12

const int humedadAire = 600; //Definir valor d'humetat de l'aire per al map
const int humedadAgua = 200; //Definir valor d'humetat de l'aigua per al map

const char* apSSID = "HORT-AP"; //Definir nom de l'Access Point
const char* apPassword = "password123"; //Definir contrasenya de l'Access Point
const IPAddress apIP(192, 168, 1, 1); //Definir IP de l'Access Point

DNSServer dnsServer;
const char* domain = "ies.com";

int Bomba = 13; //Definir el pin per al relay de la bomba al GPIO13

int humedadTierra1 = 0; //Crear la variable per a la humetat de la zona 1
int humedadTierra2 = 0; //Crear la variable per a la humetat de la zona 2
int humedadTierra3 = 0; //Crear la variable per a la humetat de la zona 3
int humedadTierra4 = 0; //Crear la variable per a la humetat de la zona 4
int humedadTierra5 = 0; //Crear la variable per a la humetat de la zona 5

unsigned long ultimaActualizacion = 0; //Variables per al control de actualització

const unsigned long intervaloActualizacion = 5 * 1000; //Temps d'actualització (5*1000 = 5000 milisegons = 5 segons) - Caldrà canviarlo per a mitja hora

WiFiServer server(80); //Iniciar el servidor Web per el port 80

void setup() {
  delay(10);

  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(apSSID, apPassword);

  pinMode(Bomba, OUTPUT);
  digitalWrite(Bomba, LOW);
dnsServer.start(53, domain, apIP);
  server.begin();
}

void loop() {

dnsServer.processNextRequest();
  
  unsigned long tiempoActual = millis(); //Control del temps
  if (tiempoActual - ultimaActualizacion >= intervaloActualizacion) { //Control del temps
    actualizarValoresDeHumedadSimulados(); //Control del temps
    ultimaActualizacion = tiempoActual; //Control del temps
  }

  //ACCIONS NECESSARIES PER AL FUNCIONAMENT DE LA WEB
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  while (!client.available()) {
    delay(1);
  }
  String request = client.readStringUntil('\r');
  client.flush();
 //FI DE LES ACCIONS NECESSARIES PER AL FUNCIONAMENT DE LA WEB

  //ACCIONS PER AL CONTROL MANUAL DE LA BOMBA
  int value = LOW;
  if (request.indexOf("/BOMBA=ON") != -1)  {
    digitalWrite(Bomba, HIGH);
    value = HIGH;
  } if (request.indexOf("/BOMBA=OFF") != -1)  {
    digitalWrite(Bomba, LOW);
    value = LOW;
  }
//FI DE LES ACCIONS PER AL CONTROL MANUAL DE LA BOMBA

client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head>");
  client.println("<style>");
  client.println("body { background-color: #f9e5cf; color: #333; font-family: Arial, sans-serif; }");
  client.println("h1 { text-align: center; color: #e86830; font-size: 46px; }");
  client.println("h2 { text-align: center; color: #000000; font-size: 46px; }");
  client.println("button { background-color: #e86830; color: #fff; padding: 10px; font-size: 46px; border: none; cursor: pointer; }");
  client.println("button:hover { background-color: #d8551e; }");
  client.println("input[type='range'] { width: 80%; margin: 30px 0; }");
  client.println("#header { text-align: center; }");
  client.println("#logo { max-width: 200px; max-height: 200px; }");
  client.println("</style>");
  client.println("</head>");
  client.println("<body>");

  client.println("<div id='header'>");
  client.println("<img id='logo' src='data:image/png;base64,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' alt='Logo'>");
  client.println("</div>");
  
  client.print("<h1>SISTEMA DE REG AUTOMATIC - IES MONTDUVER</h1>");

client.println("<br><br>");
client.println("<div style='text-align: center;'>");
client.println("<a href=\"/BOMBA=ON\"><button type=\"button\">ENCENDER BOMBA</button></a>");
client.println("<a href=\"/BOMBA=OFF\"><button type=\"button\">APAGAR BOMBA</button></a><br>");
client.println("</div>");

  client.println("<br></br>");
  client.println("<div style='text-align: center;'>");
  
client.println("<h2>ZONA 1</h2>");

client.println("<div style='text-align: center;'>");
client.println("</div>");
client.print("<input type='range' min='0' max='100' value='" + String(humedadTierra1) + "' id='humedad1' disabled style='height: 20px; margin: 10px; -webkit-appearance: none; background: linear-gradient(to right, white " + String(humedadTierra1) + "%, #d3d3d3 " + String(humedadTierra1) + "%); outline: none; border: 1px solid #d3d3d3; border-radius: 10px;'><br>");

client.println("<h2>ZONA 2</h2>");
client.println("<div style='text-align: center;'>");
client.println("</div>");
client.print("<input type='range' min='0' max='100' value='" + String(humedadTierra2) + "' id='humedad2' disabled style='height: 20px; margin: 10px; -webkit-appearance: none; background: linear-gradient(to right, white " + String(humedadTierra2) + "%, #d3d3d3 " + String(humedadTierra2) + "%); outline: none; border: 1px solid #d3d3d3; border-radius: 10px;'><br>");

client.println("<h2>ZONA 3</h2>");
client.println("<div style='text-align: center;'>");
client.println("</div>");
client.print("<input type='range' min='0' max='100' value='" + String(humedadTierra3) + "' id='humedad3' disabled style='height: 20px; margin: 10px; -webkit-appearance: none; background: linear-gradient(to right, white " + String(humedadTierra3) + "%, #d3d3d3 " + String(humedadTierra3) + "%); outline: none; border: 1px solid #d3d3d3; border-radius: 10px;'><br>");

client.println("<h2>ZONA 4</h2>");
client.println("<div style='text-align: center;'>");
client.println("</div>");
client.print("<input type='range' min='0' max='100' value='" + String(humedadTierra4) + "' id='humedad4' disabled style='height: 20px; margin: 10px; -webkit-appearance: none; background: linear-gradient(to right, white " + String(humedadTierra4) + "%, #d3d3d3 " + String(humedadTierra4) + "%); outline: none; border: 1px solid #d3d3d3; border-radius: 10px;'><br>");

client.println("<h2>ZONA 5</h2>");
client.println("<div style='text-align: center;'>");
client.println("</div>");
client.print("<input type='range' min='0' max='100' value='" + String(humedadTierra5) + "' id='humedad5' disabled style='height: 20px; margin: 10px; -webkit-appearance: none; background: linear-gradient(to right, white " + String(humedadTierra5) + "%, #d3d3d3 " + String(humedadTierra5) + "%); outline: none; border: 1px solid #d3d3d3; border-radius: 10px;'><br>");

  client.println("<script>function updateValue(sensor, value) {document.getElementById('value'+sensor.charAt(sensor.length-1)).innerHTML = value; document.getElementById('humedad'+sensor.charAt(sensor.length-1)).value = value;}</script>");
  client.println("</body>");
  client.println("</html>");

  client.println("<br><br>");
client.println("<div style='text-align: center;'>");
client.println("<p>&copy; 2024 Andreu Cloquell</p>");
client.println("</div>");
client.println("<p style='text-align: center;'>Todos los derechos reservados</p>");
client.println("<p style='text-align: center;'>Version 1.0""</p>");

//FI DE LA ESTRUCTURA HTML I CSS

  updateValue("humedadTierra1", String(humedadTierra1));
  updateValue("humedadTierra2", String(humedadTierra2));
  updateValue("humedadTierra3", String(humedadTierra3));
  updateValue("humedadTierra4", String(humedadTierra4));
  updateValue("humedadTierra5", String(humedadTierra5));

  delay(1);
}

void updateValue(String sensor, String value) {
  if (sensor == "humedadTierra1") {
    humedadTierra1 = value.toInt();
  } else if (sensor == "humedadTierra2") {
    humedadTierra2 = value.toInt();
  } else if (sensor == "humedadTierra3") {
    humedadTierra3 = value.toInt();
  } else if (sensor == "humedadTierra4") {
    humedadTierra4 = value.toInt();
  } else if (sensor == "humedadTierra5") {
    humedadTierra5 = value.toInt();
  }
}

void actualizarValoresDeHumedadSimulados() {
  int humedad1 = analogRead(sensorPin1);
  humedadTierra1 = map(humedad1, humedadAire, humedadAgua, 0, 100);
  if (humedadTierra1 > 100) humedadTierra1 = 100;

  int humedad2 = analogRead(sensorPin2);
  humedadTierra2 = map(humedad2, humedadAire, humedadAgua, 0, 100);
  if (humedadTierra2 > 100) humedadTierra2 = 100;

  int humedad3 = analogRead(sensorPin3);
  humedadTierra3 = map(humedad3, humedadAire, humedadAgua, 0, 100);
  if (humedadTierra3 > 100) humedadTierra3 = 100;

  int humedad4 = analogRead(sensorPin4);
  humedadTierra4 = map(humedad4, humedadAire, humedadAgua, 0, 100);
  if (humedadTierra4 > 100) humedadTierra4 = 100;

  int humedad5 = analogRead(sensorPin5);
  humedadTierra5 = map(humedad5, humedadAire, humedadAgua, 0, 100);
  if (humedadTierra5 > 100) humedadTierra5 = 100;
}