Saltar al contenido
Nivel intermedio

Regar según la humedad del suelo

Conectar el higrómetro

En el nivel inicial desarrollamos un programa que controla la frecuencia de riego abriendo y cerrando una electroválvula por tiempo. Ahora vamos a ajustar ese riego en base a la información que obtengamos midiendo la humedad del suelo: regar cuando la humedad sea baja y dejar de regar cuando alcance un valor que consideremos suficiente.

Para eso usamos un higrómetro de suelo (FC-28), un sensor que mide la humedad de la tierra a partir de su conductividad eléctrica.

Módulo higrómetro de suelo FC-28: a la izquierda, la plaqueta con el circuito y los pines de conexión; a la derecha, la horquilla de dos puntas que se clava en la tierra, unida a la plaqueta por dos cables.
El higrómetro de suelo FC-28: la horquilla (derecha) se clava en la tierra y la plaqueta (izquierda) entrega la lectura a la placa (figura original del proyecto).

El módulo tiene tres pines de conexión: dos para la alimentación (VCC y GND) y un tercero de salida analógica, que entrega un nivel de tensión según la humedad registrada. Por eso se conecta a una entrada analógica de la placa: esas entradas digitalizan la señal y devuelven un número proporcional a la tensión de entrada.

Esquema de conexión: placa Arduino UNO con 5V y GND al módulo higrómetro FC-28, y la salida analógica del módulo al pin A0; la horquilla de dos puntas conectada a la plaqueta.
Esquema de conexión del higrómetro en el nivel intermedio (figura original del proyecto): alimentación a 5V/GND y salida analógica al pin A0.

Para obtener una buena medición hay que enterrar la horquilla del sensor en un lugar que represente lo más fielmente posible las condiciones generales de la huerta, cantero o maceta. Una mala ubicación (por ejemplo, fuera de la zona de riego) puede hacer que algunas zonas queden muy secas y otras muy húmedas.

En el Arduino UNO seguimos el esquema original: VCC al pin 5V, GND a GND y la salida analógica del módulo a la entrada A0 (la constante PIN_HIGROMETRO del código del paso 5). Las entradas analógicas del UNO (A0 a A5) devuelven un valor entre 0 y 1023.

En el ESP32 la conexión es equivalente, con dos cuidados propios de la placa: alimentá el módulo con 3,3 V (no 5 V) para que su salida no supere ese nivel, y leelo por un GPIO del ADC1, que sigue funcionando con el WiFi encendido. El número exacto está en la constante PIN_HIGROMETRO del código del paso 5 (el GPIO 34, que además es de solo entrada). Su conversor es de 12 bits, así que devuelve un valor entre 0 y 4095, en lugar del 0 a 1023 del UNO.

Leer el puerto serie

Cuando trabajamos con entradas digitales, que solo tienen dos estados, es fácil reflejar su estado con un LED. Pero el higrómetro es analógico: no da dos valores sino un rango (todos los niveles posibles de humedad de la tierra). Para ver esos datos y tomar decisiones en base a ellos usamos el puerto serie.

El puerto serie es un canal de comunicación entre la placa y la computadora. Lo vamos a usar para ver en pantalla los valores que registra el higrómetro. En la placa, el puerto serie está físicamente vinculado al mismo cable USB con el que subimos los programas, así que sirve tanto para cargar el código como para intercambiar mensajes.

En el Arduino UNO ese puerto está conectado a los pines 0 (RX) y 1 (TX): en proyectos que usen el puerto serie, no conectes nada a esos dos pines, porque quedan reservados para la comunicación (por eso el higrómetro va a A0 y no ahí).

En el código, para habilitar el puerto serie se usa Serial.begin() con una velocidad —en este proyecto, la constante VELOCIDAD_SERIAL, de 115200 baudios— y para enviar un mensaje se usa Serial.println(). Del lado de la computadora, en el Arduino IDE 2.x abrimos el Monitor Serie (el ícono de la lupa arriba a la derecha, o desde el menú Herramientas) y seleccionamos la misma velocidad, 115200 baudios, en su menú desplegable. Si los caracteres se ven ilegibles, casi siempre es porque la velocidad del Monitor no coincide con la del programa.

Leer el higrómetro por el puerto serie

Ahora que sabemos comunicarnos con la computadora por el puerto serie, vamos a transmitir los valores que leemos en la entrada analógica donde está el higrómetro. El programa que armaremos en el paso 5 hace exactamente eso: en cada vuelta lee el sensor con analogRead(PIN_HIGROMETRO), guarda el número en una variable y lo envía a la computadora con Serial.println().

Cada vez que subís un programa nuevo, el IDE usa el puerto para la carga, así que puede que el Monitor Serie se corte un instante; una vez terminada la subida, volvés a verlo actualizarse. Deberías empezar a recibir valores dentro del rango de tu placa (0 a 1023 en el UNO, 0 a 4095 en el ESP32) que cambian con la humedad: probá clavar la horquilla en tierra seca y en tierra mojada y observá cómo se mueve el número. Ese “movimiento” es lo que vamos a usar para decidir.

Determinar los valores de humedad para activar la válvula

El higrómetro nos va a permitir decidir cuándo abrir la válvula (cuando el suelo esté demasiado seco) y cuándo cerrarla (cuando esté suficientemente húmedo). Para eso primero tenemos que fijar dos valores de referencia.

Acá hay un detalle que conviene tener muy claro, porque es fácil equivocarse: en estos módulos resistivos, la lectura es inversa. A mayor valor leído, el suelo está más seco (hay menos agua conduciendo, así que el sensor “ve” más resistencia). No al revés. Por eso:

  • El umbral de “seco” es el valor alto: la constante UMBRAL_SECO. Cuando la lectura lo supera, la tierra está demasiado seca y hay que regar.
  • El umbral de “húmedo” es el valor bajo: la constante UMBRAL_HUMEDO. Cuando la lectura cae por debajo de él, la tierra está suficientemente húmeda y hay que cortar.

Ahora que ya podemos ver qué valores arroja el higrómetro por el puerto serie, tomamos muestras de tierra con distintos grados de humedad en unos recipientes, les colocamos el sensor y vamos anotando los valores (sin olvidar limpiar y secar bien la horquilla entre una muestra y la siguiente). Con esos números elegimos tus UMBRAL_SECO y UMBRAL_HUMEDO. El programa del paso 5 ya viene con los valores del ejemplo del original cargados en esas constantes, pero son un punto de partida: se miden en tu suelo, no se copian.

Programar la apertura y el cierre de la válvula según la humedad

Con los umbrales definidos, editamos el programa para que el higrómetro comande la válvula. La lógica, en cada vuelta de loop(), es la que definimos en el paso anterior:

  1. Leer el higrómetro una vez y guardar el valor (y publicarlo por el puerto serie, para seguir viéndolo).
  2. Si la lectura supera UMBRAL_SECO, la tierra está demasiado seca: abrir la válvula (VALVULA_ABIERTA) para regar.
  3. Si la lectura cae por debajo de UMBRAL_HUMEDO, la tierra está húmeda: cerrar la válvula (VALVULA_CERRADA).
Ver el código completo · riego-por-humedad.ino
riego-por-humedad.ino Arduino UNO
// Riego por humedad: un higrómetro de suelo (FC-28) mide qué tan seca está
// la tierra y el programa abre o cierra la electroválvula en función de eso.
// El higrómetro también se imprime por la consola serial para poder
// calibrar los umbrales observando valores reales.
//
// CONVENCIÓN DEL HIGRÓMETRO (¡importante!): en estos módulos resistivos,
// MAYOR lectura = tierra MÁS SECA (más resistencia, menos agua conduciendo).
// Por eso "seco" es el umbral ALTO y "húmedo" el umbral BAJO. El original
// lo confirma: "mayor a 750 => demasiado seco; menor a 380 => húmedo".
//
// HISTÉRESIS NATURAL DEL ORIGINAL (se preserva tal cual): son dos ifs
// independientes con DOS umbrales distintos. Por encima de 750 abre; por
// debajo de 380 cierra; en la franja intermedia (380 a 750) NINGUNO de los
// dos se cumple, así que la válvula conserva su estado anterior. Esa banda
// muerta evita que la válvula traquetee cuando la lectura baila cerca de un
// único umbral: es una solución elegante que ya venía en el original.
//
// SEGURIDAD: agua y electricidad no se llevan bien. Conexiones eléctricas
// fuera y por encima del agua. Electroválvula de baja tensión (12 V) o
// simulación en el aula; 220 V solo docente/instalación supervisada, nunca
// sobre la protoboard (desvío pedagógico acordado).
//
// Plataforma: Arduino UNO.
// Conexión (la del esquema original): señal analógica del higrómetro → A0;
// entrada "S" del módulo relé de la electroválvula → pin 2.
//
// Basado en: Fragmento de código 5 — Sistema de Riego Automatizado,
// Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas en lugar del C de mBlock3; el
// original llamaba a analogRead(A0) tres veces por vuelta (una para
// imprimir y una por cada if), lo que podía dar tres valores distintos;
// acá se lee UNA vez a una variable y esa misma lectura se imprime y se
// compara. Es más correcto y hace evidente que se decide sobre un único dato.

const int PIN_HIGROMETRO   = A0;
const int PIN_RELE_VALVULA = 2;

// Módulo relé activo-alto, como en el original (HIGH = válvula abierta).
// Si tu módulo es activo-bajo, invertí solo estas dos constantes.
const int VALVULA_ABIERTA = HIGH;
const int VALVULA_CERRADA = LOW;

// Umbrales del original (escala del UNO: 0 a 1023). NO son mágicos: salen
// de medir muestras de tierra con distintos grados de humedad y anotar los
// valores por la consola (Paso 4 del original). Ajustalos a TU suelo.
const int UMBRAL_SECO   = 750; // por encima: tierra demasiado seca → regar
const int UMBRAL_HUMEDO = 380; // por debajo: tierra húmeda → cortar

const long VELOCIDAD_SERIAL = 115200; // la del original

// El original medía una vez por segundo (_delay(1)).
const unsigned long INTERVALO_MEDICION_MS = 1000;

void setup() {
  pinMode(PIN_HIGROMETRO, INPUT);
  pinMode(PIN_RELE_VALVULA, OUTPUT);
  // Estado inicial SEGURO: arrancamos con la válvula cerrada. Sin esta línea
  // el pin queda en LOW por defecto; si invertís las constantes para un módulo
  // activo-bajo, ese LOW pasaría a ser "abierta" y, si al encender la lectura
  // cae en la banda muerta (entre 380 y 750), la válvula regaría sin control.
  // Regla de oro: dejá SIEMPRE el actuador en estado seguro antes del loop.
  digitalWrite(PIN_RELE_VALVULA, VALVULA_CERRADA);
  Serial.begin(VELOCIDAD_SERIAL);
}

void loop() {
  int humedad = analogRead(PIN_HIGROMETRO);

  // Publicamos la lectura por consola: sirve para calibrar los umbrales
  // y para ver en vivo qué "piensa" el sistema del suelo.
  Serial.println(humedad);

  // Histéresis del original: dos ifs independientes, dos umbrales.
  if (humedad > UMBRAL_SECO) {
    // Tierra demasiado seca: abrir la válvula para regar.
    digitalWrite(PIN_RELE_VALVULA, VALVULA_ABIERTA);
  }
  if (humedad < UMBRAL_HUMEDO) {
    // Tierra suficientemente húmeda: cerrar la válvula.
    digitalWrite(PIN_RELE_VALVULA, VALVULA_CERRADA);
  }
  // Entre 380 y 750 no se cumple ninguno: la válvula queda como estaba.

  delay(INTERVALO_MEDICION_MS);
}
riego-por-humedad.ino ESP32
// Riego por humedad: un higrómetro de suelo (FC-28) mide qué tan seca está
// la tierra y el programa abre o cierra la electroválvula en función de eso.
// El higrómetro también se imprime por la consola serial para poder
// calibrar los umbrales observando valores reales.
//
// CONVENCIÓN DEL HIGRÓMETRO (¡importante!): en estos módulos resistivos,
// MAYOR lectura = tierra MÁS SECA (más resistencia, menos agua conduciendo).
// Por eso "seco" es el umbral ALTO y "húmedo" el umbral BAJO. El original
// lo confirma: "mayor a 750 => demasiado seco; menor a 380 => húmedo".
//
// HISTÉRESIS NATURAL DEL ORIGINAL (se preserva tal cual): son dos ifs
// independientes con DOS umbrales distintos. Por encima del umbral seco
// abre; por debajo del húmedo cierra; en la franja intermedia NINGUNO de
// los dos se cumple, así que la válvula conserva su estado anterior. Esa
// banda muerta evita que la válvula traquetee cuando la lectura baila
// cerca de un único umbral: es una solución elegante que ya venía en el
// original.
//
// DIFERENCIA DE ADC (didáctica): el conversor del ESP32 es de 12 bits, así
// que analogRead() devuelve 0 a 4095 (3,3 V), NO el 0 a 1023 (10 bits, 5 V)
// del UNO. Los umbrales del original (750 y 380) se reescalan en la misma
// proporción: 750/1023 ≈ 3000/4095 y 380/1023 ≈ 1520/4095. Mismo fenómeno,
// distinta "regla de medir".
//
// SEGURIDAD: agua y electricidad no se llevan bien. Conexiones eléctricas
// fuera y por encima del agua. Electroválvula de baja tensión (12 V) o
// simulación en el aula; 220 V solo docente/instalación supervisada, nunca
// sobre la protoboard (desvío pedagógico acordado).
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: señal analógica del higrómetro → GPIO 34; relé de la
// electroválvula → GPIO 16.
// Nota eléctrica: el ESP32 trabaja a 3,3 V. El GPIO 34 es de SOLO ENTRADA
// y pertenece al ADC1 (sigue midiendo con WiFi activo, a diferencia del
// ADC2). El módulo higrómetro de 3 pines ya entrega una señal analógica
// lista para el pin; alimentalo con 3,3 V para que su salida no supere ese
// nivel.
//
// Basado en: Fragmento de código 5 — Sistema de Riego Automatizado,
// Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas y portado a ESP32 (el original usaba
// A0 y el pin 2 del UNO); umbrales reescalados al ADC de 12 bits; el
// original llamaba a analogRead tres veces por vuelta (una para imprimir y
// una por cada if), lo que podía dar tres valores distintos; acá se lee UNA
// vez a una variable y esa misma lectura se imprime y se compara.

const int PIN_HIGROMETRO   = 34;
const int PIN_RELE_VALVULA = 16;

// Módulo relé activo-alto, como en el original (HIGH = válvula abierta).
// Si tu módulo es activo-bajo, invertí solo estas dos constantes.
const int VALVULA_ABIERTA = HIGH;
const int VALVULA_CERRADA = LOW;

// Umbrales del original reescalados al ADC de 12 bits del ESP32.
// Ajustalos a TU suelo midiendo con la consola (Paso 4 del original).
const int UMBRAL_SECO   = 3000; // por encima: tierra seca → regar   (750 en UNO)
const int UMBRAL_HUMEDO = 1520; // por debajo: tierra húmeda → cortar (380 en UNO)

const long VELOCIDAD_SERIAL = 115200; // la del original

// El original medía una vez por segundo (_delay(1)).
const unsigned long INTERVALO_MEDICION_MS = 1000;

void setup() {
  pinMode(PIN_HIGROMETRO, INPUT);
  pinMode(PIN_RELE_VALVULA, OUTPUT);
  // Estado inicial SEGURO: arrancamos con la válvula cerrada. Sin esta línea
  // el pin queda en LOW por defecto; si invertís las constantes para un módulo
  // activo-bajo, ese LOW pasaría a ser "abierta" y, si al encender la lectura
  // cae en la banda muerta (entre 1520 y 3000), la válvula regaría sin control.
  // Regla de oro: dejá SIEMPRE el actuador en estado seguro antes del loop.
  digitalWrite(PIN_RELE_VALVULA, VALVULA_CERRADA);
  Serial.begin(VELOCIDAD_SERIAL);
}

void loop() {
  int humedad = analogRead(PIN_HIGROMETRO);

  // Publicamos la lectura por consola: sirve para calibrar los umbrales
  // y para ver en vivo qué "piensa" el sistema del suelo.
  Serial.println(humedad);

  // Histéresis del original: dos ifs independientes, dos umbrales.
  if (humedad > UMBRAL_SECO) {
    // Tierra demasiado seca: abrir la válvula para regar.
    digitalWrite(PIN_RELE_VALVULA, VALVULA_ABIERTA);
  }
  if (humedad < UMBRAL_HUMEDO) {
    // Tierra suficientemente húmeda: cerrar la válvula.
    digitalWrite(PIN_RELE_VALVULA, VALVULA_CERRADA);
  }
  // Entre el umbral húmedo y el seco no se cumple ninguno: la válvula
  // queda como estaba.

  delay(INTERVALO_MEDICION_MS);
}
Riego por humedad: se lee el higrómetro, se imprime por el puerto serie y se abre o cierra la válvula según los umbrales. Entre UMBRAL_HUMEDO y UMBRAL_SECO, la válvula conserva su estado.

Hay un detalle elegante que ya venía en el original: son dos if independientes con dos umbrales distintos. Cuando la lectura queda en la franja intermedia (entre UMBRAL_HUMEDO y UMBRAL_SECO), ninguno de los dos se cumple, así que la válvula conserva el estado que tenía. Esa banda “muerta” es una histéresis natural: evita que la válvula traquetee abriendo y cerrando sin parar cuando la lectura baila cerca de un único punto. Es la respuesta al desafío del paso 4.

Podés ver el sistema completo —el higrómetro midiendo, la lectura subiendo cuando la tierra se seca y la válvula regando hasta humedecerla— en el simulador:

Simulación del comportamiento

La misma máquina de estados del firmware, portada a TypeScript, maneja el comportamiento del dispositivo. No se ejecuta el binario real: la ejecución del .hex con avr8js está en el roadmap.

Simulación lista. Presioná «Iniciar» para arrancar la secuencia.

Cierre del nivel

Al terminar este nivel, el sistema dejó de regar “por reloj” y pasó a regar “por necesidad”: el higrómetro mide la humedad del suelo y la placa abre la válvula solo cuando la tierra está seca, cortando cuando ya está húmeda. Aprendiste a leer un sensor analógico por el puerto serie, a calibrar umbrales con mediciones reales y a aprovechar una histéresis que evita el traqueteo de la válvula. En el nivel avanzado, los estudiantes y docentes van a poder mirar todo esto desde el celular: vamos a publicar la humedad del suelo y el estado de la válvula por Internet de las Cosas.

Evidencia de cierre

Al terminar este nivel, esto tiene que estar funcionando:

  • El higrómetro está conectado a la entrada analógica de la placa (A0 en el UNO, GPIO 34 en el ESP32) y su horquilla clavada en un lugar representativo de la tierra a regar.
  • Sabés abrir el Monitor Serie del Arduino IDE 2.x a 115200 baudios y leer los valores que reporta el higrómetro.
  • Determinaste tus umbrales UMBRAL_SECO y UMBRAL_HUMEDO tomando muestras, entendiendo que a mayor lectura, tierra más seca.
  • El sistema riega cuando la tierra está seca y corta cuando está húmeda, con la banda entre umbrales evitando que la válvula traquetee.