micropython-lectura-sensores-digitales-analogicos

Lectura de sensores digitales y analógicos en MicroPython

  • 5 min

Un sensor es un dispositivo que convierte una magnitud física en una señal eléctrica que podemos leer.

Hasta ahora hemos aprendido a usar los pines GPIO y el ADC desde un punto de vista puramente electrónico. Sabemos leer un 1 o un 0, y sabemos leer un voltaje de 0V a 3.3V.

Pero en el mundo real, no nos interesa el voltaje. Nos interesa saber si hay alguien en la habitación (Digital) o cuánta luz hay (Analógico).

En esta entrada vamos a conectar sensores reales y, lo más importante, vamos a aprender a procesar sus datos para que tengan sentido dentro de nuestro programa.

Sensores digitales: todo o nada

Un sensor digital es, en esencia, un interruptor automático. Solo tiene dos estados posibles: Activado o Desactivado.

Ejemplos típicos:

  • PIR (HC-SR501): Detecta movimiento infrarrojo.
  • Sensor de Obstáculos IR: Detecta si algo refleja la luz cerca.
  • Sensor de Inclinación (Tilt): Una bolita metálica que cierra el circuito si se mueve.
  • Sensor Hall: Detecta campos magnéticos.

Niveles de tensión: 3,3 V y 5 V

¡Cuidado con los sensores de Arduino! Muchos módulos de sensores baratos están diseñados para 5V. Si un sensor digital “envía” 5V por su pin de salida cuando se activa, y lo conectas directo a tu ESP32 o Raspberry Pi Pico (que funcionan a 3.3V), puedes quemar el pin.

  • PIR HC-SR501: Funciona a 5V, pero su señal de salida suele ser de 3.3V (compatible).
  • Sensores industriales: A menudo usan 12V o 24V (necesitas optoacopladores).

Ejemplo: sensor de movimiento PIR

Vamos a usar un sensor PIR HC-SR501. Tiene 3 pines: VCC (5V), GND y OUT. Cuando detecta movimiento, pone el pin OUT en HIGH (3.3V) durante un tiempo.

from machine import Pin
import time

# Configuramos el pin del sensor como ENTRADA
# No necesitamos Pull-up porque el sensor ya envía voltaje activo
pir = Pin(14, Pin.IN)

# LED para indicar la detección
led = Pin(2, Pin.OUT)

print("Iniciando vigilancia...")
time.sleep(2) # El PIR necesita un tiempo para "calibrarse" al arrancar

while True:
    estado = pir.value()
    
    if estado == 1:
        print("¡Movimiento detectado!")
        led.value(1)
    else:
        led.value(0)
        
    time.sleep(0.1)
Copied!

Para este tipo de sensores que mantienen la señal activa unos segundos, el polling (bucle while) funciona bien. Para sensores muy rápidos (como un sensor Hall al pasar una rueda), deberíamos usar Interrupciones (IRQ) como vimos en capítulos anteriores.

Sensores analógicos: un espectro continuo

Aquí la cosa se pone interesante. Queremos medir magnitudes que varían suavemente: la intensidad de luz, la temperatura, la humedad del suelo, la fuerza ejercida.

La mayoría de estos sensores básicos son Resistivos. Esto significa que varían su resistencia eléctrica según la magnitud física.

  • LDR (Fotorresistencia): Menos luz = Más resistencia.
  • Termistor NTC: Más calor = Menos resistencia.
  • Potenciómetro: Varía según el giro.

El divisor de tensión

El ADC de nuestro microcontrolador solo sabe medir voltaje, no resistencia. No puedes conectar una LDR directamente entre el pin y GND. No funcionará.

Necesitamos convertir esa variación de resistencia en una variación de voltaje. Para ello usamos el circuito más famoso de la electrónica: el Divisor de Tensión.

Conectamos el sensor en serie con una resistencia fija (normalmente 10kΩ).

  1. VCC (3.3V) Patilla 1 de la LDR.
  2. Punto Medio Patilla 2 de LDR + Resistencia 10k + Pin ADC.
  3. GND El otro extremo de la resistencia 10k.

Ejemplo: interruptor crepuscular con LDR

Vamos a leer una LDR. Recuerda que el ADC en MicroPython devuelve un valor de 0 a 65535 (u16).

from machine import Pin, ADC
import time

# Configuración del ADC
# En ESP32: Pin 34 (ADC1) es solo entrada, ideal para sensores
# En Pico: Pin 26 (ADC0)
sensor_luz = ADC(Pin(34))

# Atenuación (Solo ESP32): Para leer el rango completo 0-3.3V
# sensor_luz.atten(ADC.ATTN_11DB) 

while True:
    # 1. Lectura cruda (Raw)
    lectura = sensor_luz.read_u16()
    
    # 2. Convertir a Voltaje (Opcional, para debug)
    voltaje = (lectura / 65535) * 3.3
    
    # 3. Lógica de control
    # Experimentalmente, vemos que con luz ambiente da unos 40000
    # y tapándola baja a 10000 (o sube, depende de tu cableado LDR/Resistencia)
    
    print(f"Valor RAW: {lectura} | Voltaje: {voltaje:.2f}V")
    
    if lectura < 20000: # Ajusta este umbral según tu resistencia
        print("Está oscuro -> Encender luces")
    else:
        print("Hay luz -> Apagar luces")
        
    time.sleep(0.5)
Copied!

Mapeo de valores con una función map

A menudo no queremos trabajar con números raros como 45320, sino con un porcentaje 0-100%. Arduino tiene la función map(), pero Python no.

Vamos a crear nuestra propia función de mapeo para normalizar sensores.

def map_value(x, in_min, in_max, out_min, out_max):
    # Regla de tres para escalar el valor
    valor = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
    # Limitamos para no salirnos del rango (clamping)
    return max(min(valor, out_max), out_min)

# Ejemplo de uso con un potenciómetro
# Supongamos que nuestro pote no llega perfecto a 0 o 65535 por tolerancias
valor_raw = sensor_luz.read_u16()

# Convertimos de 1000-60000 a 0-100%
porcentaje = map_value(valor_raw, 1000, 60000, 0, 100)

print(f"Luz: {int(porcentaje)} %")
Copied!

Filtrado de ruido mediante el promedio

Los sensores analógicos suelen tener “ruido”. Si lees el sensor muy rápido, verás que los valores bailan: 34050, 34100, 33950. Esto puede hacer que tu sistema parpadee erráticamente.

La solución más sencilla por software es hacer un Promedio simple.

def leer_promedio(adc_pin, muestras=10):
    suma = 0
    for _ in range(muestras):
        suma += adc_pin.read_u16()
        time.sleep_ms(5) # Pequeña pausa entre lecturas
    return suma // muestras

# Uso
lectura_estable = leer_promedio(sensor_luz)
Copied!

Antes de conectar un sensor

Integrar sensores no es solo conectar cables. Requiere:

  1. Saber si es Digital (Estados) o Analógico (Valores).
  2. Asegurar los voltajes (cuidado con 5V).
  3. Usar Divisores de Tensión para sensores resistivos.
  4. Procesar los datos (mapeo y filtrado) para que sean útiles.

Con estos fundamentos, ya puedes conectar casi cualquier sensor simple que encuentres en el mercado.