Los sensores comunes de iniciación son módulos para medir magnitudes físicas con poco cableado, como distancia, temperatura, humedad o luz.
Ya sabemos distinguir entre una señal analógica y una digital. Ahora vamos a ensuciarnos las manos conectando los sensores que usarás en el 90% de tus primeros proyectos.
Vamos a cubrir la “Santísima Trinidad” del maker:
- Medir distancias (Ultrasonidos HC-SR04).
- Medir clima (Temperatura/Humedad DHT).
- Medir luz (LDR).
Sensor de ultrasonidos HC-SR04
Este sensor es un clásico absoluto para robots esquiva-obstáculos y medidores de nivel de líquidos. Funciona imitando a los murciélagos: emite un sonido inaudible y espera a escuchar el eco.
El funcionamiento es una secuencia de tiempos precisa:
- Enviamos un pulso de 10µs por el pin Trig (Disparador).
- El sensor lanza 8 pulsos de 40kHz (el “grito” ultrasónico).
- El pin Echo se pone en ALTO (3.3V/5V) y se mantiene así hasta que el sensor escucha el rebote.
- La duración de ese pulso en el pin Echo es el tiempo de vuelo del sonido.
Precaución: el divisor de tensión
El HC-SR04 estándar funciona a 5V.
- El pin Trig suele aceptar los 3.3V de nuestra placa sin problemas.
- PERO: El pin Echo devuelve una señal de 5V.
Si conectas el Echo de 5V directamente a una Raspberry Pi Pico o un ESP32 (que son de 3.3V), puedes quemar el pin.
Solución Obligatoria Necesitas bajar el voltaje del pin Echo. Usa un divisor de tensión simple con dos resistencias:
- Echo del Sensor Resistencia 1kΩ Pin del Microcontrolador.
- Pin del Microcontrolador Resistencia 2kΩ GND.
Código para medir la distancia
Para medir el ancho del pulso de retorno, MicroPython nos regala la función machine.time_pulse_us(), que es mucho más precisa que intentar medirlo nosotros con un bucle.
from machine import Pin, time_pulse_us
import time
# Configuración de pines
# Trig = Salida (Nosotros gritamos)
# Echo = Entrada (Nosotros escuchamos)
trig = Pin(5, Pin.OUT)
echo = Pin(18, Pin.IN)
# Velocidad del sonido: 343 m/s = 0.0343 cm/µs
# Como el sonido va y vuelve, dividimos por 2
# Factor = 0.0343 / 2 = 0.01715
def medir_distancia():
# 1. Asegurar que el trigger está bajo
trig.value(0)
time.sleep_us(2)
# 2. Lanzar pulso de 10us
trig.value(1)
time.sleep_us(10)
trig.value(0)
# 3. Medir cuánto tiempo el pin Echo está en ALTO (1)
# timeout de 30000us (30ms) equivale a unos 5 metros (si tarda más, no hay objeto)
duracion = time_pulse_us(echo, 1, 30000)
if duracion < 0:
return None # Fuera de rango
# 4. Calcular distancia (cm)
distancia = duracion * 0.01715
return distancia
while True:
dist = medir_distancia()
if dist:
print(f"Distancia: {dist:.1f} cm")
else:
print("Nada a la vista o muy lejos")
time.sleep(0.5)
Temperatura y humedad con DHT11 y DHT22
Ya hablamos brevemente de ellos en la sección de sensores digitales, pero como son omnipresentes, vamos a ver el código mínimo funcional aquí.
Estos sensores utilizan un protocolo propio de un solo cable (no es OneWire estándar, aunque se le parece). Afortunadamente, MicroPython incluye el driver.
- DHT11 (Azul): Barato, pero impreciso. Rango 0-50°C.
- DHT22 (Blanco): Mejor opción. Rango -40 a 80°C y decimales.
import dht
from machine import Pin
import time
# Recuerda: Resistencia Pull-Up de 10k entre DATA y 3.3V necesaria
sensor = dht.DHT22(Pin(15))
while True:
try:
sensor.measure() # Toma la muestra
t = sensor.temperature()
h = sensor.humidity()
print(f"Temp: {t}°C | Humedad: {h}%")
except OSError as e:
print("Error al leer sensor")
# IMPORTANTE: No leer más rápido de una vez cada 2 segundos
time.sleep(2)
Sensor de temperatura interno de la CPU
¿Sabías que tu microcontrolador ya tiene un termómetro dentro? Se usa para monitorizar la temperatura del núcleo del chip, pero puede servirnos como aproximación de la temperatura ambiente si la placa no está haciendo tareas pesadas (que calienten la CPU).
En Raspberry Pi Pico (RP2040)
El sensor interno está conectado al canal 4 del ADC.
import machine
import time
sensor_temp = machine.ADC(4)
factor_conversion = 3.3 / 65535
while True:
lectura = sensor_temp.read_u16() * factor_conversion
# Fórmula del datasheet del RP2040:
# Temperatura = 27 - (Voltaje - 0.706) / 0.001721
temperatura = 27 - (lectura - 0.706) / 0.001721
print(f"CPU Temp: {temperatura:.1f} °C")
time.sleep(1)
En ESP32
La disponibilidad cambia según la variante. El ESP32 original expone esp32.raw_temperature() (en grados Fahrenheit), mientras que variantes como ESP32-C3, C6, S2 y S3 ofrecen esp32.mcu_temperature() (en grados Celsius). En ambos casos se mide la temperatura interna del chip, no la temperatura ambiente, por lo que para medir una habitación debes usar un sensor externo.
Fotorresistencia (LDR) e histéresis
La LDR es una resistencia que cambia con la luz. Ya vimos cómo leerla con el ADC en el capítulo anterior. Pero, ¿cómo la usamos para encender una farola automática de forma robusta?
Si simplemente decimos if luz < 500: encender, cuando la luz esté justo en 500, cualquier ruido eléctrico hará que lea 499, 501, 499… y la lámpara parpadeará como loca.
Para evitarlo, usamos la Histéresis (o ventana de margen).
from machine import Pin, ADC
import time
ldr = ADC(Pin(26)) # Pin ADC (GP26 en Pico, GPIO34 en ESP32)
rele = Pin(16, Pin.OUT)
# Umbrales separados
UMBRAL_NOCHE = 20000 # Si baja de esto, encendemos
UMBRAL_DIA = 25000 # Si sube de esto, apagamos
# Estado actual
luces_encendidas = False
while True:
luz = ldr.read_u16()
print(f"Nivel de luz: {luz}")
if luces_encendidas and luz > UMBRAL_DIA:
print("Ya es de día. Apagando.")
rele.value(0)
luces_encendidas = False
elif not luces_encendidas and luz < UMBRAL_NOCHE:
print("Se ha hecho de noche. Encendiendo.")
rele.value(1)
luces_encendidas = True
time.sleep(0.5)
Con este código, la luz debe cambiar significativamente para cambiar el estado, evitando parpadeos en el atardecer.
Precauciones que conviene recordar
Con estos tres componentes (HC-SR04, DHT22 y LDR) tienes cubiertas las necesidades básicas de percepción del entorno:
- Usa divisores de tensión con sensores de 5V (como el HC-SR04).
- Respeta los tiempos de refresco (2s para el DHT).
- Implementa histéresis en sensores analógicos para evitar inestabilidad.
¡Ahora tu código puede reaccionar a lo que ocurre fuera del chip!