Logótipo

Servidor Web no Raspberry Pi Pico W

Projecto DIY para alojar um index.html no Pico W, controlar um LED e receber o IP por Telegram.

Pico W MicroPython HTML local LED Telegram Bot DIY
./projecto_pico_w_web.txt

1Ideia do projecto

Este projecto transforma um Raspberry Pi Pico W num pequeno servidor web. O Pico W lê um ficheiro index.html guardado internamente e apresenta uma página simples para ligar e desligar um LED.

A página é local, sem dependência de Bootstrap externo, e funciona através do endereço IP atribuído pela rede Wi-Fi.

2O que o projecto faz

  • Liga o Pico W à rede Wi-Fi.
  • Obtém o endereço IP atribuído pelo router.
  • Envia esse IP para o Telegram através de um bot.
  • Abre um servidor web no Pico W.
  • Lê o ficheiro index.html guardado no Pico.
  • Controla um LED através dos botões /ligar e /desligar.

3Material necessário

  • 1 Raspberry Pi Pico W.
  • 1 LED.
  • 1 resistência de 220 Ω ou 330 Ω.
  • Fios Dupont.
  • Breadboard.
  • Thonny com MicroPython para Pico W.
  • Conta Telegram para receber a mensagem com o IP.

4Ligação do LED

GPIO 15 ---- resistência 220 Ω ---- perna maior do LED
GND ------------------------------- perna menor do LED
./estrutura_no_pico.txt

1Estrutura dos ficheiros

No Pico W devem existir dois ficheiros principais:

/
├── main.py
└── index.html

2Função de cada ficheiro

  • main.py: liga ao Wi-Fi, envia o IP para o Telegram, cria o servidor web e controla o LED.
  • index.html: contém a interface visual com os botões para ligar e desligar o LED.

3Pré-visualização da página local

Pico W

Controlo local de LED

Ligar LED Desligar LED Página alojada no Raspberry Pi Pico W
./configurar_telegram_bot.txt
Atenção: nunca publiques o token real do bot no GitHub, em páginas públicas ou em imagens. Quem tiver o token pode enviar mensagens através do teu bot.

1Criar o bot

No Telegram, pesquisa por @BotFather e envia:

/newbot

Escolhe um nome e depois um username terminado em bot, por exemplo:

pico_w_ip_alvaro_bot

2Guardar o BOT_TOKEN

O BotFather devolve um token. Guarda-o para colocar no main.py.

BOT_TOKEN = "COLOCA_AQUI_O_TOKEN_DO_BOT"

3Obter o CHAT_ID

Abre conversa com o teu bot, carrega em Start e envia uma mensagem, por exemplo olá.

Depois abre no navegador:

https://api.telegram.org/botBOT_TOKEN/getUpdates

Procura o valor:

"chat":{"id":6954376768

Esse número é o CHAT_ID. No código fica assim:

CHAT_ID = "6954376768"

4Testar o envio

https://api.telegram.org/botBOT_TOKEN/sendMessage?chat_id=CHAT_ID&text=Teste%20do%20Pico%20W

Se receberes a mensagem no Telegram, podes passar para o Pico W.

./main.py

Guarda este ficheiro no Pico W com o nome main.py.

import network
import socket
from machine import Pin
import time
import urequests

# -----------------------------
# Configuração Wi-Fi
# -----------------------------
SSID = "NOME_DA_TUA_REDE"
PASSWORD = "PASSWORD_DA_TUA_REDE"

# -----------------------------
# Configuração Telegram
# -----------------------------
BOT_TOKEN = "COLOCA_AQUI_O_TOKEN_DO_BOT"
CHAT_ID = "COLOCA_AQUI_O_CHAT_ID"

# -----------------------------
# LED no GPIO 15
# -----------------------------
led = Pin(15, Pin.OUT)


# -----------------------------
# Enviar IP para o Telegram
# -----------------------------
def enviar_ip_telegram(ip):
    mensagem = "Pico W ligado!\nIP: " + ip + "\nAbrir: http://" + ip

    url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage"

    dados = {
        "chat_id": CHAT_ID,
        "text": mensagem
    }

    try:
        resposta = urequests.post(url, json=dados)
        resposta.close()
        print("IP enviado por Telegram.")
    except Exception as erro:
        print("Erro ao enviar Telegram:", erro)


# -----------------------------
# Ler ficheiro HTML local
# -----------------------------
def ler_ficheiro(nome):
    with open(nome, "r") as ficheiro:
        return ficheiro.read()


# -----------------------------
# Ligar ao Wi-Fi
# -----------------------------
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)

print("A ligar ao Wi-Fi...")

while not wlan.isconnected():
    time.sleep(1)
    print("A tentar ligar...")

ip = wlan.ifconfig()[0]

print("Ligado ao Wi-Fi!")
print("IP do Pico W:", ip)

# Enviar IP para o Telegram
enviar_ip_telegram(ip)


# -----------------------------
# Criar servidor web
# -----------------------------
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]

servidor = socket.socket()
servidor.bind(addr)
servidor.listen(1)

print("Servidor activo em:")
print("http://" + ip)


# -----------------------------
# Ciclo principal do servidor
# -----------------------------
while True:
    cliente, endereco = servidor.accept()
    pedido = cliente.recv(1024)
    pedido = str(pedido)

    print("Pedido recebido:", pedido)

    if "GET /ligar" in pedido:
        led.value(1)
        print("LED ligado")

    elif "GET /desligar" in pedido:
        led.value(0)
        print("LED desligado")

    resposta = ler_ficheiro("index.html")

    cliente.send("HTTP/1.1 200 OK\r\n")
    cliente.send("Content-Type: text/html; charset=utf-8\r\n")
    cliente.send("Connection: close\r\n\r\n")
    cliente.sendall(resposta)
    cliente.close()
./index.html

Guarda este ficheiro no Pico W com o nome index.html.

                <!doctype html>
<html lang="pt">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Pico W - LED</title>

    <!-- Bootstrap 5 via CDN -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body class="bg-light min-vh-100 d-flex align-items-center justify-content-center">

    <main class="container px-3">
        <div class="row justify-content-center">
            <div class="col-12 col-sm-10 col-md-7 col-lg-5 col-xl-4">

                <div class="card border-0 shadow-lg rounded-4">
                    <div class="card-body p-4 p-md-5 text-center">

                        <h1 class="fw-bold mb-3">Pico W</h1>
                        <p class="lead text-secondary mb-4">Controlo local de LED</p>

                        <div class="d-grid gap-3">
                            <a href="/ligar" class="btn btn-success btn-lg rounded-3 fw-bold py-3">
                                Ligar LED
                            </a>

                            <a href="/desligar" class="btn btn-danger btn-lg rounded-3 fw-bold py-3">
                                Desligar LED
                            </a>
                        </div>

                        <p class="small text-muted mt-4 mb-0">
                            Página alojada no Raspberry Pi Pico W
                        </p>

                    </div>
                </div>

            </div>
        </div>
    </main>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

</body>
</html>
              
./testar_projecto.txt

1Instalar MicroPython correcto

No Thonny, escolhe o firmware para Raspberry Pi Pico W. Não uses o firmware do Pico normal, porque esse não tem Wi-Fi.

2Guardar os ficheiros

Envia para o Pico W os ficheiros:

main.py
index.html

3Executar

Ao correr o main.py, o terminal deve mostrar algo semelhante a:

A ligar ao Wi-Fi...
Ligado ao Wi-Fi!
IP do Pico W: 192.168.1.80
IP enviado por Telegram.
Servidor activo em:
http://192.168.1.80

4Abrir a página

Abre o endereço recebido por Telegram no navegador. O telemóvel ou computador deve estar na mesma rede Wi-Fi do Pico W.

http://192.168.1.80
Resultado esperado: ao carregar em Ligar LED, o LED no GPIO 15 acende. Ao carregar em Desligar LED, o LED apaga.
Nota: o IP recebido é normalmente um IP local, como 192.168.1.x. Esse endereço só funciona dentro da mesma rede. Para acesso externo seria necessário usar VPN, túnel seguro ou outra solução de rede.