Regar según la humedad del suelo
Recorrido del nivel
Esa barra de arriba te dice en qué paso estás. Tocala para ver el índice completo y saltar a cualquier paso.
Conectar el higrómetro
En el nivel inicial desarrollamos un programa que controla la frecuencia de riego abriendo y cerrando una electroválvulaElectroválvulaActuador que permite o interrumpe el paso de un fluido. Se acciona a través de su propia alimentación, por lo que tiene únicamente dos pines: sus estados posibles son activada o no, y se puede controlar mediante una salida digital y un relé. 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 sueloHigrómetro de sueloSensor que estima la humedad del suelo midiendo su conductividad eléctrica. Entrega una salida analógica que se conecta a una entrada A0–A5 del Arduino; sirve para distinguir un suelo seco de uno húmedo, no para una medición precisa. (FC-28), un sensor que mide la humedad de la tierra a partir de su conductividad eléctrica.
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.
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 seriePuerto COMPuerto de comunicaciones por el cual el sistema operativo se comunica con un dispositivo externo, como la placa. Se asigna automáticamente al conectarla por USB y puede cambiar de número; en el IDE hay que indicar cuál usar. 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.
La franja del medio
Fijate que UMBRAL_SECO y UMBRAL_HUMEDO no son el mismo número: entre los dos queda una
franja. Discutan en grupo: cuando la lectura está en esa franja intermedia, ¿la válvula debería
abrir o cerrar? ¿Qué pasaría si los dos umbrales fueran el mismo valor y la lectura quedara
bailando justo ahí? Anoten su hipótesis: el código del paso 5 resuelve exactamente ese
problema, y no por casualidad.
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:
- Leer el higrómetro una vez y guardar el valor (y publicarlo por el puerto serie, para seguir viéndolo).
- Si la lectura supera
UMBRAL_SECO, la tierra está demasiado seca: abrir la válvula (VALVULA_ABIERTA) para regar. - 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: 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: 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);
} 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.
Verificá
Con el Monitor Serie abierto a 115200 baudios, probalo primero en seco: al clavar la horquilla
en tierra seca (o al dejar el sensor al aire), la lectura sube por encima de UMBRAL_SECO y la
válvula tiene que abrir (el LED del relé se enciende); al mojar la tierra, la lectura baja por
debajo de UMBRAL_HUMEDO y la válvula tiene que cerrar. Si abre y cierra sin parar, revisá que
UMBRAL_SECO sea mayor que UMBRAL_HUMEDO y que haya una franja razonable entre los dos.
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.