Controlar una salida de tu Raspberry Pi Pico desde el navegador del celular, sin apps ni servicios en la nube, es más fácil de lo que parece: basta con levantar un pequeño servidor web dentro de la propia Pico. En este tutorial vas a programar una Raspberry Pi Pico W (o Pico 2W) con el IDE de Arduino para servir una página con dos botones que encienden y apagan una salida, y. dándole una vuelta al proyecto original. vamos a controlar un relé en lugar de un simple LED, para que puedas manejar algo real: una ampolleta, un ventilador o una bomba. Al final vas a saber cómo funciona un servidor web asíncrono en la Pico y cómo reflejar el estado del GPIO en la página.
Importante: este proyecto solo sirve con Raspberry Pi Pico W y Raspberry Pi Pico 2W, que son las que tienen WiFi. Una Pico común (sin W) no puede levantar el servidor.
Qué vamos a construir
Cuando escribes la dirección IP de la Pico en el navegador, haces una petición al servidor (la Pico) en la ruta raíz /. La Pico responde con el HTML de una página simple con dos botones. Al tocar cada botón se dispara una nueva petición:
- Botón encender: petición a
/lighton? - Botón apagar: petición a
/lightoff?
La página usa una plantilla HTML que inserta el estado actual de la salida justo después de cada petición. Ojo con un detalle: no confirma el estado real del pin, solo lo actualiza según la petición que se hizo.

Instalar las librerías
Para crear el servidor web asíncrono usamos la librería ESPAsyncWebServer, la misma que se ocupa en ESP32 y ESP8266; también es compatible con la RP2040/RP2350 de la Pico. Para la Pico necesitas además la librería RPAsyncTCP.
En el IDE de Arduino ve a Sketch > Include Library > Manage Libraries (o el ícono del Library Manager en la barra lateral) e instala:
- ESPAsyncWebServer por ESP32Async
- RPAsyncTCP por Ayush Sharma

Hardware y conexiones
El código controla la salida en GPIO 2. Puedes usar cualquier otro GPIO si ajustas la línea correspondiente del código. El tutorial original enciende un LED con su resistencia de 220Ω; nosotros vamos a conectar en ese mismo pin un módulo relé de 1 canal, que trae optoacoplador y se comanda igual con un nivel alto/bajo. Así el mismo sketch pasa de prender un LED de prueba a conmutar una carga de verdad.

Si quieres empezar con el LED simple para probar (recomendado antes de meter voltaje de red), lo conectas al GPIO 2 con una resistencia de 220Ω a GND, sobre una protoboard y con cables dupont. Cuando ya funcione, reemplazas el LED por la entrada de señal del relé.
El código completo
Este es el sketch que levanta el servidor y sirve la página. Pega tu SSID y contraseña en las líneas correspondientes antes de subirlo:
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-web-server-outputs-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
// Import required libraries
#include <WiFi.h>
#include <RPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// LED to control
#define LED_PIN 2
// Current LED state (to display on the web page)
String ledState = "OFF";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Pico Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {
font-family: Arial;
display: inline-block;
margin: 0px auto;
text-align: center;
}
body {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: #333;
}
h2 {
color: #666;
}
form {
margin: 10px 0;
}
.button {
background-color: #4CAF50;
border: none;
color: white;
padding: 10px 20px;
text-decoration: none;
font-size: 20px;
margin: 2px;
cursor: pointer;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
transition: background-color 0.3s, box-shadow 0.3s;
}
.button:hover {
background-color: #45a049;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.button2 {
background-color: #f44336;
}
.button2:hover {
background-color: #da190b;
}
.state {
font-size: 1.4em;
margin: 20px 0;
color: #444;
}
</style>
</head>
<body>
<h1>Raspberry Pi Pico Web Server</h1>
<h2>Led Control</h2>
<p class="state">LED State: %STATE%</p>
<form action="./lighton">
<input type="submit" value="LED on" class="button" />
</form>
<form action="./lightoff">
<input type="submit" value="LED off" class="button button2" />
</form>
</body>
</html>
)rawliteral";
// Processor function
String processor(const String& var){
if(var == "STATE"){
return ledState;
}
return String();
}
void setup(){
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print Pico Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Route to turn LED ON
server.on("/lighton", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(LED_PIN, HIGH);
ledState = "ON";
request->send(200, "text/html", index_html, processor);
});
// Route to turn LED OFF
server.on("/lightoff", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(LED_PIN, LOW);
ledState = "OFF";
request->send(200, "text/html", index_html, processor);
});
// Start server
server.begin();
}
void loop() {
}
Cómo funciona, en breve
- Librerías:
WiFipara conectar a la red, másRPAsyncTCPyESPAsyncWebServerpara el servidor. index_html: guarda todo el HTML como raw string literal (entreR"rawliteral(y)rawliteral"), lo que permite escribir el HTML tal cual sin escapar comillas ni saltos de línea. Se almacena en flash conPROGMEM.%STATE%: es un marcador de posición. Antes de enviar la página, la funciónprocessor()lo reemplaza por el valor real deledState.- Rutas:
server.on("/", ...)sirve la página;/lightony/lightoffcambian el pin condigitalWrite()y actualizan el estado. loop()vacío: como el servidor es asíncrono, no hace falta poner nada en el loop; las rutas se ejecutan solas cuando llega una petición.
Subir el código y probar
Para subir código a la Pico W tiene que estar en modo bootloader. Si viene con MicroPython, conéctala al computador manteniendo apretado el botón BOOTSEL. Se abrirá una unidad de almacenamiento; ciérrala. En próximas subidas desde el IDE de Arduino, la placa entra sola en bootloader.

En el menú desplegable superior elige Select other board and port…, selecciona Raspberry Pi Pico W o Raspberry Pi Pico 2W según tu placa, marca Show all ports si no aparece el COM, y sube el código. Luego abre el Monitor Serial a 115200 baudios: al reconectar la Pico, imprimirá su dirección IP. Escribe esa IP en el navegador y ya puedes controlar la salida.

Variantes y mejoras
- Leer el estado real del pin: como notamos arriba, la página muestra el estado "supuesto". Puedes cambiar
processor()para que leadigitalRead(LED_PIN)y devuelva el estado real del GPIO, más fiable si algo externo cambia la salida. - Varias salidas: duplica las rutas y los botones para controlar 2 o 4 relés desde la misma página (riego por zonas, luces por ambiente).
- Protección de la carga: si vas a conmutar 220V con el relé, aísla bien la etapa de potencia y nunca manipules la protoboard con la carga energizada.
Personalización para Chile
En Chile consigues todo en MechatronicStore:
- Raspberry Pi Pico 2 W (SKU GS3-4). $16.990 CLP
- Módulo relé 1 canal 5V (SKU D-205). $1.690 CLP
- LED 5mm rojo (SKU GA1-5). $100 CLP
- Resistencia 220Ω 1/4W (SKU GK1-18). $100 CLP
- Protoboard 400 puntos (SKU C-301). $2.690 CLP
- Cables macho macho 30 cm (SKU C-417). $2.990 CLP
Si en algún tutorial ves una "Pico W" a secas, la Pico 2 W (RP2350) del catálogo cumple la misma función con más rendimiento y también trae WiFi.
Recursos
- Tutorial original (inglés): Raspberry Pi Pico: Web Server to Control Outputs (Arduino IDE)
- Librerías: ESPAsyncWebServer (por ESP32Async) y RPAsyncTCP (por Ayush Sharma), ambas desde el Library Manager del IDE de Arduino.
Versión chilena con componentes en stock local en MechatronicStore, inspirada en el tutorial de Random Nerd Tutorials y re enfocada para controlar una carga real con relé.










