PROYECTO #08

Invernadero
Automatizado

Avanzado
⏱ 90 minutos

Sistema completo de monitorizacion y control: lee humedad del suelo y nivel de luz, ventila cuando hay exceso de calor y enciende el LED si hay poca luz. Dashboard en tiempo real en la OLED.

Sensor Lluvia (Humedad)
Sensor Luz LDR
Ventilador PWM
LED Verde
Pantalla OLED
5 componentes

Materiales

Este proyecto utiliza el mayor numero de componentes hasta ahora — 5 a la vez. Todos se conectan a la placa de expansion simultaneamente.

🌧
Sensor Lluvia / Humedad
x1 unidad (como sensor de suelo)
Sensor de Luz (LDR)
x1 unidad
💨
Ventilador PWM
x1 unidad
🟢
LED Verde
x1 unidad (luz artificial)
Pantalla OLED
x1 unidad (128x64)
🔭
micro:bit v2
x1 + placa expansion

Conexion

Con 5 componentes, la organizacion del cableado es clave. Usa colores diferentes para cada componente y etiqueta los cables si es posible.

Pin Componente Cable sugerido
P0
Sensor Lluvia — Analog
Entrada analogica 0-1023
Cian
P1
Sensor Luz — Analog
Entrada analogica 0-1023
Amarillo
P2
Ventilador — PWM
Salida analogica 0-1023
Verde azul
P3
LED Verde — Digital
Salida digital on/off
Verde
P19 (SCL)
OLED — CLK
Bus I2C — reloj
Blanco
P20 (SDA)
OLED — DA
Bus I2C — datos
Morado
🔋
Si luz > 700 → Ventilador ON (velocidad proporcional)
mucha luz = calor = necesita ventilacion
🟢
Si luz < 300 → LED verde ON (luz artificial)
poca luz = las plantas necesitan iluminacion artificial
Siempre → Dashboard OLED actualizado cada segundo
humedad + luz + estado ventilador + estado LED
💻
Boton A → Mostrar maximos registrados
max humedad y max luz desde el arranque
1
Conecta el Sensor de Lluvia a P0
Aqui actua como sensor de humedad del suelo. Signal a P0 (analogico), V a 3.3V, G a GND. Al mojar el modulo, el valor sube (mas conductividad = mas humedad).
2
Conecta el Sensor de Luz a P1
Signal a P1 (analogico), V a 3.3V, G a GND. Valores altos = mucha luz. Valores bajos = oscuridad. En un invernadero real, se puede colocar apuntando hacia arriba para medir la luz solar.
3
Conecta el Ventilador a P2
Signal a P2 (PWM), V a 5V (o alimentacion de la placa), G a GND. El ventilador recibe una salida analogica entre 0 y 1023 — esto controla su velocidad proporcionalmente a la luz.
4
Conecta el LED Verde a P3
Signal a P3 (digital), V a 3.3V, G a GND. Este LED simula la luz artificial que se encenderia cuando hay poca luz natural. Solo necesita encendido/apagado.
5
Conecta la Pantalla OLED (I2C)
CLK a P19, DA a P20, V a 3.3V, G a GND. La OLED es el dashboard del sistema — muestra en tiempo real todos los valores y el estado de cada actuador.

Programacion

Codigo completo con comentarios. El sistema lee sensores, toma decisiones automaticas y actualiza el dashboard cada segundo. El boton A guarda y muestra los valores maximos registrados.

JavaScript — MakeCode
// Invernadero automatizado con múltiples sensores
// Sistema: sensor → decisión → actuador

let humedad = 0
let luz = 0
let UMBRAL_LUZ_BAJA = 300   // Encender LED artificial
let UMBRAL_CALOR = 700       // Encender ventilador

// Inicializar OLED
OLED.init(128, 64)

function getEstadoHumedad(val: number): string {
    if (val < 200) return "Seco"
    if (val < 500) return "Normal"
    return "Humedo"
}

function getEstadoLuz(val: number): string {
    if (val < 300) return "Oscuro"
    if (val < 700) return "Normal"
    return "Brillante"
}

basic.forever(function () {
    // === LEER SENSORES ===
    humedad = pins.analogReadPin(AnalogPin.P0)
    luz = pins.analogReadPin(AnalogPin.P1)

    // === CONTROL AUTOMÁTICO ===

    // Ventilador: encender si hay mucha luz (calor)
    if (luz > UMBRAL_CALOR) {
        pins.analogWritePin(AnalogPin.P2, Math.map(luz, UMBRAL_CALOR, 1023, 400, 1023))
    } else {
        pins.analogWritePin(AnalogPin.P2, 0)  // Ventilador apagado
    }

    // LED artificial: encender si hay poca luz
    if (luz < UMBRAL_LUZ_BAJA) {
        pins.digitalWritePin(DigitalPin.P3, 1)
    } else {
        pins.digitalWritePin(DigitalPin.P3, 0)
    }

    // === DASHBOARD OLED ===
    OLED.clear()
    OLED.writeString("=== INVERNADERO ===")
    OLED.writeString("Hum: " + humedad + " " + getEstadoHumedad(humedad))
    OLED.writeString("Luz: " + luz + " " + getEstadoLuz(luz))
    OLED.writeString("Vent: " + (luz > UMBRAL_CALOR ? "ON" : "OFF"))
    OLED.writeString("LED: " + (luz < UMBRAL_LUZ_BAJA ? "ON" : "OFF"))

    basic.pause(1000)
})

// Botón A: mostrar valores máximos registrados
let maxHumedad = 0
let maxLuz = 0

input.onButtonPressed(Button.A, function () {
    if (humedad > maxHumedad) maxHumedad = humedad
    if (luz > maxLuz) maxLuz = luz
    OLED.clear()
    OLED.writeString("=== MAXIMOS ===")
    OLED.writeString("Max Hum: " + maxHumedad)
    OLED.writeString("Max Luz: " + maxLuz)
    basic.pause(3000)
})
MicroPython
from microbit import *
import ssd1306

oled = ssd1306.SSD1306_I2C(128, 64, i2c)

UMBRAL_LUZ_BAJA = 300
UMBRAL_CALOR = 700

max_humedad = 0
max_luz = 0

def estado_humedad(val):
    if val < 200: return "Seco"
    if val < 500: return "Normal"
    return "Humedo"

def estado_luz(val):
    if val < 300: return "Oscuro"
    if val < 700: return "Normal"
    return "Brillante"

def mapear(v, amin, amax, bmin, bmax):
    return int((v - amin) * (bmax - bmin) / (amax - amin) + bmin)

while True:
    # Leer sensores
    humedad = pin0.read_analog()
    luz = pin1.read_analog()

    # Actualizar máximos
    if humedad > max_humedad: max_humedad = humedad
    if luz > max_luz: max_luz = luz

    # Control ventilador
    if luz > UMBRAL_CALOR:
        vel = mapear(luz, UMBRAL_CALOR, 1023, 400, 1023)
        pin2.write_analog(vel)
    else:
        pin2.write_analog(0)

    # Control LED artificial
    pin3.write_digital(1 if luz < UMBRAL_LUZ_BAJA else 0)

    # Dashboard OLED
    oled.fill(0)
    oled.text("== INVERNADERO ==", 0, 0)
    oled.text("Hum:" + str(humedad) + " " + estado_humedad(humedad), 0, 14)
    oled.text("Luz:" + str(luz) + " " + estado_luz(luz), 0, 26)
    oled.text("Vent:" + ("ON" if luz > UMBRAL_CALOR else "OFF"), 0, 38)
    oled.text("LED:" + ("ON" if luz < UMBRAL_LUZ_BAJA else "OFF"), 0, 50)
    oled.show()

    # Botón A: ver máximos
    if button_a.was_pressed():
        oled.fill(0)
        oled.text("=== MAXIMOS ===", 0, 0)
        oled.text("Max Hum: " + str(max_humedad), 0, 20)
        oled.text("Max Luz: " + str(max_luz), 0, 36)
        oled.show()
        sleep(3000)

    sleep(1000)
Concepto clave — Control proporcional del ventilador

En vez de encender el ventilador a tope o apagarlo, usamos Math.map (MakeCode) o la funcion mapear (MicroPython) para convertir el rango de luz (700-1023) al rango de PWM del ventilador (400-1023). Asi el ventilador va mas rapido cuanta mas luz hay — un control proporcional real, como el que usan los sistemas industriales.


Pruebalo

Con 5 componentes hay mas cosas que verificar. Prueba cada uno por separado antes de probar el sistema completo.

Dashboard en marcha: la OLED muestra "INVERNADERO" con valores de humedad y luz actualizandose cada segundo.
Sensor de humedad: moja ligeramente el sensor de lluvia con el dedo. El valor de "Hum" sube y el texto cambia a "Humedo".
Control del ventilador: ilumina el sensor de luz con una linterna. Cuando el valor de "Luz" supera 700, el ventilador arranca. Al quitar la luz, se para.
Velocidad proporcional: el ventilador va mas rapido cuanta mas luz hay — no es solo on/off, es proporcional.
LED artificial: tapa el sensor de luz con la mano. Cuando "Luz" baja de 300, el LED verde se enciende automaticamente.
Boton A — Maximos: pulsa el boton A del micro:bit. La OLED muestra "MAXIMOS" con los valores mas altos registrados desde el arranque.

Actividades

Retos para convertir este invernadero basico en un sistema mas completo. Algunos requieren investigacion y experimentacion.

🎯
Reto 1 — Alerta
Alarma de suelo seco
Añade un umbral de humedad baja: si la humedad esta por debajo de 200, muestra "REGAR!" en la OLED con caracteres grandes y haz que el LED parpadee. El umbral exacto dependera de tu sensor — experimenta.
🎯
Reto 2 — Modo manual
Control manual con boton B
Añade un "modo manual" activado con el boton B que desactive la automatizacion. En modo manual, el boton A sube la velocidad del ventilador un nivel (0 → 300 → 600 → 1023 → 0). Muestra "MANUAL" en la OLED cuando este activo.
🎯
Reto 3 — Investigacion
Calibra tu sensor real
El sensor de lluvia puede simular humedad del suelo. Investiga: ¿que valor da con el sensor en seco? ¿Y al mojarlo? ¿Sube o baja el valor? Ajusta los umbrales UMBRAL_LUZ_BAJA y UMBRAL_CALOR para que el comportamiento sea realista con tu hardware especifico.
🎯
Reto 4 — Historico
Promedio de ultimas 5 lecturas
Implementa un array de 5 posiciones para guardar las ultimas 5 lecturas de luz. Calcula el promedio y muéstralo en la OLED como "Prom:" junto al valor actual. El promedio evita que el sistema reaccione a cambios instantaneos de luz.

Problemas comunes

Con mas componentes, hay mas posibles puntos de fallo. Aislacion: prueba cada componente de uno en uno.

"Tengo 5 componentes y no se como conectarlos todos sin que se confundan los pines"
La placa de expansion tiene multiples conectores P0-P16 con sus propios pines V y G. Usa P0, P1, P2, P3 para los sensores/actuadores y CLK/DA para la OLED — todos pueden estar conectados a la vez. Si la placa tiene regletas de alimentacion comunes (V y G en los bordes), conecta todos los V a esa regleta y todos los G a la otra.
"El ventilador se enciende pero el LED verde no reacciona"
Comprueba que el LED esta conectado a P3 (DigitalPin.P3) y no a P2 que es el ventilador. Un error comun es intercambiar los conectores. Prueba temporalmente a cambiar pins.digitalWritePin(DigitalPin.P3, 1) por un valor fijo durante la depuracion para confirmar que el LED responde.
"La funcion getEstadoHumedad da error en MakeCode: 'no se puede acceder antes de la inicializacion'"
En MakeCode JavaScript, las funciones deben declararse FUERA de basic.forever, no dentro. Si declaras una funcion dentro del bloque forever, puede dar errores de scope. Mueve las declaraciones de function getEstadoHumedad(...) al nivel raiz del archivo.
"El invernadero reacciona muy lento — el ventilador tarda segundos en responder"
Reduce el basic.pause(1000) a 500ms. Pero ten en cuenta el equilibrio: con lecturas muy frecuentes (menos de 300ms) la OLED puede parpadear visiblemente porque se borra y reescribe continuamente. El valor de 500-1000ms es el equilibrio ideal para este sistema.

Mas alla

El invernadero puede evolucionar hacia un sistema de precision agricola real. Estas ideas van de menor a mayor complejidad.

💧
Riego automatico
Añade una mini bomba de agua controlada por un rele. Cuando la humedad sea muy baja, activa la bomba durante 3 segundos.
🌞
Ciclos dia/noche
Usa el sensor de luz para detectar el ciclo natural de luz. Guarda si es "dia" o "noche" y aplica reglas diferentes de riego y ventilacion para cada periodo.
📊
Log de datos
Usa la funcion de almacenamiento del micro:bit v2 para guardar lecturas cada hora y transferirlas al PC via USB para analizarlas en una hoja de calculo.
🍀
Caja real de invernadero
Construye una caja de carton o madera, coloca los sensores en posicion real (humedad en el suelo, luz apuntando arriba) y prueba con una planta pequeña de verdad.