PROYECTO #09

Estacion
Meteorologica

Avanzado
⏱ 90 minutos
⭐ Proyecto final

Panel de datos meteorologicos en tiempo real. Lee dos sensores, formatea los datos y los muestra en un dashboard profesional en la OLED con barras de progreso. Aprende sobre funciones, strings formateados y actualizacion continua de datos.

Sensor Lluvia
Sensor Luz LDR
Pantalla OLED
Dashboard + Historico
Funciones avanzadas

Materiales

Este proyecto usa solo 3 componentes — la complejidad esta en el codigo, no en el hardware. Es una buena forma de profundizar en programacion.

🌧
Sensor Lluvia
x1 unidad
Sensor de Luz (LDR)
x1 unidad
Pantalla OLED
x1 unidad (128x64)
🔭
micro:bit v2
x1 + placa expansion
Cables macho-macho
x6 aprox.

Conexion

Conexion sencilla con solo dos sensores analogicos y la OLED. El foco de este proyecto esta en el software.

Pin Componente Cable sugerido
P0
Sensor Lluvia — Analog
Entrada analogica 0-1023
Cian
P1
Sensor Luz — Analog
Entrada analogica 0-1023
Amarillo
P19 (SCL)
OLED — CLK
Bus I2C — reloj
Blanco
P20 (SDA)
OLED — DA
Bus I2C — datos
Morado
V / G
Todos los componentes
Alimentacion 3.3V / GND
/
Vista principal (tecla A = off)
== METEO STATION ==
NUBLADO | PARCIAL
Lluvia: 423
[####------]
Luz: 512
[#####-----]
Vista historico (tecla A = on)
== HISTORICO ==
Lecturas: 47
Lluv min/max:
120 / 891
Luz min/max:
45 / 978
1
Conecta el Sensor de Lluvia a P0
Signal a P0, V a 3.3V, G a GND. Este sensor mide precipitaciones — un valor alto indica mas humedad/lluvia en el modulo sensor.
2
Conecta el Sensor de Luz a P1
Signal a P1, V a 3.3V, G a GND. El LDR es nuestro sensor de irradiacion solar. Colocado en el exterior (o en la ventana), da lecturas realistas de condiciones de luz.
3
Conecta la OLED (I2C)
CLK a P19, DA a P20, V a 3.3V, G a GND. La OLED es el "monitor" de la estacion — mostrara el dashboard principal o el historico segun el modo activo.
4
Comprende los controles
Boton A: alterna entre vista principal e historico. Boton B: resetea todos los registros historicos (min, max, contador de lecturas). Ambos estan programados en los eventos de botones del micro:bit.

Programacion

El codigo mas complejo de la ruta. Presta atencion a las funciones auxiliares — cada una tiene una responsabilidad clara. La funcion barraProgreso es especialmente util para visualizar datos.

JavaScript — MakeCode
// Estación meteorológica completa
// Dashboard en tiempo real con histórico

let lluvia = 0
let luz = 0
let minLluvia = 1023
let maxLluvia = 0
let minLuz = 1023
let maxLuz = 0
let lecturas = 0
let vistaDashboard = 0  // 0=actual, 1=histórico

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

function getCondicion(): string {
    if (lluvia > 600) return "LLUVIA"
    if (lluvia > 300) return "NUBLADO"
    return "DESPEJADO"
}

function getSol(): string {
    if (luz > 700) return "SOLEADO"
    if (luz > 400) return "PARCIAL"
    return "OSCURO"
}

function barraProgreso(valor: number, max: number, largo: number): string {
    let lleno = Math.round(valor / max * largo)
    let barra = ""
    for (let i = 0; i < largo; i++) {
        barra += (i < lleno ? "#" : "-")
    }
    return "[" + barra + "]"
}

function actualizarHistorico() {
    if (lluvia < minLluvia) minLluvia = lluvia
    if (lluvia > maxLluvia) maxLluvia = lluvia
    if (luz < minLuz) minLuz = luz
    if (luz > maxLuz) maxLuz = luz
    lecturas += 1
}

basic.forever(function () {
    // Leer sensores
    lluvia = pins.analogReadPin(AnalogPin.P0)
    luz = pins.analogReadPin(AnalogPin.P1)
    actualizarHistorico()

    OLED.clear()

    if (vistaDashboard == 0) {
        // Vista principal
        OLED.writeString("== METEO STATION ==")
        OLED.writeString(getCondicion() + " | " + getSol())
        OLED.writeString("Lluvia: " + lluvia)
        OLED.writeString(barraProgreso(lluvia, 1023, 10))
        OLED.writeString("Luz: " + luz)
        OLED.writeString(barraProgreso(luz, 1023, 10))
    } else {
        // Vista histórico
        OLED.writeString("== HISTORICO ==")
        OLED.writeString("Lecturas: " + lecturas)
        OLED.writeString("Lluv min/max:")
        OLED.writeString(minLluvia + " / " + maxLluvia)
        OLED.writeString("Luz min/max:")
        OLED.writeString(minLuz + " / " + maxLuz)
    }

    basic.pause(2000)
})

// Botón A: cambiar vista
input.onButtonPressed(Button.A, function () {
    vistaDashboard = 1 - vistaDashboard  // Alterna entre 0 y 1
    basic.showIcon(IconNames.Yes)
})

// Botón B: resetear histórico
input.onButtonPressed(Button.B, function () {
    minLluvia = 1023
    maxLluvia = 0
    minLuz = 1023
    maxLuz = 0
    lecturas = 0
    basic.showString("RST")
})
MicroPython
from microbit import *
import ssd1306

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

min_lluvia = 1023; max_lluvia = 0
min_luz = 1023; max_luz = 0
lecturas = 0
vista = 0  # 0=actual, 1=historico

def condicion(lluvia):
    if lluvia > 600: return "LLUVIA"
    if lluvia > 300: return "NUBLADO"
    return "DESPEJADO"

def sol(luz):
    if luz > 700: return "SOLEADO"
    if luz > 400: return "PARCIAL"
    return "OSCURO"

def barra(valor, maximo, largo=8):
    lleno = int(valor / maximo * largo)
    return "[" + "#" * lleno + "-" * (largo - lleno) + "]"

while True:
    global min_lluvia, max_lluvia, min_luz, max_luz, lecturas, vista

    lluvia = pin0.read_analog()
    luz = pin1.read_analog()

    # Actualizar histórico
    if lluvia < min_lluvia: min_lluvia = lluvia
    if lluvia > max_lluvia: max_lluvia = lluvia
    if luz < min_luz: min_luz = luz
    if luz > max_luz: max_luz = luz
    lecturas += 1

    oled.fill(0)

    if vista == 0:
        oled.text("METEO STATION", 0, 0)
        oled.text(condicion(lluvia) + "|" + sol(luz), 0, 12)
        oled.text("Lluvia:" + str(lluvia), 0, 24)
        oled.text(barra(lluvia, 1023), 0, 34)
        oled.text("Luz:" + str(luz), 0, 44)
        oled.text(barra(luz, 1023), 0, 54)
    else:
        oled.text("== HISTORICO ==", 0, 0)
        oled.text("Lecturas:" + str(lecturas), 0, 14)
        oled.text("Lluv:" + str(min_lluvia) + "/" + str(max_lluvia), 0, 28)
        oled.text("Luz:" + str(min_luz) + "/" + str(max_luz), 0, 42)

    oled.show()

    if button_a.was_pressed():
        vista = 1 - vista
    if button_b.was_pressed():
        min_lluvia = 1023; max_lluvia = 0
        min_luz = 1023; max_luz = 0
        lecturas = 0
        display.scroll("RST")

    sleep(2000)
Concepto clave — Funciones que devuelven strings

Las funciones getCondicion(), getSol() y barraProgreso() siguen el principio de separacion de responsabilidades: cada funcion hace una sola cosa y devuelve un resultado. Esto hace el codigo facil de leer, probar y modificar de forma independiente — un habito de programacion muy valioso.


Pruebalo

Verifica el dashboard, las funciones de clasificacion y el sistema de historico. Usa linterna y agua para simular condiciones.

Dashboard principal: la OLED muestra "METEO STATION", la condicion del tiempo y los valores de lluvia y luz con barras de progreso.
Clasificacion correcta: cubre el sensor de lluvia con agua/humedad. El texto pasa de "DESPEJADO" a "NUBLADO" y luego a "LLUVIA" segun el valor.
Barra de progreso: las barras [####------] cambian su longitud proporcionalmente al valor del sensor — no son estaticas.
Boton A — Cambiar vista: al pulsar A, la pantalla cambia a "HISTORICO" con los valores minimos y maximos registrados. Al volver a pulsar A, regresa a la vista principal.
Historico acumulando: el contador de "Lecturas" sube cada 2 segundos. Los valores min/max se actualizan cuando hay nuevos extremos.
Boton B — Reset: al pulsar B, el micro:bit muestra "RST" y los valores del historico vuelven a los valores iniciales (min=1023, max=0, lecturas=0).

Actividades

Los retos finales de la ruta de aprendizaje. Son los mas exigentes — combina todo lo aprendido.

🎯
Reto 1 — Estetica
Barras mas modernas
La funcion barraProgreso usa "#" y "-". Modificala para usar "=" como caracter lleno y "." como caracter vacio. Ejemplo: [====......]. Prueba con diferentes combinaciones de caracteres ASCII.
🎯
Reto 2 — Sensor interno
Temperatura del micro:bit
Añade una tercera "pantalla" al ciclo: cuando el usuario pulse A dos veces seguidas, muestra el sensor interno de temperatura del micro:bit: input.temperature() en MakeCode o temperature() en MicroPython.
🎯
Reto 3 — Alertas
Alerta de inundacion
Implementa un contador: si la lluvia supera 800 durante 3 lecturas consecutivas (no solo una), muestra "ALERTA INUNDACION!" en la OLED y haz parpadear el icono del micro:bit. El contador se resetea si la lluvia baja antes de llegar a 3.
🎯
Reto 4 — Clasificacion
5 tipos de tiempo combinados
Crea una funcion que clasifique el tiempo en 5 categorias combinando lluvia Y luz: Tormenta (lluvia alta + luz baja), Lluvia (lluvia alta + cualquier luz), Nublado (lluvia media + luz baja), Parcial (lluvia baja + luz media), Soleado (lluvia baja + luz alta).

Problemas comunes

Problemas frecuentes en este proyecto. Muchos son de codigo, no de hardware — lee los mensajes de error con atencion.

"La funcion barraProgreso muestra simbolos raros o cuadrados en la pantalla"
La OLED 128x64 con el driver SSD1306 solo puede mostrar caracteres ASCII basicos (codigos 32-127). Caracteres especiales como bloques graficos o letras con tilde se muestran como cuadrados o interrogaciones. Usa solo guiones, almohadillas y brackets para las barras: [####------] funciona perfectamente.
"El historico se resetea cada vez que desenchufo el micro:bit"
Es el comportamiento correcto y esperado: las variables en RAM se pierden al quitar la alimentacion. El micro:bit no tiene almacenamiento persistente de variables normales. Si quieres datos persistentes, tendrias que usar el sistema de almacenamiento de datos del micro:bit v2 (datalogger) — esto va mas alla de este proyecto.
"El boton A no funciona a la vez que el loop — solo responde a veces"
En MakeCode, usa input.onButtonPressed() fuera del forever — esto crea un evento que se ejecuta en cualquier momento, incluso durante el loop. En MicroPython, usa button_a.was_pressed() dentro del loop (no get_presses() que acumula y puede confundirse).
"La OLED muestra texto cortado — la ultima linea no aparece completa"
La pantalla OLED 128x64 tiene espacio para exactamente 8 lineas de texto con la fuente por defecto (8px de altura). Si escribes mas de 8 lineas, el texto sale por debajo de la pantalla. Cuenta siempre cuantas lineas escribes en cada vista: en la vista principal son 6 lineas — caben perfectamente. Si añades mas, elimina o combina alguna.

Mas alla

Algunas ideas para seguir explorando con lo aprendido. Y un reconocimiento muy merecido.

🌐
Estacion exterior
Monta el hardware en una caja impermeable y coloca los sensores en el exterior durante una semana. Compara tus datos con una app meteorologica real.
📡
Radio meteorologica
Usa la radio del micro:bit para enviar datos desde la estacion (exterior) a otro micro:bit receptor (interior). Asi construyes un sistema inalambrico real.
📈
Grafica de datos
Usa el Data Logger del micro:bit v2 para exportar datos al PC. Abre el archivo CSV en Excel o Google Sheets y crea graficas de tendencias a lo largo del dia.
🏠
Red de estaciones
Conecta 3 micro:bits en una red de radio. Cada uno es una estacion diferente. Un cuarto micro:bit "base" recibe datos de las tres y muestra una media.
🎉

¡Has completado la Ruta de Aprendizaje!

Has programado 9 proyectos progresivos con micro:bit — desde un LED parpadeante hasta una estacion meteorologica con dashboard en tiempo real. Ahora sabes controlar sensores, actuadores, pantallas y maquinas de estados.

3
Proyectos
Nivel 1
3
Proyectos
Nivel 2
3
Proyectos
Nivel 3
Ruta
Completada
← Ver todos los proyectos