Objetivo y caso de uso
Qué construirás: Leer datos de temperatura de un sensor I2C utilizando la placa Pico-ICE con el chip RP2040.
Para qué sirve
- Monitoreo de temperatura en proyectos de domótica utilizando sensores DHT22.
- Control de temperatura en invernaderos mediante integración con sistemas de riego.
- Registro de datos ambientales en estaciones meteorológicas de bajo costo.
- Desarrollo de sistemas de alerta para condiciones extremas de temperatura en laboratorios.
Resultado esperado
- Lectura de temperatura con una precisión de ±0.5 °C.
- Transmisión de datos a través de MQTT con una frecuencia de 1 mensaje por segundo.
- Latencia de respuesta del sensor inferior a 100 ms.
- Capacidad de manejar hasta 10 sensores en un mismo bus I2C sin pérdida de datos.
Público objetivo: Estudiantes y entusiastas de la electrónica; Nivel: Básico
Arquitectura/flujo: Sensor I2C conectado a Pico-ICE, datos procesados en MicroPython y enviados a un servidor mediante MQTT.
Nivel: basico
Prerrequisitos
- Hardware de apoyo:
- Un Raspberry Pi (4B, 400, o 5) funcionando como host de desarrollo.
- Conectividad a Internet en el Raspberry Pi para descargar herramientas y firmware.
- Sistema operativo en el host:
- Raspberry Pi OS Bookworm 64‑bit (basado en Debian 12).
- Python en el host:
- Python 3.11 (Bookworm usa Python 3.11 por defecto; verifícalo con
python3 --version, que debería devolver “Python 3.11.x”, típicamente 3.11.2). - Toolchain y utilidades con versiones concretas (host):
- Entorno virtual de Python: venv de Python 3.11.
- mpremote 1.22.2 (cliente oficial para MicroPython).
- pyserial 3.5 (para lectura serie/CDC desde el host).
- i2c-tools 4.3 (opcional; para validar que el bus I2C del host está habilitado, aunque no lo usaremos para el sensor en este caso).
- Firmware del dispositivo (RP2040 en la Pico-ICE):
- MicroPython 1.22.2 para RP2040 (imagen UF2 para Raspberry Pi Pico — compatible con RP2040 de la Pico-ICE).
- Conocimientos previos:
- Conectar componentes con cables Dupont sobre protoboard.
- Usar la terminal en Linux (Raspberry Pi OS).
- Nivel básico de Python.
Notas importantes de coherencia:
– Este caso práctico usa el modelo “Pico-ICE (Lattice iCE40UP5K)”. Trabajaremos exclusivamente con el microcontrolador RP2040 integrado en la placa para implementar el maestro I2C y leer el sensor de temperatura. La FPGA Lattice iCE40UP5K no se programa en este ejercicio básico.
– El sensor I2C se conecta físicamente a los pines del RP2040 presentes en la Pico‑ICE; no conectes el mismo sensor al bus I2C del Raspberry Pi host para evitar conflictos de múltiples maestros en el mismo bus.
Materiales
- 1x Pico-ICE (Lattice iCE40UP5K) — placa con RP2040 + FPGA iCE40UP5K y conector USB‑C.
- 1x Sensor de temperatura I2C: TMP102 o compatible (dirección por defecto 0x48). Cualquier breakout de TMP102 a 3.3 V (p. ej., con regulador y resistencias de pull-up integradas) funciona.
- 1x Cable USB‑C a USB‑A (o a USB‑C, según el puerto del Raspberry Pi) para alimentar/programar la Pico-ICE.
- Cables Dupont hembra‑hembra (al menos 4) para: SDA, SCL, 3V3, GND.
- 1x Protoboard pequeña (opcional, para organizar conexiones).
- Accesorios para validación:
- Dedo/mano para calentar el sensor con contacto.
- Cubitos de hielo o bolsa fría para observar descensos de temperatura.
Preparación y conexión
Habilitar interfaces y preparar el entorno en Raspberry Pi OS Bookworm 64‑bit
Aunque el sensor I2C no se conectará al bus del Raspberry Pi, es buena práctica habilitar I2C en el host y confirmar que el kernel carga los módulos necesarios. Además, configuraremos el entorno Python 3.11 en un venv e instalaremos herramientas exactas.
1) Actualiza el sistema:
– Abre una terminal en el Raspberry Pi y ejecuta:
sudo apt update
sudo apt full-upgrade -y
sudo reboot
2) Habilita I2C desde raspi-config (recomendado):
– Tras reiniciar:
sudo raspi-config
- Interfaz gráfica de texto:
- 3 Interface Options
- I5 I2C
- Enable → Yes
- Finish → Yes (reinicia si lo pide)
3) Alternativa: habilitar I2C editando /boot/firmware/config.txt (opcional si ya hiciste el paso anterior):
echo "dtparam=i2c_arm=on" | sudo tee -a /boot/firmware/config.txt
sudo reboot
4) Instala dependencias y crea un entorno virtual con Python 3.11:
sudo apt install -y python3-venv python3-pip git curl i2c-tools
python3 --version
- Debe mostrar algo como:
Python 3.11.2
5) Crea y activa el venv:
python3 -m venv ~/venv-picoice
source ~/venv-picoice/bin/activate
pip install --upgrade pip
6) Instala las herramientas exactas (versionadas):
pip install mpremote==1.22.2 pyserial==3.5
mpremote --version
python -c "import serial; print(serial.__version__)"
- Debe mostrar:
- mpremote 1.22.2
- 3.5
7) (Opcional pero recomendable) Añade tu usuario al grupo dialout para acceder a /dev/ttyACM0 sin sudo:
sudo usermod -aG dialout $USER
newgrp dialout
8) Descarga la imagen de MicroPython 1.22.2 para RP2040 (UF2):
– Creamos un directorio de trabajo:
mkdir -p ~/pico-ice-i2c-temp && cd ~/pico-ice-i2c-temp
- Descarga (ejemplo de URL para MicroPython 1.22.2 RP2/Pico):
curl -L -o micropython-1.22.2-rp2-pico.uf2 https://micropython.org/resources/firmware/micropython-1.22.2-rp2-pico.uf2
ls -lh micropython-1.22.2-rp2-pico.uf2
Nota: Esta imagen está destinada al RP2040 (Pico). La Pico‑ICE emplea un RP2040 y, para este uso básico, la imagen estándar del Pico funciona correctamente.
Conexión física del sensor TMP102 a la Pico-ICE
Usaremos el bus I2C0 del RP2040 con sus pines por defecto:
– SDA en GP4
– SCL en GP5
– VCC a 3V3
– GND a GND
Muchos breakouts de TMP102 ya incluyen resistencias de pull‑up a 3.3 V, por lo que no se requieren resistencias externas adicionales. No alimentes el sensor con 5 V.
Tabla de mapeo de pines para la conexión:
| Señal del sensor | Pin en sensor TMP102 | Pin en Pico-ICE (RP2040) | Cabecera Pico-ICE (estilo Pico) | Notas |
|---|---|---|---|---|
| VCC (3.3 V) | VCC/3V3 | 3V3(OUT) | Pin físico 36 | Alimentación 3.3 V |
| GND | GND | GND | Cualquier pin GND (p. ej., 38) | Tierra |
| SDA | SDA | GP4 (I2C0 SDA) | Pin físico 6 | Línea de datos I2C |
| SCL | SCL | GP5 (I2C0 SCL) | Pin físico 7 | Línea de reloj I2C |
| ALERT (opcional) | ALRT | No conectado (o GP2 si quieres usarlo) | — | No necesario para lectura básica |
Consejos:
– Asegura conexiones cortas y firmes, sin invertir SDA/SCL.
– Si tu breakout permite seleccionar la dirección I2C (A0/A1/A2 o ADDR), déjalo en la dirección por defecto 0x48 para seguir el código tal cual.
– La Pico‑ICE se conecta al Raspberry Pi mediante USB‑C; ese mismo cable alimenta el RP2040 y proporciona un puerto serie USB‑CDC para logs.
Código completo (MicroPython sobre RP2040)
Trabajaremos con MicroPython 1.22.2. Subiremos un main.py al sistema de archivos del RP2040 en la Pico‑ICE. El script:
– Inicializa I2C0 a 100 kHz en GP4/GP5.
– Hace un escaneo de dispositivos en el bus para confirmar la presencia del TMP102.
– Lee el registro de temperatura (0x00) del TMP102.
– Convierte la lectura de 12 bits a grados Celsius.
– Imprime una línea por segundo con la temperatura.
main.py (MicroPython)
# main.py - Lectura I2C de sensor TMP102 con Pico-ICE (RP2040) y MicroPython 1.22.2
# Autor: Profesor de Ingeniería Electrónica e Informática
# Objetivo: i2c-lectura-sensor-temperatura
import time
from machine import Pin, I2C
# Configuración I2C para RP2040 (I2C0 en GP4=SDA, GP5=SCL)
I2C_ID = 0
PIN_SDA = 4 # GP4
PIN_SCL = 5 # GP5
I2C_FREQ = 100_000 # 100 kHz (válido para TMP102)
# Dirección por defecto del TMP102 (A0=0 => 0x48)
TMP102_ADDR = 0x48
TMP102_TEMP_REG = 0x00
def tmp102_read_celsius(i2c, addr=TMP102_ADDR):
# Lee 2 bytes del registro de temperatura (0x00)
raw = i2c.readfrom_mem(addr, TMP102_TEMP_REG, 2)
msb = raw[0]
lsb = raw[1]
# Formato TMP102: 12 bits de temperatura en complemento a dos,
# resol. 0.0625 °C. El dato está en bits [15:4] (4 bits LSB descartados).
temp_raw = ((msb << 4) | (lsb >> 4)) & 0xFFF
# Ajuste de signo (12 bits)
if temp_raw & 0x800: # bit de signo (bit 11)
temp_raw -= 1 << 12
temp_c = temp_raw * 0.0625
return temp_c
def main():
print("Iniciando: Pico-ICE (RP2040) + TMP102 @ I2C0 (GP4/GP5)")
i2c = I2C(I2C_ID, scl=Pin(PIN_SCL), sda=Pin(PIN_SDA), freq=I2C_FREQ)
# Escaneo del bus para diagnóstico
devices = i2c.scan()
if not devices:
print("No se detectan dispositivos I2C. Verifica cableado y alimentación.")
else:
print("Dispositivos I2C detectados:", [hex(d) for d in devices])
# Verifica que el TMP102 esté en la dirección esperada
if TMP102_ADDR not in devices:
print("Advertencia: no se encontró TMP102 en 0x48.")
print("Si usas otra configuración de ADDR (A0/A1/A2), ajusta TMP102_ADDR.")
else:
print("TMP102 detectado en 0x48. Iniciando lecturas...")
# Bucle principal de lectura
while True:
try:
temp_c = tmp102_read_celsius(i2c, TMP102_ADDR)
print("Temperatura: {:.2f} °C".format(temp_c))
except OSError as e:
# Error típico si el dispositivo no responde en el bus
print("Error I2C/OSError:", e)
except Exception as e:
print("Error inesperado:", e)
time.sleep(1.0)
# Punto de entrada
if __name__ == "__main__":
main()
Explicación breve de partes clave:
– Inicialización de I2C: I2C(0, sda=Pin(4), scl=Pin(5), freq=100000) configura el bus I2C0 del RP2040 en los pines estándar GP4/GP5, a 100 kHz, compatible con TMP102.
– i2c.scan(): útil para comprobar si la dirección 0x48 aparece en el bus tras conectar el sensor.
– Lectura del registro 0x00 del TMP102: se obtienen 2 bytes y se reconstruye el dato de 12 bits en complemento a dos (resolución 0.0625 °C por LSB).
– Bucle infinito: imprime la temperatura cada segundo. Sirve tanto para validación como para logging en el host.
Script opcional en el host para registrar en CSV (Python 3.11)
Este script usa pyserial 3.5 para abrir el puerto CDC del RP2040 (aparece como /dev/ttyACM0) y copiar todas las líneas recibidas a un CSV con timestamp. Es útil para validación y depuración.
# host_log_temp.py - Registro de lecturas desde /dev/ttyACM0 a CSV
# Requiere: Python 3.11, pyserial==3.5
import csv
import sys
import time
import serial
PORT = "/dev/ttyACM0"
BAUD = 115200
OUT_CSV = "log_temp.csv"
def main():
print(f"Abriendo {PORT} @ {BAUD}...")
with serial.Serial(PORT, BAUD, timeout=1) as ser, open(OUT_CSV, "w", newline="") as f:
writer = csv.writer(f)
writer.append(["timestamp_epoch_s", "line_raw"])
print(f"Registrando a {OUT_CSV}. Ctrl+C para detener.")
while True:
try:
line = ser.readline().decode("utf-8", errors="replace").strip()
if line:
writer.writerow([f"{time.time():.3f}", line])
f.flush()
print(line)
except KeyboardInterrupt:
print("\nFin de registro.")
break
except Exception as e:
print("Error:", e, file=sys.stderr)
time.sleep(0.5)
if __name__ == "__main__":
main()
Compilación/flash/ejecución
En este caso no compilamos C/C++; cargamos MicroPython 1.22.2 (UF2) y subimos el main.py al RP2040 de la Pico‑ICE.
1) Poner la Pico‑ICE en modo BOOTSEL (montaje masivo):
– Desconecta la Pico‑ICE del Raspberry Pi (si está conectada).
– Mantén pulsado el botón BOOT (si tu versión lo expone; en la Pico‑ICE el RP2040 tiene modo BOOTSEL como el Pico).
– Conecta el cable USB‑C al Raspberry Pi.
– Suelta el botón BOOT tras 1–2 segundos.
– Debe aparecer un dispositivo de almacenamiento masivo llamado RPI-RP2.
2) Copiar MicroPython 1.22.2 (UF2) al RP2040:
– En el host (Raspberry Pi), asumiendo que el sistema montó la unidad en /media/pi/RPI-RP2:
cd ~/pico-ice-i2c-temp
ls /media/pi | grep RPI-RP2
cp micropython-1.22.2-rp2-pico.uf2 /media/pi/RPI-RP2/
sync
- Al terminar la copia, el dispositivo RPI‑RP2 se desmontará automáticamente y la Pico‑ICE reiniciará con MicroPython.
3) Verifica el puerto serie del RP2040:
dmesg | tail -n 20
ls -l /dev/ttyACM*
- Debes ver algo como /dev/ttyACM0.
4) Subir el script main.py con mpremote 1.22.2:
– Crea el archivo local main.py con el código anterior (si no lo has hecho).
– Conecta mpremote:
source ~/venv-picoice/bin/activate
mpremote connect list
- Debe listar /dev/ttyACM0 como dispositivo disponible.
- Sube el archivo:
mpremote connect /dev/ttyACM0 fs put main.py
- Opcional: ejecuta inmediatamente (aunque al reiniciar se ejecutará solo):
mpremote connect /dev/ttyACM0 run main.py
5) Observar la salida en la REPL:
– Abrir REPL y ver emisiones:
mpremote connect /dev/ttyACM0 repl
- Si el script se está ejecutando, verás líneas tipo:
- “Dispositivos I2C detectados: [‘0x48’]”
- “Temperatura: 23.75 °C”
6) Alternativa de logging desde el host con pyserial:
– En otra terminal:
cd ~/pico-ice-i2c-temp
python host_log_temp.py
- Se creará
log_temp.csvcon las líneas recibidas.
Validación paso a paso
1) Detección del dispositivo I2C:
– Al iniciar, el script imprime el resultado de i2c.scan(). Debe incluir 0x48 si el TMP102 está correctamente cableado.
– Mensaje esperado:
– “Dispositivos I2C detectados: [‘0x48’]”
– “TMP102 detectado en 0x48. Iniciando lecturas…”
– Si no aparece 0x48: revisa cableado y dirección del sensor (ver Troubleshooting).
2) Lectura de temperatura estable:
– Verás lecturas cada segundo, por ejemplo:
– “Temperatura: 22.50 °C”
– “Temperatura: 22.44 °C”
– La temperatura en reposo suele estar entre 20–30 °C según el ambiente.
3) Prueba de calentamiento:
– Toca el sensor con los dedos durante 10–20 s.
– Debe subir al menos 1–3 °C con respecto a la línea base, confirmando que la lectura cambia de forma realista.
4) Prueba de enfriamiento:
– Acerca un cubito de hielo en una bolsa (para evitar agua) a 1–2 cm del sensor, o sopla aire frío.
– Debe observarse un descenso progresivo de la temperatura (1–4 °C o más según el tiempo y proximidad).
5) Verificación del refresco y estabilidad:
– Observa que el intervalo sea de aprox. 1 segundo entre lecturas.
– Si notas lecturas erráticas, comprueba que los cables no sean excesivamente largos y que el breakout tenga pull‑ups integradas. Si no las tiene, añade resistencias de 4.7 kΩ a 3.3 V en SDA y SCL.
6) Validación de persistencia en reinicio:
– Desconecta y reconecta la Pico‑ICE. MicroPython ejecutará main.py automáticamente (si existe en el sistema de archivos interno).
– Debe comenzar a imprimir “Iniciando…” seguido de las lecturas.
Troubleshooting
1) No aparece /dev/ttyACM0 en el host:
– Causas:
– Cable USB defectuoso o solo de carga (sin datos).
– MicroPython no cargó correctamente (no se copió UF2 o copia incompleta).
– Falta de permisos sobre el dispositivo.
– Soluciones:
– Prueba con otro cable USB‑C.
– Repite el proceso BOOTSEL y copia de UF2.
– Añade el usuario al grupo dialout: sudo usermod -aG dialout $USER y vuelve a iniciar sesión.
– Observa dmesg | tail -n 50 para ver mensajes del kernel.
2) i2c.scan() devuelve lista vacía:
– Causas:
– SDA/SCL invertidos.
– Sensor sin alimentación o a 5V por error.
– Cables flojos o pin incorrecto en la Pico‑ICE.
– Falta de pull‑ups en el breakout (poco frecuente si es una placa comercial).
– Soluciones:
– Verifica el mapeo: SDA → GP4, SCL → GP5, VCC → 3V3(OUT), GND → GND.
– Usa cables cortos.
– Asegúrate de que el breakout indica 3.3 V y que VCC está conectado a 3V3 (no a 5V).
3) Dirección I2C distinta a 0x48:
– Causas:
– Pines de dirección (A0/A1/A2 o ADDR) del sensor configurados para otra dirección (0x49–0x4B).
– Soluciones:
– Revisa la hoja de datos y el jumper/soldadura del breakout.
– Cambia TMP102_ADDR = 0x48 en el código a la dirección detectada por i2c.scan().
4) Lecturas inestables o erráticas:
– Causas:
– Cables largos o cercanos a fuentes de ruido.
– Pull‑ups insuficientes si el breakout es “bare”.
– Frecuencia del I2C demasiado alta para la topología del cableado.
– Soluciones:
– Mantén cables cortos.
– Reduce I2C_FREQ a 50 kHz para probar estabilidad.
– Añade resistencias pull‑up de 4.7 kΩ en SDA y SCL a 3.3 V si tu breakout no las tiene.
5) Error OSError: [Errno 5] EIO o similares durante lectura:
– Causas:
– Transacciones interrumpidas por mal contacto.
– Dirección/registros incorrectos para el sensor.
– Soluciones:
– Revisa conexiones físicas.
– Confirma que el sensor es efectivamente un TMP102; si no, adapta el registro y la conversión.
6) El script no arranca automáticamente tras reiniciar:
– Causas:
– main.py no se copió al sistema de archivos del RP2040.
– El archivo se guardó con nombre distinto o en el directorio del host.
– Soluciones:
– Vuelve a subir con mpremote ... fs put main.py.
– Verifica con mpremote ... fs ls que main.py está en la raíz.
7) El host muestra lecturas pero no cambian con el calor/frío:
– Causas:
– Sensor colocado muy lejos o aislado térmicamente.
– Errores de manipulación del dato para otro modelo de sensor.
– Soluciones:
– Toca directamente el encapsulado del sensor (no el plástico del conector).
– Asegúrate de usar el código de conversión correcto para TMP102. Si usas MCP9808 u otro, ajusta la rutina de lectura.
8) Conflicto con I2C del host (Raspberry Pi):
– Causas:
– Conectar el mismo sensor simultáneamente al bus I2C del Pi y al RP2040 en la Pico‑ICE.
– Soluciones:
– No mezclar buses maestros. Mantén el sensor conectado solo a la Pico‑ICE para este ejercicio.
Mejoras/variantes
- Alertas por umbral:
- Usa el pin ALERT del TMP102 para generar una interrupción en un GPIO del RP2040 (p. ej., GP2). Programa el registro de configuración del TMP102 para umbrales de alta/baja y lee el pin en MicroPython para actuar (p. ej., imprimir “ALERTA” o activar una salida digital).
- Filtrado y promediado:
- Implementa un promedio móvil de N muestras para suavizar lecturas. Útil para entornos con ruido.
- Cambio de frecuencia I2C:
- Sube a 400 kHz (fast-mode) si las líneas y el breakout lo soportan, ajustando
I2C_FREQ = 400_000. Valida estabilidad. - Otros sensores I2C:
- MCP9808 (mejor resolución y precisión), BME280/BMP280 (temperatura y presión), SHT31 (humedad y temperatura). Cambia la rutina de lectura y la dirección I2C.
- Registro a CSV con timestamp:
- Extiende
host_log_temp.pypara añadir marca temporal legible (datetime) y escritura de columnas parseadas (solo el valor °C), facilitando graficado con herramientas como LibreOffice Calc o matplotlib. - Integración con la FPGA (avanzado):
- En ejercicios posteriores, la iCE40UP5K podría implementarse como coprocesador o temporizador para gestionar otras tareas mientras el RP2040 mantiene el I2C. Este caso básico no usa la FPGA para mantener el foco en I2C y MicroPython.
- Envío de datos por USB o UART a otro sistema:
- El RP2040 ya emite por USB‑CDC; puedes añadir un protocolo simple (CSV o JSON de una línea) para integración con aplicaciones Python en el host.
- Auto‑detección de dirección I2C:
- En lugar de fijar
TMP102_ADDR, detecta la dirección leyendo la lista dei2c.scan()y seleccionando una dirección válida entre 0x48–0x4B.
Checklist de verificación
- [ ] Raspberry Pi OS Bookworm 64‑bit actualizado y operativo.
- [ ] Python 3.11 verificado en el host (
python3 --version). - [ ] Entorno virtual creado y activado (
~/venv-picoice). - [ ] mpremote 1.22.2 y pyserial 3.5 instalados y verificados.
- [ ] MicroPython 1.22.2 UF2 descargado en
~/pico-ice-i2c-temp/. - [ ] Pico‑ICE se monta como RPI‑RP2 en modo BOOTSEL y UF2 copiado con éxito.
- [ ] Puerto serie USB‑CDC disponible en
/dev/ttyACM0. - [ ] Sensor TMP102 cableado: VCC→3V3, GND→GND, SDA→GP4, SCL→GP5.
- [ ]
main.pysubido al RP2040 conmpremote ... fs put. - [ ] Salida en serie muestra detección de
0x48y lecturas razonables de temperatura. - [ ] La temperatura sube al tocar el sensor y baja con frío.
- [ ] Al reiniciar la Pico‑ICE,
main.pyse ejecuta automáticamente. - [ ] No hay errores I2C recurrentes ni lecturas erráticas; si aparecen, revisión de cables/pull‑ups/frecuencia I2C.
Apéndice: Comandos clave agrupados
- Actualización del sistema:
sudo apt update
sudo apt full-upgrade -y
sudo reboot
- Habilitar I2C (método rápido no interactivo):
sudo raspi-config nonint do_i2c 0
sudo reboot
- Preparación de venv y herramientas:
sudo apt install -y python3-venv python3-pip git curl i2c-tools
python3 -m venv ~/venv-picoice
source ~/venv-picoice/bin/activate
pip install --upgrade pip
pip install mpremote==1.22.2 pyserial==3.5
- Descarga de MicroPython 1.22.2 UF2:
mkdir -p ~/pico-ice-i2c-temp && cd ~/pico-ice-i2c-temp
curl -L -o micropython-1.22.2-rp2-pico.uf2 https://micropython.org/resources/firmware/micropython-1.22.2-rp2-pico.uf2
- Copiado de UF2 (modo BOOTSEL):
cp micropython-1.22.2-rp2-pico.uf2 /media/pi/RPI-RP2/
sync
- Detección del puerto serie:
dmesg | tail -n 50
ls -l /dev/ttyACM*
- Subida y ejecución de main.py:
mpremote connect list
mpremote connect /dev/ttyACM0 fs put main.py
mpremote connect /dev/ttyACM0 run main.py
mpremote connect /dev/ttyACM0 repl
Este caso práctico te guía, de principio a fin, para leer un sensor de temperatura I2C usando exactamente el modelo Pico-ICE (Lattice iCE40UP5K), con un enfoque de nivel básico y una toolchain concreta: Raspberry Pi OS Bookworm 64‑bit, Python 3.11, MicroPython 1.22.2 en el RP2040, y mpremote 1.22.2/pyserial 3.5 en el host. Conexiones, código y comandos están alineados para reproducibilidad y validación rápida por parte del alumno.
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.



