Materia: Lenguajes de Interfaz
Institución: Instituto Tecnológico de Tijuana
Modalidad: Individual
Lenguaje: MicroPython
Hardware: Raspberry Pi Pico W
La Raspberry Pi Pico W es un microcontrolador con conectividad WiFi, pero con una limitación importante: su stack de red en MicroPython solo soporta HTTP/1.0, no HTTPS. Todas las APIs modernas (OpenAI, Gemini, Hugging Face, etc.) requieren conexiones seguras (HTTPS), por lo que no es posible llamarlas directamente desde la Pico W.
Esta práctica te enseña a resolver ese problema mediante una arquitectura de proxy seguro en tres capas, protegiendo tu API key y permitiendo que la Pico W aproveche la inteligencia artificial en la nube.
Adicionalmente, implementarás un mini-RAG local (Retrieval-Augmented Generation simplificado): un pequeño banco de conocimiento almacenado en la Pico W que enriquece cada consulta antes de enviarla al LLM.
┌─────────────────────────────────────────────────────────────────────┐
│ FLUJO DE DATOS │
│ │
│ Pico W Proxy local Capa segura API externa │
│ (main.py) ──▶ (proxy.py) ──▶ (Code.gs) ──▶ (LLM/API) │
│ HTTP/1.0 FastAPI Apps Script HTTPS │
│ sensor/UI laptop/PC API key aquí │
└─────────────────────────────────────────────────────────────────────┘
| Capa | Tecnología | Responsabilidad |
|---|---|---|
| Pico W | MicroPython | Entrada de datos, mini-RAG, servidor web local |
| Proxy | FastAPI (Python) | Traducir HTTP/1.0 → HTTPS, reenviar a Apps Script |
| Backend seguro | Google Apps Script | Guardar API key, construir prompt, llamar al LLM |
Debe contener:
- Conexión WiFi con credenciales en variables separadas
- Base de conocimiento local (mínimo 5 frases sobre el dominio elegido)
- Función
mini_rag(consulta)que selecciona la frase más relevante por coincidencia de palabras - Servidor web HTTP que sirve al menos dos rutas: entrada y resultado
- Envío POST al proxy con JSON que contiene la consulta y el contexto seleccionado
- Renderizado dinámico de HTML con la respuesta del LLM
# Estructura mínima esperada en main.py
WIFI_SSID = "tu_red"
WIFI_PASS = "tu_contraseña"
PROXY_URL = "http://192.168.x.x:8000/pico"
BASE_CONOCIMIENTO = [
"frase de contexto 1 sobre tu dominio",
"frase de contexto 2 sobre tu dominio",
"frase de contexto 3 sobre tu dominio",
"frase de contexto 4 sobre tu dominio",
"frase de contexto 5 sobre tu dominio",
]
def mini_rag(consulta):
palabras = set(consulta.lower().split())
mejor = max(BASE_CONOCIMIENTO,
key=lambda f: len(palabras & set(f.lower().split())))
return mejor
def enviar_consulta(pregunta):
contexto = mini_rag(pregunta)
payload = {"pregunta": pregunta, "contexto": contexto}
# ... código de envío HTTP POST al proxy
def iniciar_servidor():
# ... servidor web que sirve index.html y procesa formulariosCorre en tu laptop o PC. Recibe peticiones HTTP/1.0 de la Pico W y las reenvía a Google Apps Script vía HTTPS.
from fastapi import FastAPI, Request
import requests, uvicorn, json
APPS_SCRIPT_URL = "https://script.google.com/macros/s/TU_URL/exec"
app = FastAPI()
@app.post("/pico")
async def proxy_pico(request: Request):
raw = await request.body()
data = json.loads(raw.decode())
res = requests.post(APPS_SCRIPT_URL, json=data, timeout=15)
return {"respuesta": res.text}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)La API key nunca sale de este archivo. Construye el prompt enriquecido y llama al LLM.
const OPENAI_API_KEY = "sk-..."; // Solo aquí, nunca en main.py
function doPost(e) {
const data = JSON.parse(e.postData.contents);
const pregunta = data.pregunta || "";
const contexto = data.contexto || "";
const prompt = `Contexto: ${contexto}\n\nPregunta: ${pregunta}\nResponde de forma breve y clara.`;
const payload = {
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "Eres un experto en [TU DOMINIO]. Responde de forma concisa." },
{ role: "user", content: prompt }
]
};
const response = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", {
method: "post",
contentType: "application/json",
headers: { Authorization: `Bearer ${OPENAI_API_KEY}` },
payload: JSON.stringify(payload)
});
const result = JSON.parse(response.getContentText());
return ContentService.createTextOutput(result.choices[0].message.content);
}El usuario accede desde su navegador a la IP local de la Pico W. Debe mostrar:
- Formulario de entrada (texto, selección, o botón según el proyecto)
- Respuesta del LLM formateada
- Indicación del contexto mini-RAG utilizado
El mini-RAG es el elemento académico clave. Demuestra que la Pico W no es solo un relay — procesa localmente antes de consultar la nube.
| Componente | Descripción |
|---|---|
BASE_CONOCIMIENTO |
Lista de 5–10 frases sobre el dominio elegido |
mini_rag(consulta) |
Función que selecciona la frase más relevante |
| Criterio de selección | Coincidencia de palabras (bag-of-words simple) |
| Uso | El contexto seleccionado viaja junto con la pregunta al LLM |
¿Por qué esto es RAG? Porque en lugar de enviar solo la pregunta cruda al LLM, primero recuperas información relevante de tu base local y luego augmentas (enriqueces) el prompt antes de generar la respuesta.
| # | Regla | Penalización |
|---|---|---|
| 1 | La API key no debe aparecer en main.py ni en la Pico W |
-40 puntos |
| 2 | No llamar HTTPS directamente desde la Pico W | -30 puntos |
| 3 | No usar el mismo dominio del ejemplo (ajedrez) | -20 puntos |
| 4 | El mini-RAG debe ser funcional (no decorativo) | -20 puntos |
| 5 | Todos los archivos deben estar en un Gist público | Entrega inválida |
| Criterio | Puntaje |
|---|---|
| Proxy funcional: Pico W → FastAPI → Apps Script | 20 pts |
API key protegida exclusivamente en Code.gs |
20 pts |
| mini-RAG implementado y funcionando | 20 pts |
| Interfaz HTML servida desde la Pico W | 20 pts |
| Dominio propio, coherente y base de conocimiento relevante | 20 pts |
| Total | 100 pts |
- Gist público en GitHub con todos los archivos:
main.py,proxy.py,Code.gs,index.html - El README del gist debe incluir: nombre, matrícula, dominio elegido, número de proyecto de la lista
- Video demostrativo de 2–3 minutos mostrando el flujo completo
Elige uno de los siguientes proyectos. El dominio define tu BASE_CONOCIMIENTO, el system prompt en Apps Script, y la temática de tu interfaz.
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 1 | Asistente de riego inteligente | Humedad del suelo (simulada) | ¿Necesita riego esta planta? |
| 2 | Identificador de plagas | Nombre de síntoma ingresado | ¿Qué plaga causa estas manchas amarillas? |
| 3 | Guía de cultivo de hortalizas | Tipo de vegetal seleccionado | ¿Cómo cultivo jitomates en clima seco? |
| 4 | Monitor de calidad del aire para invernadero | Valor de CO₂ (simulado) | ¿Es seguro este nivel de CO₂ para lechugas? |
| 5 | Calendario de siembra | Mes y región ingresados | ¿Qué puedo sembrar en mayo en Baja California? |
| 6 | Asistente de compostaje | Material a compostar | ¿Cuánto tiempo tarda en compostar cáscara de naranja? |
| 7 | Detector de déficit hídrico | Temperatura + humedad | ¿Sufre estrés hídrico mi cultivo con estos datos? |
| 8 | Consultor de fertilización | Tipo de planta + síntoma | ¿Qué fertilizante necesita una planta con hojas amarillas? |
| 9 | Guía de plantas medicinales | Planta ingresada | ¿Para qué sirve la manzanilla y cómo se prepara? |
| 10 | Detector de condiciones de helada | Temperatura nocturna | ¿Debo proteger mis plantas con esta temperatura? |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 11 | Asistente de hidratación | Temperatura ambiente + actividad | ¿Cuánta agua debo tomar hoy? |
| 12 | Guía de primeros auxilios | Síntoma o lesión ingresada | ¿Qué hago ante una quemadura leve? |
| 13 | Contador de calorías básico | Alimento ingresado | ¿Cuántas calorías tiene un plátano mediano? |
| 14 | Asistente de sueño | Horas dormidas + hora de levantada | ¿Dormí suficiente? ¿Qué hábito mejorar? |
| 15 | Monitor de postura (simulado) | Tiempo sentado ingresado | ¿Cuándo debo levantarme y estirarme? |
| 16 | Guía de ejercicio en casa | Grupo muscular seleccionado | Dame una rutina de 10 minutos para abdomen |
| 17 | Asistente de meditación | Estado de ánimo seleccionado | Guíame en una respiración para reducir estrés |
| 18 | Control de presión arterial (valores simulados) | Sistólica/diastólica | ¿Es normal esta presión arterial? |
| 19 | Detector de síntomas comunes | Síntoma ingresado | ¿Qué puede causar dolor de cabeza frecuente? |
| 20 | Asistente nutricional | Ingredientes disponibles | Dame una comida saludable con pollo y espinacas |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 21 | Estación meteorológica con IA | Temperatura + humedad (DHT22) | ¿Qué tiempo hará mañana según estos datos? |
| 22 | Índice de calidad del aire | Valor de sensor MQ135 | ¿Es seguro el nivel de contaminación registrado? |
| 23 | Asistente de reciclaje | Material a desechar | ¿En qué contenedor va la botella de plástico PET? |
| 24 | Monitor de consumo eléctrico | Watts estimados ingresados | ¿Cuánto pagaré si uso este aparato 4 horas diarias? |
| 25 | Guía de ahorro de agua | Actividad seleccionada | ¿Cuánta agua consume un baño de 10 minutos? |
| 26 | Detector de lluvia ácida (simulado) | Valor de pH | ¿Es ácida esta lectura de pH en el agua de lluvia? |
| 27 | Calculadora de huella de carbono | Medio de transporte + km | ¿Cuánto CO₂ emití en mi trayecto de 20 km en auto? |
| 28 | Asistente de energía solar | Hora del día + nubosidad | ¿Es buen momento para cargar con panel solar? |
| 29 | Monitor de ruido ambiental | Nivel de dB (simulado) | ¿Es peligroso este nivel de ruido para la audición? |
| 30 | Guía de ecoturismo local | Ciudad o región ingresada | ¿Qué actividades ecoturísticas hay en Ensenada? |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 31 | Tutor de matemáticas básicas | Problema ingresado | Explícame cómo resolver esta ecuación cuadrática |
| 32 | Quiz de historia de México | Botón aleatorio | Genera una pregunta de historia de México con 4 opciones |
| 33 | Asistente de idioma inglés | Frase en español | Traduce y corrige el uso de los tiempos verbales |
| 34 | Trivia de ciencias | Categoría seleccionada | Pregunta de física nivel preparatoria con explicación |
| 35 | Generador de ejemplos de programación | Lenguaje + concepto | Dame un ejemplo de ciclo for en Python con comentarios |
| 36 | Asistente de geografía | País o ciudad ingresada | Dime 3 datos curiosos de Japón |
| 37 | Tutor de lectura de comprensión | Párrafo ingresado | Resume este texto en una oración y haz una pregunta |
| 38 | Quiz de cultura general | Botón de inicio | Genera una pregunta de trivia con 4 opciones y explica la respuesta |
| 39 | Asistente de ortografía | Oración con posibles errores | Corrige esta oración y explica el error |
| 40 | Explorador de ciencias naturales | Fenómeno ingresado | Explica la fotosíntesis de forma sencilla para secundaria |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 41 | Generador de recetas con lo que tienes | Ingredientes disponibles | Dame una receta con pollo, arroz y chile |
| 42 | Asistente de maridaje | Platillo seleccionado | ¿Qué vino marida mejor con el mole negro? |
| 43 | Calculadora de tiempos de cocción | Tipo de carne + peso | ¿Cuánto tiempo debo hornear un pollo de 1.5 kg? |
| 44 | Guía de cocina regional mexicana | Estado seleccionado | ¿Cuál es el platillo típico de Oaxaca y cómo se prepara? |
| 45 | Asistente de repostería | Postre seleccionado | Dame la receta básica de tres leches para 10 personas |
| 46 | Detector de alergenos | Ingrediente ingresado | ¿El gluten está presente en la salsa soja? |
| 47 | Guía de conservación de alimentos | Alimento + temperatura | ¿Cuántos días dura el aguacate en refrigeración? |
| 48 | Asistente de dieta vegetariana | Nutriente a cubrir | ¿Cómo obtengo proteína sin comer carne? |
| 49 | Conversor de medidas culinarias | Cantidad + unidad | ¿Cuántas tazas son 250 gramos de harina? |
| 50 | Menú semanal personalizado | Preferencias seleccionadas | Dame un menú saludable para 5 días sin gluten |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 51 | Explicador de errores de código | Mensaje de error ingresado | ¿Qué significa "TypeError: 'NoneType' object is not iterable"? |
| 52 | Generador de pseudocódigo | Descripción del algoritmo | Escribe el pseudocódigo para ordenar una lista burbuja |
| 53 | Asistente de comandos Linux | Tarea a realizar | ¿Cómo listo los procesos que más CPU usan en Linux? |
| 54 | Guía de protocolos IoT | Protocolo seleccionado | Explica MQTT vs HTTP para IoT con ejemplos |
| 55 | Asistente de diseño de circuitos | Componente seleccionado | ¿Cómo conecto un DHT22 a una Raspberry Pi Pico W? |
| 56 | Generador de expresiones regulares | Patrón a detectar | Dame una regex para validar correos electrónicos |
| 57 | Tutor de SQL básico | Consulta a construir | ¿Cómo selecciono los 5 clientes con más compras? |
| 58 | Asistente de Git | Acción a realizar | ¿Cómo deshago el último commit sin perder los cambios? |
| 59 | Explicador de conceptos de redes | Concepto ingresado | Explica la diferencia entre TCP y UDP con analogía |
| 60 | Generador de casos de prueba | Función descrita | Dame 3 casos de prueba para una función que valida contraseñas |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 61 | Generador de ideas de historias | Género + elemento | Dame una idea de cuento de terror con un espejo |
| 62 | Asistente de guión de cortometraje | Tema ingresado | Dame la estructura de 3 actos para un cortometraje de amistad |
| 63 | Trivia de cine | Género seleccionado | Pregunta de trivia sobre películas de ciencia ficción |
| 64 | Generador de letras de canción | Emoción + género musical | Dame el estribillo de una canción de amor al estilo ranchero |
| 65 | Asistente de dibujo para principiantes | Objeto a dibujar | Dame 5 pasos para dibujar un gato de forma simple |
| 66 | Trivia de música mexicana | Época seleccionada | Pregunta sobre la época dorada del cine y música mexicana |
| 67 | Generador de chistes | Tema seleccionado | Dame un chiste de tecnología para nivel universitario |
| 68 | Asistente de fotografía | Escena a fotografiar | ¿Qué configuración de cámara uso para fotografiar un atardecer? |
| 69 | Guía de literatura mexicana | Autor o época | Describe la obra de Juan Rulfo y su importancia |
| 70 | Recomendador de películas | Estado de ánimo + género | Recomiéndame una película de comedia para ver en familia |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 71 | Asistente de rutas de transporte | Origen + destino | ¿Cómo llego del Tec de Tijuana a la Zona Río en transporte público? |
| 72 | Guía de trámites ciudadanos | Trámite seleccionado | ¿Qué documentos necesito para renovar mi INE? |
| 73 | Asistente de seguridad vial | Situación ingresada | ¿Qué hago si presencio un accidente de tráfico? |
| 74 | Calculadora de presupuesto personal | Ingreso + gastos | ¿Cómo distribuyo $8,000 pesos de quincena? |
| 75 | Guía de primeros pasos en Tijuana | Necesidad del visitante | ¿Dónde cambio dólares a pesos con mejor tipo de cambio? |
| 76 | Asistente de reglamento de tránsito | Infracción descrita | ¿Cuál es la multa por no usar cinturón de seguridad en BC? |
| 77 | Guía de emprendimiento básico | Tipo de negocio | ¿Qué trámites necesito para abrir una taquería en Tijuana? |
| 78 | Asistente de finanzas personales | Meta financiera | ¿Cómo ahorro $50,000 en un año con sueldo de $12,000 mensuales? |
| 79 | Guía de reparaciones del hogar | Problema doméstico | ¿Cómo cambio un enchufe sin llamar a un electricista? |
| 80 | Asistente de compras inteligentes | Producto a comprar | ¿Qué revisar antes de comprar un celular usado? |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 81 | Calculadora de materiales de construcción | Área + tipo de obra | ¿Cuántos blocks necesito para una barda de 10×2 metros? |
| 82 | Asistente de soldadura | Tipo de unión | ¿Qué electrodo uso para soldar acero inoxidable? |
| 83 | Guía de mantenimiento de equipos | Equipo seleccionado | ¿Cada cuánto se debe hacer mantenimiento a un compresor? |
| 84 | Asistente de metrología | Medición + tolerancia | ¿Qué instrumento uso para medir 0.01 mm de precisión? |
| 85 | Calculadora de resistencia de materiales | Material + carga | ¿Soporta una viga de madera de pino 200 kg en 2 metros? |
| 86 | Guía de impresión 3D | Problema de impresión | ¿Por qué se despega mi impresión de la cama caliente? |
| 87 | Asistente de diagramas eléctricos | Circuito a analizar | ¿Cómo leo un diagrama de escalera (ladder) en PLC? |
| 88 | Calculadora de consumo de motores | Potencia + tiempo | ¿Cuánto consume un motor de 1 HP en 8 horas diarias? |
| 89 | Guía de control de calidad | Defecto detectado | ¿Qué es una carta de control X-R y cuándo usarla? |
| 90 | Asistente de CNC básico | Operación de maquinado | ¿Qué velocidad de corte uso para fresar aluminio con fresa de 10mm? |
| # | Proyecto | Entrada en Pico W | Consulta al LLM |
|---|---|---|---|
| 91 | Generador de slogans | Producto + público | Dame 3 slogans para una app de delivery para universitarios |
| 92 | Asistente de atención a clientes | Queja del cliente | ¿Cómo respondo a un cliente que recibió un pedido incompleto? |
| 93 | Generador de descripciones de productos | Producto + características | Escribe una descripción para vender tenis deportivos en Instagram |
| 94 | Asistente de análisis FODA | Tipo de negocio | Dame un FODA básico para una cafetería universitaria |
| 95 | Guía de redes sociales para negocios | Red social + objetivo | ¿Cómo consigo mis primeros 1,000 seguidores en TikTok para mi negocio? |
| 96 | Generador de correos profesionales | Situación de negocio | Redacta un correo para pedir una reunión con un cliente potencial |
| 97 | Asistente de precios | Costo + margen deseado | ¿A qué precio vendo si mi costo es $80 y quiero 30% de ganancia? |
| 98 | Guía de negociación | Situación de negociación | ¿Cómo negocio un mejor precio con un proveedor? |
| 99 | Asistente de plan de negocios | Idea de negocio | Dame los 5 elementos clave para el plan de un negocio de hamburguesas |
| 100 | Detector de tendencias de mercado | Producto o industria | ¿Cuáles son las tendencias actuales en el mercado de comida saludable? |
[USUARIO]
│
▼
Navega a IP de Pico W (ej. 192.168.1.50)
│
▼
[PICO W - main.py]
┌─────────────────────────────┐
│ 1. Muestra formulario HTML │
│ 2. Recibe entrada usuario │
│ 3. Ejecuta mini_rag() │
│ → selecciona contexto │
│ 4. Construye JSON payload: │
│ {"pregunta": "...", │
│ "contexto": "..."} │
│ 5. POST → proxy:8000/pico │
└─────────────────────────────┘
│ HTTP/1.0
▼
[PROXY - proxy.py en laptop]
┌─────────────────────────────┐
│ 1. Recibe JSON de Pico W │
│ 2. Reenvía → Apps Script │
│ (HTTPS) │
│ 3. Devuelve respuesta │
└─────────────────────────────┘
│ HTTPS
▼
[GOOGLE APPS SCRIPT - Code.gs]
┌─────────────────────────────┐
│ 1. Extrae pregunta+contexto │
│ 2. Construye prompt │
│ 3. Llama OpenAI con API key │
│ 4. Devuelve solo el texto │
└─────────────────────────────┘
│ HTTPS
▼
[OPENAI / LLM]
│
▼ (respuesta viaja de regreso)
[PICO W]
┌─────────────────────────────┐
│ Renderiza respuesta en HTML │
│ Muestra al usuario │
└─────────────────────────────┘
El proxy es el componente que corre en tu laptop o PC durante la demostración. Sigue estos pasos antes de encender la Pico W.
- Python 3.10 o superior instalado
- Conexión a la misma red WiFi que la Pico W
- Puerto 8000 disponible (no bloqueado por firewall)
# Crear carpeta del proyecto
mkdir proxy-picow && cd proxy-picow
# Crear entorno virtual
python -m venv venv
# Activar entorno virtual
# En Windows:
venv\Scripts\activate
# En macOS / Linux:
source venv/bin/activatepip install fastapi uvicorn requestsO con un archivo requirements.txt:
fastapi==0.115.0
uvicorn==0.30.6
requests==2.32.3
pip install -r requirements.txtEdita estas dos líneas antes de correr:
# URL de tu Google Apps Script (cópiala al publicar el script como Web App)
APPS_SCRIPT_URL = "https://script.google.com/macros/s/TU_URL_AQUI/exec"
# En la última línea, pon la IP de tu laptop en la red local
uvicorn.run(app, host="0.0.0.0", port=8000)¿Cómo conozco la IP de mi laptop?
# Windows ipconfig # macOS / Linux ip addr show # o: ifconfigBusca la IP que empiece con
192.168.x.xo10.x.x.x.
python proxy.pyDeberías ver:
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Desde otra terminal (o navegador), prueba que el proxy está activo:
curl -X POST http://localhost:8000/pico \
-H "Content-Type: application/json" \
-d '{"pregunta": "hola", "contexto": "prueba de conexión"}'Respuesta esperada:
{"respuesta": "¡Hola! ¿En qué puedo ayudarte?"}Actualiza estas variables con los datos de tu entorno:
WIFI_SSID = "NombreDeTuRed"
WIFI_PASS = "ContraseñaDeRed"
PROXY_URL = "http://192.168.1.50:8000/pico" # IP de tu laptop, puerto 8000Importante: La Pico W y la laptop deben estar conectadas a la misma red WiFi.
- Ve a script.google.com e inicia sesión con tu cuenta de Google
- Crea un nuevo proyecto y pega el contenido de
Code.gs - Agrega tu API key de OpenAI en la variable
OPENAI_API_KEY - Haz clic en Implementar → Nueva implementación
- Tipo: Aplicación web
- Ejecutar como: Yo
- Quién tiene acceso: Cualquier persona
- Copia la URL generada y pégala en
APPS_SCRIPT_URLdeproxy.py
Red WiFi local (192.168.1.x)
│
├── Pico W → IP asignada por DHCP (ej. 192.168.1.50)
│ Puerto servidor → :80 (HTTP, acceso desde navegador)
│
└── Laptop → IP fija o DHCP (ej. 192.168.1.100)
Puerto proxy → :8000 (FastAPI, recibe peticiones de la Pico)
Laptop → Internet → Google Apps Script → OpenAI API
| Problema | Causa probable | Solución |
|---|---|---|
ConnectionError en la Pico W |
IP del proxy incorrecta | Verifica con ipconfig / ip addr |
OSError: -202 en la Pico W |
WiFi no conectado | Revisa SSID y contraseña en main.py |
| Proxy no inicia | Puerto 8000 ocupado | Cambia a port=8001 en proxy.py y en PROXY_URL |
| Apps Script devuelve error 401 | API key inválida | Revisa la key en Code.gs |
| Apps Script devuelve error 403 | Implementación no pública | Re-implementa con acceso "Cualquier persona" |
| Proxy corre pero Pico no llega | Firewall del sistema | Permite Python en el firewall de Windows/macOS |
Thonny es el IDE recomendado para trabajar con MicroPython en la Raspberry Pi Pico W. Sigue estos pasos para instalar el firmware y cargar tu código.
Descarga e instala Thonny desde thonny.org (disponible para Windows, macOS y Linux).
Si ya lo tienes instalado, verifica que sea la versión 4.0 o superior en Ayuda → Acerca de Thonny.
Solo necesitas hacerlo una vez por dispositivo.
-
Descarga el firmware MicroPython para Pico W desde:
micropython.org/download/RPI_PICO_W
Descarga el archivo.uf2más reciente. -
Mantén presionado el botón BOOTSEL de la Pico W mientras la conectas al USB.
-
La Pico aparecerá como una unidad de almacenamiento llamada RPI-RP2 en tu explorador de archivos.
-
Arrastra y suelta el archivo
.uf2dentro de esa unidad.
La Pico se reiniciará automáticamente y el firmware quedará instalado.
- Abre Thonny.
- Ve al menú Herramientas → Opciones → Intérprete.
- Selecciona: MicroPython (Raspberry Pi Pico).
- En el campo Puerto, elige el puerto COM correspondiente:
- Windows:
COM3,COM4, etc. (verifica en el Administrador de dispositivos) - macOS:
/dev/cu.usbmodem... - Linux:
/dev/ttyACM0o/dev/ttyUSB0
- Windows:
- Haz clic en Aceptar.
En la parte inferior de Thonny aparecerá el Shell de MicroPython:
MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>>
Antes de subir, organiza tus archivos en la misma carpeta en tu PC:
mi-proyecto/
├── main.py ← código principal
├── index.html ← interfaz servida por la Pico
└── (otros .py si los necesitas)
La Pico W ejecuta automáticamente
main.pyal encenderse, por eso ese nombre es obligatorio.
- Abre
main.pyen Thonny (File → Open → selecciona el archivo de tu PC). - Ve a Archivo → Guardar como...
- Aparecerá un diálogo preguntando dónde guardar:
- Selecciona Raspberry Pi Pico
- Escribe el nombre
main.pyy haz clic en Aceptar.
- Activa el panel de archivos: Ver → Archivos.
- En el panel izquierdo verás los archivos de tu PC; en el derecho, los de la Pico.
- Navega hasta tu carpeta del proyecto en el panel izquierdo.
- Haz clic derecho sobre
main.py→ Subir a / - Repite para
index.htmly cualquier otro archivo necesario.
Panel izquierdo (PC) Panel derecho (Pico W)
───────────────────── ──────────────────────
📁 mi-proyecto/ 📁 /
📄 main.py ──▶ 📄 main.py
📄 index.html ──▶ 📄 index.html
En el Shell de Thonny escribe:
import os
os.listdir()Deberías ver:
['main.py', 'index.html']Presiona el botón ▶ Ejecutar (F5) o ve a Ejecutar → Ejecutar script actual.
La salida aparecerá en el Shell de Thonny:
Conectando a WiFi...
IP asignada: 192.168.1.50
Servidor HTTP iniciado en el puerto 80
Una vez que main.py está en la Pico, simplemente desconecta y reconecta el USB (o usa una fuente de alimentación). La Pico ejecutará main.py automáticamente al arrancar.
Con la Pico W conectada y el proxy corriendo en tu laptop:
- Anota la IP que aparece en el Shell (ej.
192.168.1.50) - Abre un navegador en cualquier dispositivo de la misma red
- Escribe:
http://192.168.1.50(sin HTTPS)
| Situación | Qué hacer en Thonny |
|---|---|
| El código se cuelga | Presiona Ctrl+C en el Shell para interrumpir |
Quieres ver print() en tiempo real |
Deja el Shell abierto mientras corre el servidor |
| Necesitas borrar un archivo de la Pico | Panel derecho → clic derecho → Eliminar |
| La Pico no aparece en los puertos | Desconecta, espera 3 segundos, reconecta |
| Thonny muestra "puerto ocupado" | Cierra cualquier otra terminal que use ese puerto |
1. Edita main.py en tu PC → 2. Sube a la Pico con Thonny
↑ ↓
6. Ajusta el código 3. Corre el proxy en otra terminal
↑ ↓
5. Observa el Shell 4. Abre el navegador → IP de la Pico
- Puedes usar Gemini API (Google AI Studio) en lugar de OpenAI — también es gratuito con clave
- El proxy puede correr en Render.com o Railway (gratis) si no quieres usar tu laptop
- La base de conocimiento puede crecer: mientras más frases, mejor el mini-RAG
- El proyecto puede extenderse agregando persistencia (guardar respuestas en un archivo en la Pico)
Instituto Tecnológico de Tijuana — Departamento de Sistemas y Computación
Lenguajes de Interfaz — Práctica integradora IoT + IA