Objetivo y caso de uso
Qué construirás: Un sistema para leer la temperatura utilizando un sensor I2C conectado a la placa Pico-ICE RP2040 y validando los datos en una Raspberry Pi.
Para qué sirve
- Monitoreo de temperatura en entornos industriales utilizando sensores I2C.
- Control de climatización en invernaderos mediante lectura de temperatura en tiempo real.
- Desarrollo de proyectos de IoT que requieren datos de temperatura precisos.
- Integración de datos de temperatura en sistemas de automatización del hogar.
Resultado esperado
- Lectura de temperatura con una precisión de ±0.5 °C.
- Actualización de datos cada 2 segundos a través de I2C.
- Latencia de respuesta inferior a 100 ms al consultar el sensor desde Raspberry Pi.
- Capacidad de enviar datos a un servidor MQTT con un intervalo de 5 segundos.
Público objetivo: Desarrolladores y entusiastas de la electrónica; Nivel: Medio
Arquitectura/flujo: Sensor I2C conectado a Pico-ICE RP2040, datos leídos y procesados en Raspberry Pi.
Nivel: Medio
Prerrequisitos
En este caso práctico trabajaremos con el microcontrolador RP2040 incluido en la placa “Pico-ICE (RP2040 + iCE40UP5K)”, conectando un sensor de temperatura por I2C y validando la lectura desde un equipo “host” Raspberry Pi con Raspberry Pi OS Bookworm 64‑bit.
Sistema operativo y versiones probadas
- Raspberry Pi OS Bookworm 64‑bit (kernel 6.x), actualizado a fecha reciente.
- Python 3.11 (versión incluida por defecto en Bookworm: 3.11.x).
Toolchain exacta utilizada (probada y recomendada)
Herramientas para compilar y depurar el firmware del RP2040 con el SDK de Raspberry Pi:
- Raspberry Pi Pico SDK: v1.5.1
- CMake: 3.25.1
- Arm GNU Toolchain (arm-none-eabi-gcc): 12.2.Rel1
- picotool: 1.1.0
- i2c-tools (host): 4.3
- Python paquetes (host, en venv):
- pyserial==3.5
- rich==13.7.1
Nota: En este caso práctico no sintetizaremos lógica para el FPGA iCE40UP5K, pero si deseas tener el toolchain listo para futuras ampliaciones con el FPGA de la Pico-ICE, estas versiones funcionan correctamente en Raspberry Pi OS Bookworm:
– Yosys: 0.29
– nextpnr-ice40: 0.4
– Project IceStorm: 0.0+20230110
Habilitar interfaces en la Raspberry Pi (host)
- I2C del host (útil para herramientas de diagnóstico como i2cdetect, aunque el I2C principal lo usará el RP2040 en la Pico-ICE):
- Interactivo: sudo raspi-config
- Interface Options → I2C → Enable.
- O bien editando en el host:
- Añadir/asegurar dtoverlay=i2c‑arm en /boot/firmware/config.txt
- Serie:
- Para usar /dev/ttyACM0 (USB CDC del RP2040) no necesitas activar UART del GPIO de la Pi. Basta con pertenecer al grupo dialout.
Preparación de entorno Python (host)
1) Crear un entorno virtual y activarlo.
2) Instalar pyserial y rich.
Comandos exactos (host Raspberry Pi):
sudo apt update
sudo apt install -y python3-venv python3-pip i2c-tools cmake git gcc-arm-none-eabi gdb-multiarch build-essential picotool minicom
# (Opcional) Verificar versiones principales
cmake --version # Debe indicar 3.25.1 en Bookworm
arm-none-eabi-gcc --version # "12.2.Rel1"
picotool --version # "picotool v1.1.0" (o cercano)
# Crear venv para las utilidades en Python
python3 -m venv ~/venvs/pico-ice-env
source ~/venvs/pico-ice-env/bin/activate
pip install --upgrade pip
pip install pyserial==3.5 rich==13.7.1
Para trabajar con el SDK del RP2040:
# Obtener pico-sdk v1.5.1 y pico-examples (solo para referencias si lo deseas)
mkdir -p ~/pico
cd ~/pico
git clone -b 1.5.1 https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git submodule update --init
# (Opcional) ejemplos
cd ..
git clone -b 1.5.1 https://github.com/raspberrypi/pico-examples.git
Configura la variable de entorno PICO_SDK_PATH en tu shell (puedes añadirla a ~/.bashrc):
echo 'export PICO_SDK_PATH=$HOME/pico/pico-sdk' >> ~/.bashrc
source ~/.bashrc
Tabla de herramientas y versiones
| Componente | Versión | Comando de verificación |
|---|---|---|
| Raspberry Pi OS | Bookworm 64‑bit | cat /etc/os-release |
| Python | 3.11.x | python3 –version |
| Raspberry Pi Pico SDK | v1.5.1 | echo $PICO_SDK_PATH; ls $PICO_SDK_PATH |
| CMake | 3.25.1 | cmake –version |
| GCC Arm (arm-none-eabi) | 12.2.Rel1 | arm-none-eabi-gcc –version |
| picotool | 1.1.0 | picotool –version |
| i2c-tools | 4.3 | i2cdetect -V |
| pyserial | 3.5 | python -c «import serial; print(serial.version)» |
| rich | 13.7.1 | python -c «import rich, sys; print(rich.version)» |
| (Opc.) Yosys | 0.29 | yosys -V |
| (Opc.) nextpnr-ice40 | 0.4 | nextpnr-ice40 –version |
| (Opc.) IceStorm | 0.0+20230110 | icepack -V (o strings sobre binarios) |
Materiales
- 1× Pico-ICE (RP2040 + iCE40UP5K).
- 1× Sensor de temperatura I2C: TMP102 (módulo de 3.3 V, típico en breakout de Adafruit o SparkFun).
- 1× Cable USB-C a USB-A (la Pico-ICE suele emplear conector USB-C) para conectar a la Raspberry Pi host.
- 1× Protoboard y 4× cables dupont M-F.
- (Opcional) 2× resistencias de 4.7 kΩ como pull-up de SDA/SCL si tu breakout no las integra (muchos módulos de TMP102 ya las incluyen).
- (Opcional) Lupa o multímetro para verificar continuidad.
Recomendación: verifica que el módulo TMP102 tenga resistencias pull-up en SDA/SCL. Si no estás seguro, consulta su hoja de datos o el serigrafiado del breakout.
Preparación y conexión
Preparación del entorno de trabajo (host Raspberry Pi)
1) Actualiza el sistema:
– sudo apt update && sudo apt full-upgrade -y
– Reinicia si hay actualización del kernel: sudo reboot
2) Asegura pertenencia al grupo dialout para acceder a /dev/ttyACM0 sin sudo:
– sudo usermod -aG dialout $USER
– cierra sesión y vuelve a entrar, o ejecuta newgrp dialout.
3) Habilita I2C del host (útil para i2cdetect y diagnóstico):
– sudo raspi-config → Interface Options → I2C → Enable
– o edita /boot/firmware/config.txt (dtoverlay=i2c-arm) y reinicia.
4) Prepara el venv de Python con pyserial y rich (ya mostrado en prerrequisitos).
Conexiones entre Pico-ICE y el TMP102
Vamos a usar I2C0 del RP2040 en los pines GP4 (SDA) y GP5 (SCL), que son el mapeo “clásico” del Pico y compatibles con muchas bibliotecas y ejemplos.
Conexión recomendada:
- Alimentación:
- 3V3 (de la Pico-ICE) → VCC del TMP102
- GND (de la Pico-ICE) → GND del TMP102
- I2C:
- GP4 (I2C0 SDA) → SDA del TMP102
- GP5 (I2C0 SCL) → SCL del TMP102
- Dirección:
- ADD0/ADDR del TMP102 → GND para dirección 0x48 (dirección por defecto más común)
- ALERT/INT → sin conectar (no lo usaremos en este ejercicio)
Tabla de conexión de pines:
| Señal | Pin en Pico-ICE (RP2040) | Pin en TMP102 |
|---|---|---|
| Alimentación | 3V3 | VCC |
| Tierra | GND | GND |
| I2C SDA | GP4 | SDA |
| I2C SCL | GP5 | SCL |
| Selección direc. | — | ADD0 → GND |
| Alarma (opcional) | — | ALERT (NC) |
Notas:
– El bus I2C requiere resistencias pull‑up en SDA y SCL (típicamente 4.7 kΩ). Muchos breakouts las integran. Si tu módulo no las tiene, añade las pull-up a 3V3.
– El RP2040 permite activar pull-ups internos, pero son débiles; no sustituyen correctamente a unas pull-up externas en buses I2C de cierta longitud/ruido.
Código completo
A continuación presentamos el firmware completo en C basado en el Raspberry Pi Pico SDK v1.5.1 para:
– Inicializar I2C0 a 100 kHz en GP4/GP5.
– Detectar el dispositivo en 0x48.
– Leer la temperatura del registro 0x00 del TMP102.
– Enviar por USB CDC (stdout) un JSON por línea con la lectura, cada 500 ms.
Incluimos además el CMakeLists.txt mínimo del proyecto. Después proporcionamos un pequeño script Python (host) para escuchar las líneas por /dev/ttyACM0 y mostrarlas con formato.
main.c (firmware RP2040: lectura I2C del TMP102 y envío por USB)
// main.c
// Proyecto: i2c-temperature-sensor-readout en Pico-ICE (RP2040 + iCE40UP5K)
// Toolchain: Pico SDK v1.5.1, arm-none-eabi-gcc 12.2.Rel1, CMake 3.25.1
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#define I2C_PORT i2c0
#define I2C_SDA_PIN 4 // GP4 para SDA de I2C0
#define I2C_SCL_PIN 5 // GP5 para SCL de I2C0
#define I2C_BAUDRATE 100000
// Dirección por defecto del TMP102 con ADD0 a GND
#define TMP102_ADDR 0x48
#define TMP102_TEMP_REG 0x00
static bool i2c_device_present(uint8_t addr) {
// Intento de escribir 0 bytes con STOP, típico para detectar NACK/ACK
uint8_t dummy = 0x00;
int ret = i2c_write_blocking(I2C_PORT, addr, &dummy, 1, false);
return (ret >= 0);
}
static bool tmp102_read_temp_c(float *temp_c) {
uint8_t reg = TMP102_TEMP_REG;
uint8_t buf[2] = {0};
// Escribimos el puntero de registro con 'no stop' para generar un repeated start
int w = i2c_write_blocking(I2C_PORT, TMP102_ADDR, ®, 1, true);
if (w < 0) return false;
int r = i2c_read_blocking(I2C_PORT, TMP102_ADDR, buf, 2, false);
if (r < 0) return false;
// TMP102: 12-bit, MSB first: [T11..T4] en buf[0], [T3..T0 xxxx] en buf[1]
int16_t raw = ((buf[0] << 8) | buf[1]) >> 4;
// Signo si bit 11 está a 1
if (raw & 0x800) {
raw |= 0xF000; // extender signo 12-bit a 16-bit
}
*temp_c = raw * 0.0625f; // cada LSB = 0.0625°C
return true;
}
int main() {
stdio_init_all();
// Espera hasta que el host abra el CDC (opcional, timeout)
const uint32_t start = to_ms_since_boot(get_absolute_time());
while (!stdio_usb_connected()) {
if (to_ms_since_boot(get_absolute_time()) - start > 3000) break;
tight_loop_contents();
}
// Inicialización de I2C
i2c_init(I2C_PORT, I2C_BAUDRATE);
gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
// Pull-ups internos débiles (recomendado disponer de pull-ups externos en el breakout)
gpio_pull_up(I2C_SDA_PIN);
gpio_pull_up(I2C_SCL_PIN);
// LED (si la Pico-ICE mantiene el LED en GP25)
const uint LED_PIN = 25;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
bool led = false;
// Comprobación del dispositivo I2C
bool found = i2c_device_present(TMP102_ADDR);
// Mensaje de cabecera JSON para fácil parsing en el host
printf("{\"event\":\"boot\",\"sdk\":\"1.5.1\",\"i2c_baud\":%u,\"tmp102_addr\":\"0x%02X\",\"present\":%s}\n",
I2C_BAUDRATE, TMP102_ADDR, found ? "true" : "false");
// Bucle principal
while (true) {
float t_c = 0.0f;
bool ok = tmp102_read_temp_c(&t_c);
// Timestamps de milisegundos desde arranque para depuración
uint32_t ms = to_ms_since_boot(get_absolute_time());
if (ok) {
printf("{\"ts_ms\":%u,\"addr\":\"0x%02X\",\"temp_c\":%.4f}\n", ms, TMP102_ADDR, t_c);
} else {
printf("{\"ts_ms\":%u,\"addr\":\"0x%02X\",\"error\":\"i2c_read_failed\"}\n", ms, TMP102_ADDR);
}
// Parpadeo del LED a 1 Hz aprox.
led = !led;
gpio_put(LED_PIN, led);
sleep_ms(500);
}
return 0;
}
Puntos clave del código:
– i2c_write_blocking(…, nostop=true) + i2c_read_blocking(…) implementa la lectura con “repeated start” que exigen muchos sensores.
– La conversión a temperatura toma el dato de 12 bits en complemento a dos y lo multiplica por 0.0625 °C/LSB.
– La salida en JSON por línea hace muy sencilla la validación con Python en el host.
CMakeLists.txt
# CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(i2c_temp_pico_ice C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(i2c_temp_pico_ice
main.c
)
target_link_libraries(i2c_temp_pico_ice
pico_stdlib
hardware_i2c
)
# Habilitar STDIO por USB y deshabilitar UART
pico_enable_stdio_usb(i2c_temp_pico_ice 1)
pico_enable_stdio_uart(i2c_temp_pico_ice 0)
pico_add_extra_outputs(i2c_temp_pico_ice)
Script Python (host) para leer /dev/ttyACM0 y mostrar lecturas
Este script abre el puerto serie USB de la Pico-ICE (CDC ACM) y parsea las líneas JSON, mostrando la temperatura y una barra visual simple.
# host_read_serial.py
# Requiere: pyserial==3.5, rich==13.7.1 (en el venv)
import json
import sys
import time
import serial
from rich.console import Console
from rich.table import Table
PORT = "/dev/ttyACM0"
BAUD = 115200
def main():
console = Console()
console.print(f"[bold green]Abriendo puerto {PORT} a {BAUD} baudios...[/bold green]")
try:
ser = serial.Serial(PORT, BAUD, timeout=2)
except Exception as e:
console.print(f"[bold red]Error al abrir {PORT}: {e}[/bold red]")
sys.exit(1)
# Tabla dinámica
table = Table(title="Lectura TMP102 desde Pico-ICE (USB CDC)")
table.add_column("ts_ms", justify="right")
table.add_column("addr")
table.add_column("temp_c", justify="right")
table.add_column("bar")
# Leer líneas indefinidamente
try:
while True:
line = ser.readline().decode("utf-8", errors="ignore").strip()
if not line:
continue
# Intenta parsear JSON; si falla, lo muestra crudo
try:
obj = json.loads(line)
if "temp_c" in obj:
t = float(obj["temp_c"])
ts = obj.get("ts_ms", "")
addr = obj.get("addr", "")
# Barra proporcional simple
bars = int(max(0, min(50, (t + 10) * 1.5)))
bar = "█" * bars
table.rows = [] # limpiar y mostrar solo la última
table.add_row(str(ts), str(addr), f"{t:0.2f}", bar)
console.clear()
console.print(table)
else:
console.print(f"[yellow]{line}[/yellow]")
except json.JSONDecodeError:
console.print(f"[cyan]{line}[/cyan]")
except KeyboardInterrupt:
console.print("[bold]Saliendo[/bold]")
finally:
ser.close()
if __name__ == "__main__":
main()
Compilación, flasheo y ejecución
1) Estructura de proyecto y configuración
Crea la estructura del proyecto en tu home:
cd ~
mkdir -p pico-projects/i2c_temp_pico_ice
cd pico-projects/i2c_temp_pico_ice
Copia dentro main.c y CMakeLists.txt tal como se han mostrado.
Verifica que la variable de entorno PICO_SDK_PATH está definida y apunta a ~/pico/pico-sdk (v1.5.1):
echo $PICO_SDK_PATH
ls $PICO_SDK_PATH
2) Generación con CMake y compilación
mkdir -p build
cd build
cmake -DPICO_SDK_PATH=${PICO_SDK_PATH} ..
make -j$(nproc)
Al finalizar, deberías ver artefactos:
– i2c_temp_pico_ice.uf2
– i2c_temp_pico_ice.elf
– i2c_temp_pico_ice.bin
3) Flasheo por BOOTSEL (UF2)
1) Conecta la Pico-ICE a la Raspberry Pi host por USB-C.
2) Mantén pulsado el botón BOOTSEL de la Pico-ICE y entonces enchufa o pulsa RESET (si existe). La unidad RPI-RP2 aparecerá montada en /media/pi/RPI-RP2 (la ruta puede variar).
3) Copia el UF2:
# Ajusta la ruta de montaje si es diferente
cp i2c_temp_pico_ice.uf2 /media/$USER/RPI-RP2/
sync
La Pico-ICE se reiniciará automáticamente ejecutando el firmware.
4) Verificación con picotool (opcional)
picotool info -a
Debería mostrar información del binario cargado.
5) Ejecución (lectura por USB CDC desde el host)
- Lista dispositivos: ls /dev/ttyACM*
- Ejecuta el script Python en el venv:
source ~/venvs/pico-ice-env/bin/activate
python ~/pico-projects/i2c_temp_pico_ice/host_read_serial.py
Deberás ver la tabla actualizándose con la temperatura. Toca el sensor con un dedo y observa cómo sube la lectura.
Validación paso a paso
1) Alimentación y enumeración USB:
– dmesg | tail debe mostrar un dispositivo CDC ACM al conectar la Pico-ICE.
– Comprueba /dev/ttyACM0 (o /dev/ttyACM1 si tienes otros).
2) Mensaje de arranque (JSON):
– Al abrir el puerto, deberías ver una línea similar a:
– {«event»:»boot»,»sdk»:»1.5.1″,»i2c_baud»:100000,»tmp102_addr»:»0x48″,»present»:true}
– “present”: true indica que el RP2040 recibió ACK del dispositivo en 0x48 al inicio.
3) Lecturas periódicas:
– Cada ~500 ms: {«ts_ms»:…, «addr»:»0x48″,»temp_c»:…}
– Temperatura ambiente típica: 20–30 °C en interiores.
4) Prueba térmica:
– Toca el sensor con tu dedo 5–10 s. La lectura debería subir 2–6 °C.
– Soplar aire frío o acercarlo a una ventana abierta debería bajar la lectura.
5) Robustez del parsing:
– El script Python refresca una tabla con la última lectura. Si desconectas y reconectas el cable, vuelve a ejecutar el script tras que aparezca /dev/ttyACM0.
6) Verificación básica de I2C del host (opcional):
– Aunque el sensor está cableado al RP2040, puedes usar i2cdetect -l para listar buses del host y confirmar que I2C del host está activo. No debes ver el TMP102 en el bus del host (salvo que lo re‑cables, lo cual no es necesario en este caso práctico). Este paso sirve únicamente para confirmar que i2c-tools funcionan.
Troubleshooting (errores típicos y soluciones)
1) No aparece /dev/ttyACM0:
– Verifica el cable USB-C (datos, no solo carga).
– Prueba otro puerto USB de la Raspberry Pi.
– Revisa dmesg | tail para mensajes de enumeración.
– Comprueba pertenecer al grupo dialout: groups $USER
– Reinicia la Raspberry Pi si todo falla.
2) “present:false” en el mensaje de arranque:
– Direccionamiento del TMP102: ADD0 a GND → 0x48. Si tu breakout cambia la dirección, ajusta TMP102_ADDR en el código (0x49, 0x4A, 0x4B según cableado ADD0).
– Comprueba wiring: GP4→SDA, GP5→SCL, 3V3→VCC, GND→GND.
– Asegura pull-ups efectivas en SDA/SCL (4.7 kΩ a 3.3 V). Las internas del RP2040 son débiles.
3) Lecturas erráticas o NaN:
– Verifica continuidad de cables y calidad del contacto en la protoboard.
– Reduce la frecuencia I2C a 100 kHz (ya está en 100 kHz); si la subiste, vuelve a 100 kHz.
– Aleja cables I2C de fuentes de ruido (motores, convertidores DC-DC sin blindaje).
4) “i2c_read_failed” esporádicos:
– Revisa la alimentación del sensor (VCC estable 3.3 V).
– Asegúrate de que no hay dos dispositivos con la misma dirección en el mismo bus (si añadiste otros sensores).
– Acorta los cables I2C o mejora el ruteo.
5) El LED no parpadea:
– Algunas variantes/ensamblajes pueden no tener LED en GP25 o estar cableado al FPGA. El programa no depende del LED; usa la salida por serie como validación principal. Si lo deseas, comenta el bloque del LED.
6) El script Python no muestra nada:
– Verifica que el puerto sea correcto (/dev/ttyACM0 vs ACM1).
– Asegura que el venv está activado y pyserial instalado.
– Prueba minicom -D /dev/ttyACM0 -b 115200 para ver las líneas crudas.
7) Error de compilación con pico-sdk:
– Asegura PICO_SDK_PATH apuntando a la ruta del pico-sdk v1.5.1 correctamente.
– Ejecuta git submodule update –init desde pico-sdk si faltan submódulos.
– Verifica cmake –version y arm-none-eabi-gcc –version coinciden con las versiones listadas.
8) Fallo al copiar el UF2:
– Debes entrar en modo BOOTSEL: mantener pulsado BOOTSEL al conectar o reiniciar.
– Asegura que la unidad RPI-RP2 se monta (usa lsblk o dmesg).
– Si el sistema monta en solo lectura o falla, prueba otro cable USB o puerto.
Mejoras/variantes
1) Cambiar de I2C0 a I2C1:
– Usa GP6 (SDA1) y GP7 (SCL1) o cualquier par alternativo del RP2040 compatible.
– Cambia I2C_PORT a i2c1 y actualiza los pines en el código.
2) Añadir filtrado/estadística:
– Calcula media móvil o mediana sobre N lecturas.
– Publica min/max y desviación estándar en el JSON.
3) Compatibilidad con otros sensores I2C:
– MCP9808 (0x18/0x19/0x1A/0x1C): cambio de registro y fórmula de conversión.
– LM75/TMP75: lectura de 9 a 12 bits; ajustar parsing.
4) Alerta de temperatura:
– Configurar el registro de T_HIGH/T_LOW del TMP102 y usar ALERT.
– Hacer que el RP2040 envíe un evento JSON en cada alerta.
5) Integración con el FPGA iCE40UP5K (Pico-ICE):
– Usa el valor de temperatura para modular un color en un LED RGB controlado por el FPGA.
– Toolchain recomendado (si decides dar el paso):
– Yosys 0.29, nextpnr-ice40 0.4, IceStorm 0.0+20230110.
– Crea un PWM RGB sencillo en Verilog conectado a pines del FPGA cableados al LED RGB de la Pico-ICE y recibe el dato del RP2040 por un bus simple (por ejemplo, SPI o un latch de GPIO si la placa expone dicho nexo). Esta parte excede el alcance del caso práctico actual, pero la preparación de toolchain ya está indicada.
6) Registro y visualización:
– En el host, guarda JSONL a fichero y grafica con matplotlib o con herramientas como Grafana/Telegraf.
– Añade marca de tiempo del sistema en lugar de ts_ms local de firmware.
7) Robustez:
– Implementa reintentos en I2C y watchdog.
– Detecta desconexión del sensor y re‑inicializa bus.
Checklist de verificación
- [ ] Raspberry Pi OS Bookworm 64‑bit actualizado.
- [ ] Python 3.11 disponible y venv creado/activado.
- [ ] Toolchain instalada con versiones:
- [ ] CMake 3.25.1
- [ ] arm-none-eabi-gcc 12.2.Rel1
- [ ] pico-sdk v1.5.1 descargado y PICO_SDK_PATH configurado
- [ ] picotool 1.1.0
- [ ] Paquetes Python en venv: pyserial==3.5, rich==13.7.1.
- [ ] Conexiones físicas:
- [ ] 3V3 → VCC TMP102
- [ ] GND → GND TMP102
- [ ] GP4 → SDA TMP102
- [ ] GP5 → SCL TMP102
- [ ] ADD0/ADDR TMP102 → GND (dirección 0x48)
- [ ] Pull-ups en SDA/SCL presentes (breakout o externas).
- [ ] Compilación exitosa (UF2 generado).
- [ ] Flasheo por BOOTSEL correcto (unidad RPI-RP2).
- [ ] /dev/ttyACM0 aparece en el host y pertenece al usuario (grupo dialout).
- [ ] Script host_read_serial.py ejecutándose y mostrando la temperatura.
- [ ] La temperatura sube al tocar el sensor y vuelve a bajar al soltar.
- [ ] Sin errores “i2c_read_failed” persistentes (si aparecen, revisar wiring/pull-ups/frecuencia).
Con este flujo, dispones de una solución reproducible y clara para “i2c-temperature-sensor-readout” usando exactamente la placa Pico-ICE (RP2040 + iCE40UP5K), con una toolchain concreta y versiones verificables, conexiones coherentes con el modelo, código completo y validación guiada paso a paso.
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.



