Raspberry Pi Pico W WiFi: creare un web server con MicroPython
Raspberry Pi Pico W e WiFi: il file UF2 giusto, network.WLAN e codici di stato, web server per un LED, sensori in tempo reale, API con urequests e ora via NTP.
Usare il WiFi del Raspberry Pi Pico W è uno dei modi più economici e semplici per costruire un piccolo dispositivo da controllare con lo smartphone. Il Pico W è la versione del noto Raspberry Pi Pico che aggiunge WiFi a 2,4 GHz e Bluetooth: con poche righe di MicroPython si collega alla rete di casa, pubblica una propria pagina web e scarica meteo e ora da internet. In questa guida collegherai un Pico W al WiFi partendo da zero, creerai un web server che accende un LED dallo smartphone e poi una pagina che mostra i dati di un sensore in tempo reale.
Alla fine saprai scegliere il file UF2 giusto, collegarti con network.WLAN e leggere i codici di stato, ottenere dati da un'API con urequests, impostare l'ora con NTP e fare la stessa cosa con l'Arduino IDE. Se il Pico è una novità per te, ti aiuterà leggere prima Cos'è il Raspberry Pi Pico?; i comandi di base sono spiegati nella guida Cos'è MicroPython?.

Cos'è il Raspberry Pi Pico W e in cosa differisce dal Pico?
Il Pico W usa lo stesso processore RP2040, le stesse dimensioni e la stessa piedinatura a 40 pin del Pico. La differenza è il chip wireless Infineon CYW43439 aggiunto alla scheda: offre WiFi 802.11n a 2,4 GHz e Bluetooth 5.2. Il processore comunica con questo chip tramite un collegamento SPI interno; tu usi soltanto il modulo network di MicroPython. In seguito Raspberry Pi ha lanciato il Pico 2 W con processore RP2350; dato che il chip wireless è lo stesso, tutto il codice di questo articolo funziona anche lì.
| Caratteristica | Pico W | Pico 2 W | ESP32 (WROOM-32) |
|---|---|---|---|
| Processore | RP2040, dual core Cortex-M0+, 133 MHz | RP2350, dual core Cortex-M33 (o RISC-V), 150 MHz | Xtensa LX6, dual core, 240 MHz |
| RAM | 264 KB | 520 KB | 520 KB |
| Memoria flash | 2 MB | 4 MB | Di solito 4 MB |
| WiFi | 2,4 GHz, 802.11n (CYW43439) | 2,4 GHz, 802.11n (CYW43439) | 2,4 GHz, 802.11 b/g/n (integrato nel chip) |
| Bluetooth | 5.2 (Classic e BLE) | 5.2 (Classic e BLE) | 4.2 (Classic e BLE) |
| Ingressi analogici | 3 canali, 12 bit | 3 canali, 12 bit | 18 canali, 12 bit |
| File MicroPython | RPI_PICO_W (.uf2) | RPI_PICO2_W (.uf2) | ESP32_GENERIC (.bin) |
Sulla carta l'ESP32 è più veloce e ha più esempi nel mondo Arduino. I punti di forza del Pico W sono il supporto MicroPython ufficiale e maturo, una documentazione ordinata e pin senza trappole del tipo "deve essere a questo livello all'avvio". Se ti piace imparare con Python, il Pico W è un'ottima scelta; se per te contano di più il codice Arduino e le librerie pronte, l'ESP32 potrebbe risultarti più comodo. Se sei indeciso tra i due, ti aiuterà il confronto Arduino o ESP32?.
Il chip wireless del Pico W e le differenze nei pin
I pin accessibili del Pico W sono esattamente gli stessi del Pico: GP0–GP22 e GP26–GP28 sono liberi e gli ingressi analogici restano su GP26, GP27 e GP28. Cambiano invece i quattro pin che restano all'interno della scheda. Sul Pico gestiscono il LED integrato, la modalità dell'alimentatore e il rilevamento USB; sul Pico W sono riservati alla comunicazione con il chip wireless, e il LED è collegato direttamente a quel chip. Puoi vedere la piedinatura completa della scheda nello strumento Pinout.
| Pin interno | Funzione sul Pico | Funzione sul Pico W |
|---|---|---|
| GP23 | Modalità dell'alimentatore (SMPS) | Accensione del chip wireless (WL_ON) |
| GP24 | Rilevamento tensione USB (VBUS) | Linea dati e interrupt wireless (WL_D) |
| GP25 | LED integrato | Selezione del chip wireless (WL_CS) |
| GP29 | Misura della tensione VSYS (ADC3) | Clock wireless (WL_CLK) e misura di VSYS |
| LED integrato | GP25: Pin(25) | WL_GPIO0 del chip wireless: Pin("LED") |
Passo 1: caricare il file UF2 giusto per il Pico W
L'errore più comune è caricare sul Pico W il file MicroPython del Pico normale. La scheda funziona e nella Shell di Thonny vedi il prompt, ma appena scrivi import network compare "ImportError: no module named 'network'", perché la versione per il Pico normale non contiene il driver wireless. Ogni scheda ha il suo file UF2:
| Scheda | File UF2 di MicroPython | Unità visibile in modalità BOOTSEL |
|---|---|---|
| Raspberry Pi Pico | RPI_PICO-….uf2 | RPI-RP2 |
| Raspberry Pi Pico W / WH | RPI_PICO_W-….uf2 | RPI-RP2 |
| Raspberry Pi Pico 2 | RPI_PICO2-….uf2 | RP2350 |
| Raspberry Pi Pico 2 W | RPI_PICO2_W-….uf2 | RP2350 |
- Nella pagina di download di micropython.org trova la scheda RPI_PICO_W (RPI_PICO2_W per il Pico 2 W) e scarica l'ultimo file .uf2 stabile, quello senza la scritta "preview".
- Tieni premuto il pulsante BOOTSEL del Pico W mentre colleghi il cavo USB dati al computer, poi rilascialo.
- Sul computer compare un'unità chiamata RPI-RP2. Trascinaci sopra il file scaricato; finita la copia, l'unità sparisce da sola e la scheda si riavvia con MicroPython.
- Apri Thonny e scegli MicroPython (Raspberry Pi Pico) dal menu dell'interprete in basso a destra. Se preferisci, la finestra "Install or update MicroPython" di Thonny fa la stessa installazione con un clic quando scegli la variante Pico W / Pico WH.
- Scrivi import network nella Shell. Se non compaiono errori, è installato il firmware giusto con supporto wireless.
Passo 2: collegarsi al WiFi con network.WLAN
Il Pico W ha due interfacce wireless: in modalità WLAN.IF_STA (station) si collega al router di casa come uno smartphone, in modalità WLAN.IF_AP (access point) crea una propria rete WiFi. Iniziamo dalla modalità station. Incolla il codice qui sotto in un nuovo file di Thonny, inserisci nome della rete e password e salvalo sul Pico come wifi.py. Tutti gli esempi successivi usano questo file con import wifi, così la password sta in un solo posto. Se usi una versione di MicroPython precedente alla 1.24, scrivi queste costanti come network.STA_IF e network.AP_IF; i vecchi nomi funzionano anche nelle versioni più recenti.
1# wifi.py: Pico W'ye bu adla kaydet / save it to the Pico W with this name
2import network
3import time
4
5SSID = "AgAdi" # Wi-Fi adın / your Wi-Fi name
6PASSWORD = "Sifre123" # Wi-Fi şifren / your Wi-Fi password
7HOSTNAME = "picow" # http://picow.local adresi için / for http://picow.local
8
9STATUS = {
10 0: "Boşta / idle",
11 1: "Ağa katılıyor / joining",
12 2: "IP bekleniyor / waiting for IP",
13 3: "Bağlandı / connected",
14 -1: "Bağlantı başarısız / connection failed",
15 -2: "Ağ bulunamadı / network not found",
16 -3: "Şifre hatalı / wrong password",
17}
18
19
20def connect(timeout=20):
21 network.country("TR") # ülke kodu / country code
22 network.hostname(HOSTNAME) # ağdaki adı / name on the network
23 wlan = network.WLAN(network.WLAN.IF_STA)
24 wlan.active(True)
25 wlan.config(pm=network.WLAN.PM_NONE) # güç tasarrufunu kapat / disable power saving
26 if not wlan.isconnected():
27 wlan.connect(SSID, PASSWORD)
28 for _ in range(timeout):
29 code = wlan.status()
30 print(code, STATUS.get(code, "?"))
31 if code < 0 or code == 3:
32 break
33 time.sleep(1)
34 if wlan.status() != 3:
35 raise RuntimeError("Wi-Fi: " + STATUS.get(wlan.status(), "?"))
36 print("IP:", wlan.ifconfig()[0])
37 return wlan
38
39
40if __name__ == "__main__":
41 connect()Vediamo le righe principali. network.country("TR") dice al chip wireless quali regole sui canali seguire; sostituisci TR con il codice del tuo paese, per esempio IT o CH. Se lo ometti, potresti faticare a vedere le reti sui canali 12 e 13, usati da alcuni router (nei firmware più vecchi si fa con rp2.country()). wlan.config(pm=network.WLAN.PM_NONE) disattiva il risparmio energetico (gli esempi più vecchi scrivono la stessa impostazione come pm=0xa11140): per impostazione predefinita il Pico W risparmia energia, e questo può far rispondere in ritardo il web server o far cadere la connessione dopo qualche ora. Il ciclo stampa il codice di stato ogni secondo e si ferma quando arriva a 3 o quando riceve un codice di errore negativo. Così la scheda non aspetta all'infinito e vedi sullo schermo che cosa non va.
Cosa significano i codici di wlan.status()?
La maggior parte dei problemi di connessione si risolve in pochi secondi guardando il numero restituito da wlan.status(). MicroPython offre anche costanti pronte per questi numeri nel modulo network; trovi entrambi nella tabella seguente:
| Codice | Costante | Significato | Cosa fare |
|---|---|---|---|
| 0 | STAT_IDLE | Nessuna connessione, non è partito nulla | Verifica che siano stati chiamati wlan.active(True) e wlan.connect() |
| 1 | STAT_CONNECTING | Si sta collegando alla rete | Aspetta qualche secondo |
| 2 | (nessuna costante) | Collegato alla rete, in attesa di un indirizzo IP dal router | Se ci mette troppo, controlla il DHCP del router |
| 3 | STAT_GOT_IP | Connesso con indirizzo IP | Tutto pronto |
| -1 | STAT_CONNECT_FAIL | Connessione fallita | Controlla segnale e alimentazione, poi riprova |
| -2 | STAT_NO_AP_FOUND | Rete non trovata | Controlla il nome della rete, la banda a 2,4 GHz e la distanza |
| -3 | STAT_WRONG_PASSWORD | Autenticazione fallita | Riscrivi la password facendo attenzione a maiuscole e minuscole |
Se ottieni il codice -2, il Pico W non vede la tua rete. Elencare le reti nei dintorni svela subito il problema: se la tua non compare, o trasmette a 5 GHz o il segnale è troppo debole. Un RSSI migliore di -70 dBm (per esempio -55 dBm) è comodo; intorno a -80 dBm la connessione comincia a cadere.
1import network
2
3wlan = network.WLAN(network.WLAN.IF_STA)
4wlan.active(True)
5for ssid, bssid, channel, rssi, security, hidden in wlan.scan():
6 print(ssid.decode(), "| kanal / channel:", channel, "| RSSI:", rssi, "dBm")Passo 3: un semplice web server in MicroPython (pagina per accendere e spegnere un LED)
Ora trasformiamo il Pico W in un piccolo web server da aprire con lo smartphone. Non serve nessuna libreria aggiuntiva: basta il modulo socket di MicroPython. Salva il codice qui sotto come main.py ed eseguilo. Digita l'indirizzo mostrato nella Shell (per esempio http://192.168.1.42) nel browser di uno smartphone collegato alla stessa rete WiFi; i pulsanti ON e OFF della pagina accendono e spengono il LED della scheda.
1import socket
2from machine import Pin
3import wifi
4
5wlan = wifi.connect()
6led = Pin("LED", Pin.OUT) # Pico W dahili LED / Pico W onboard LED
7led_on = False
8
9
10def page(on):
11 state = "AÇIK / ON" if on else "KAPALI / OFF"
12 return """<!DOCTYPE html>
13<html><head><meta charset="utf-8">
14<meta name="viewport" content="width=device-width, initial-scale=1">
15<title>Pico W LED</title></head>
16<body style="font-family:sans-serif;text-align:center">
17<h1>Pico W LED</h1>
18<p>Durum / State: <b>""" + state + """</b></p>
19<p><a href="/on"><button style="font-size:24px">AÇ / ON</button></a>
20<a href="/off"><button style="font-size:24px">KAPAT / OFF</button></a></p>
21</body></html>"""
22
23
24addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
25server = socket.socket()
26server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # EADDRINUSE hatasını önler / prevents EADDRINUSE
27server.bind(addr)
28server.listen(2)
29print("Tarayıcıda aç / open in browser: http://" + wlan.ifconfig()[0])
30
31while True:
32 client, remote = server.accept() # bir tarayıcı bekle / wait for a browser
33 try:
34 request = client.recv(1024) # b"GET /on HTTP/1.1 ..."
35 parts = request.split(b" ")
36 path = parts[1] if len(parts) > 1 else b"/"
37 if path == b"/on":
38 led.on()
39 led_on = True
40 elif path == b"/off":
41 led.off()
42 led_on = False
43 if path in (b"/", b"/on", b"/off"):
44 client.sendall("HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")
45 client.sendall(page(led_on))
46 else:
47 client.sendall("HTTP/1.0 404 Not Found\r\n\r\n") # ör. /favicon.ico / e.g. /favicon.ico
48 except OSError as e:
49 print("Bağlantı hatası / connection error:", e)
50 finally:
51 client.close()Vediamo come funziona. Con bind e listen il Pico W si mette in ascolto sulla porta 80 (HTTP), e accept() attende finché un browser non si collega. La prima riga della richiesta del browser è del tipo "GET /on HTTP/1.1"; il codice la divide sugli spazi per trovare il percorso richiesto (/on) e regola il LED di conseguenza. Poi invia l'intestazione HTTP ("HTTP/1.0 200 OK" e il tipo di contenuto), una riga vuota e infine la pagina HTML, e chiude la connessione. La riga meta viewport fa adattare bene la pagina allo smartphone e charset=utf-8 fa visualizzare correttamente le lettere accentate.
| Percorso | Cosa fa |
|---|---|
| / | Mostra la pagina e lo stato attuale del LED |
| /on | Accende il LED e invia di nuovo la pagina |
| /off | Spegne il LED e invia di nuovo la pagina |
| /favicon.ico e altri | Restituisce 404; i browser chiedono questo percorso da soli per l'icona della scheda |
Collegare un relè o un LED esterno al posto del LED integrato
Quando funziona con il LED integrato, per comandare un dispositivo vero dalla stessa pagina cambi una sola riga: sostituisci Pin("LED", Pin.OUT) per esempio con Pin(16, Pin.OUT). La resistenza giusta per un LED esterno la calcoli con lo strumento Resistenza per LED; per un pin a 3,3 V bastano 220–330 Ω. Se usi un modulo relè, alimentalo dal pin VBUS a 5 V e collega il suo ingresso IN al GPIO. Molti moduli relè scattano con un segnale LOW; in quel caso scambia le righe led.on() e led.off(). Trovi i dettagli del collegamento in Cos'è un modulo relè?.
| Componente | Pin del componente | Pin del Pico W (n. pin fisico) |
|---|---|---|
| LED esterno | Anodo (+), tramite una resistenza da 220 Ω | GP14 (19) |
| LED esterno | Catodo (−) | GND (18) |
| DHT22 | VCC / DATA / GND | 3V3(OUT) (36) / GP15 (20) / GND (38) |
| Modulo relè | VCC | VBUS, 5 V dall'USB (40) |
| Modulo relè | IN | GP16 (21) |
| Modulo relè | GND | GND (23) |
Passo 4: mostrare i dati di un sensore in tempo reale su una pagina web
La pagina del LED si ricaricava interamente a ogni pressione di un pulsante. In una pagina che mostra misure è molto più elegante che i valori si aggiornino senza ricaricare. Per questo useremo due percorsi: / invia la pagina stessa e /data solo le misure in formato JSON. Un piccolo codice JavaScript nella pagina legge /data ogni due secondi e aggiorna i numeri. L'esempio mostra il sensore di temperatura interno, che non richiede componenti aggiuntivi, e l'intensità del segnale WiFi (RSSI); inoltre costruisce il server con il modulo asyncio di MicroPython, così il Pico W continua a misurare mentre attende le richieste.
1import asyncio
2import json
3import time
4from machine import ADC, Pin
5import wifi
6
7wlan = wifi.connect()
8sensor = ADC(4) # dahili sıcaklık sensörü / internal temperature sensor
9led = Pin("LED", Pin.OUT)
10start = time.time()
11readings = {"temp": 0, "rssi": 0, "uptime": 0}
12
13HTML = """<!DOCTYPE html>
14<html><head><meta charset="utf-8">
15<meta name="viewport" content="width=device-width, initial-scale=1">
16<title>Pico W</title></head>
17<body style="font-family:sans-serif;text-align:center">
18<h1>Pico W</h1>
19<p>Sıcaklık / Temperature: <b id="t">-</b> °C</p>
20<p>Wi-Fi sinyali / signal: <b id="r">-</b> dBm</p>
21<p>Çalışma süresi / uptime: <b id="u">-</b> s</p>
22<script>
23async function update() {
24 try {
25 const d = await (await fetch("/data")).json();
26 document.getElementById("t").textContent = d.temp;
27 document.getElementById("r").textContent = d.rssi;
28 document.getElementById("u").textContent = d.uptime;
29 } catch (e) {}
30}
31update();
32setInterval(update, 2000);
33</script>
34</body></html>"""
35
36
37def read_temp():
38 volts = sensor.read_u16() * 3.3 / 65535
39 return round(27 - (volts - 0.706) / 0.001721, 1)
40
41
42async def measure():
43 while True:
44 readings["temp"] = read_temp()
45 readings["rssi"] = wlan.status("rssi") # yalnız STA modunda / STA mode only
46 readings["uptime"] = time.time() - start
47 led.toggle() # kalp atışı / heartbeat
48 await asyncio.sleep(2)
49
50
51async def handle(reader, writer):
52 try:
53 line = await reader.readline() # b"GET /data HTTP/1.1"
54 while True: # başlıkları atla / skip the headers
55 header = await reader.readline()
56 if header in (b"\r\n", b""):
57 break
58 parts = line.split(b" ")
59 path = parts[1] if len(parts) > 1 else b"/"
60 if path == b"/":
61 writer.write(b"HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")
62 writer.write(HTML.encode())
63 elif path == b"/data":
64 writer.write(b"HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n")
65 writer.write(json.dumps(readings).encode())
66 else:
67 writer.write(b"HTTP/1.0 404 Not Found\r\n\r\n")
68 await writer.drain()
69 except OSError as e:
70 print("Bağlantı hatası / connection error:", e)
71 finally:
72 writer.close()
73 await writer.wait_closed()
74
75
76async def main():
77 await asyncio.start_server(handle, "0.0.0.0", 80)
78 print("Tarayıcıda aç / open in browser: http://" + wlan.ifconfig()[0])
79 await measure()
80
81
82asyncio.run(main())asyncio.start_server() esegue la funzione handle come un task separato per ogni nuova connessione del browser, mentre il task measure() esegue una misura ogni due secondi in background e fa lampeggiare il LED integrato. Dal lampeggio capisci anche che la scheda non si è bloccata. Attenzione: con asyncio converti il testo in byte con .encode() prima di inviarlo, altrimenti le pagine con lettere accentate generano un errore. Il sensore di temperatura interno misura la temperatura del chip stesso, quindi i suoi valori sono rumorosi e si discostano di qualche grado da quella della stanza; la formula 27 − (V − 0,706) / 0,001721 nel codice viene dal datasheet dell'RP2040. Per la vera temperatura ambiente usa un sensore esterno.

Per misurare davvero temperatura e umidità collega un DHT22 (DATA su GP15). Il driver dei sensori DHT è già incluso nel firmware del Pico W, quindi non devi caricare altro. Nella funzione measure() del codice del sensore sostituisci la riga readings["temp"] = read_temp() con una chiamata a read_sensor() qui sotto e aggiungi all'HTML una riga per l'umidità. Il DHT22 non va letto più spesso di una volta ogni due secondi, che è proprio il ritmo del ciclo. Per saperne di più sul sensore leggi Sensore di temperatura e umidità DHT11.
1import dht
2from machine import Pin
3
4dht_sensor = dht.DHT22(Pin(15)) # DATA ucu GP15'te / DATA pin on GP15
5
6
7def read_sensor():
8 try:
9 dht_sensor.measure() # ölçümü başlat / trigger a reading
10 readings["temp"] = dht_sensor.temperature() # °C
11 readings["hum"] = dht_sensor.humidity() # % bağıl nem / % relative humidity
12 except OSError as e:
13 print("DHT22 okunamadı / read failed:", e)Passo 5: chiamare un'API con urequests (prendere dati da internet)
Il Pico W può fare anche da client, non solo da server: invia una richiesta a un servizio online e ne legge la risposta. Il modulo requests è già incluso nel firmware del Pico W; il nome urequests che trovi negli esempi più vecchi rimanda allo stesso modulo, quindi funzionano entrambe le forme. L'esempio seguente ottiene temperatura, umidità e velocità del vento attuali di Istanbul dal servizio meteo gratuito Open-Meteo, che non richiede una chiave API. Ti basta cambiare LAT e LON con quelli della tua città, per esempio 41.90 e 12.50 per Roma.
1import requests
2import wifi
3
4wifi.connect()
5
6# İstanbul; kendi konumunu yaz / Istanbul; put your own location
7LAT, LON = 41.01, 28.98
8URL = ("https://api.open-meteo.com/v1/forecast?latitude={}&longitude={}"
9 "¤t=temperature_2m,relative_humidity_2m,wind_speed_10m").format(LAT, LON)
10
11response = requests.get(URL)
12try:
13 if response.status_code == 200:
14 current = response.json()["current"]
15 print("Sıcaklık / temperature:", current["temperature_2m"], "°C")
16 print("Nem / humidity:", current["relative_humidity_2m"], "%")
17 print("Rüzgâr / wind:", current["wind_speed_10m"], "km/h")
18 else:
19 print("HTTP hatası / HTTP error:", response.status_code)
20finally:
21 response.close() # soketi ve belleği serbest bırak / free the socket and memoryIn questo codice ci sono tre cose a cui fare attenzione. Primo: chiama response.close() dopo ogni risposta; le risposte non chiuse consumano socket e memoria, e dopo qualche richiesta otterrai "OSError: [Errno 12] ENOMEM". Secondo: response.json() carica in memoria tutta la risposta; il Pico W ha 264 KB di RAM in totale, quindi con API che restituiscono JSON grandi usa indirizzi che chiedono solo i campi necessari (come il parametro current qui). Terzo: una connessione HTTPS richiede memoria in più per la cifratura; se invii richieste periodiche in un ciclo, aggiungere gc.collect() tra una e l'altra riduce la frammentazione della memoria. Con lo stesso metodo puoi inviare messaggi Telegram, scrivere dati in un foglio di calcolo o leggere i tassi di cambio; la creazione del bot Telegram è la stessa di Bot Telegram con ESP32.
Passo 6: l'ora esatta da internet con NTP
Il Pico W ha un orologio in tempo reale (RTC) interno, ma senza batteria tampone: a ogni accensione l'orologio torna al 1° gennaio 2021. Con il WiFi è facilissimo ottenere l'ora esatta dai server NTP di internet: la funzione settime() del modulo integrato ntptime imposta l'orologio interno in UTC. Per l'ora locale il codice aggiunge uno scostamento fisso; l'esempio usa 3 ore (10.800 secondi) per la Turchia. In Italia imposta UTC_OFFSET a 1 * 3600 in inverno e a 2 * 3600 durante l'ora legale.
1import time
2import ntptime
3import wifi
4
5wifi.connect()
6ntptime.host = "pool.ntp.org" # varsayılan sunucu / default server
7UTC_OFFSET = 3 * 3600 # Türkiye UTC+3; kendi saat dilimini yaz / set your own time zone
8
9for attempt in range(5):
10 try:
11 ntptime.settime() # dahili saati UTC'ye ayarlar / sets the internal clock to UTC
12 print("Saat ayarlandı / time set")
13 break
14 except OSError as e:
15 print("NTP hatası / NTP error:", e)
16 time.sleep(2)
17
18DAYS = ("Pzt/Mon", "Sal/Tue", "Çar/Wed", "Per/Thu", "Cum/Fri", "Cmt/Sat", "Paz/Sun")
19
20while True:
21 y, mo, d, h, mi, s, wd, yd = time.localtime(time.time() + UTC_OFFSET)
22 print("%02d.%02d.%d %s %02d:%02d:%02d" % (d, mo, y, DAYS[wd], h, mi, s))
23 time.sleep(1)Per impostazione predefinita ntptime usa il server pool.ntp.org e attende la risposta per un secondo; se non arriva, solleva "OSError: [Errno 110] ETIMEDOUT", ed è per questo che il codice ci prova cinque volte. L'orologio interno può spostarsi di qualche secondo nel tempo, quindi nei progetti che restano accesi a lungo richiama settime() una volta al giorno. Nei paesi con l'ora legale lo scostamento cambia due volte l'anno; dovrai gestirlo nel codice con un controllo sulla data. Se vuoi mostrare l'ora su un display, unisci questo codice agli esempi MicroPython degli articoli sul display OLED o sul display LCD I2C; la versione per ESP32 è in ESP32 NTP.
Creare una rete tutta tua (modalità AP) e l'indirizzo picow.local
Dove non c'è un router, per esempio allo stand di una fiera della scienza o in giardino, il Pico W può trasmettere una propria rete WiFi. In modalità access point colleghi lo smartphone direttamente alla rete "PicoW-BlueGrays" e apri la pagina all'indirizzo http://192.168.4.1. Il codice del web server funziona senza modifiche; scrivi semplicemente le righe qui sotto al posto di wlan = wifi.connect() e aggiungi wlan = ap. La password deve avere almeno 8 caratteri. La riga dell'RSSI nell'esempio del sensore funziona solo in modalità station, quindi eliminala in modalità AP. In questa modalità il Pico W non ha accesso a internet, perciò gli esempi NTP e API non funzionano.
1import network
2
3ap = network.WLAN(network.WLAN.IF_AP)
4ap.config(ssid="PicoW-BlueGrays", password="bluegrays123") # şifre en az 8 karakter / at least 8 characters
5ap.active(True)
6while not ap.active():
7 pass
8print("Ağ hazır / network ready:", ap.ifconfig()[0]) # genellikle 192.168.4.1 / usually 192.168.4.1Se leggere ogni volta l'indirizzo IP nella Shell ti pesa, puoi usare un nome. Le versioni recenti di MicroPython supportano mDNS sul Pico W: grazie alla riga network.hostname("picow") in wifi.py, la scheda risponde anche all'indirizzo http://picow.local. Questo indirizzo di solito funziona su Windows, macOS, Linux e iPhone; alcuni smartphone Android non aprono gli indirizzi .local, quindi lì usa l'IP. Se vuoi che l'indirizzo IP non cambi mai, la soluzione più affidabile è assegnare un IP fisso all'indirizzo MAC del Pico W dalle impostazioni del router (prenotazione DHCP).
Nota sul Pico 2 W: cosa cambia?
Il Pico 2 W ha le stesse dimensioni e la stessa piedinatura del Pico W e usa lo stesso chip wireless CYW43439; cambia solo il processore, il più veloce RP2350. Lato software l'unica differenza è il firmware: scarica da micropython.org il file RPI_PICO2_W, e quando lo colleghi con BOOTSEL l'unità compare come RP2350. Tutto il codice MicroPython di questo articolo funziona senza modifiche. Con 520 KB di RAM, le richieste HTTPS, le risposte JSON grandi e le pagine HTML lunghe stanno molto più comode sul Pico 2 W. Nell'Arduino IDE si sceglie la scheda Raspberry Pi Pico 2W. Una nota: le prime versioni dell'RP2350 hanno un erratum noto (E9) che riguarda le resistenze di pull-down interne; per i pulsanti, collegarli a GND e usare PULL_UP è la soluzione più sicura. Per funzioni avanzate come i due core e il PIO leggi PIO e dual core del Pico.
Alternativa: programmare il Pico W con l'Arduino IDE (arduino-pico)
Se C++ e librerie Arduino ti sono più familiari, puoi programmare il Pico W dall'Arduino IDE con il core arduino-pico di Earle Philhower. Include librerie WiFi e WebServer compatibili con quelle dell'ESP32, quindi il codice di un web server scritto per l'ESP32 funziona sul Pico W con piccole modifiche.
- Nell'Arduino IDE apri File > Impostazioni e aggiungi https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json nel campo "URL aggiuntive per il Gestore schede".
- Nel Gestore schede cerca pico e installa il pacchetto Raspberry Pi Pico/RP2040/RP2350 di Earle F. Philhower.
- Scegli Raspberry Pi Pico W da Strumenti > Scheda (Raspberry Pi Pico 2W per il Pico 2 W).
- Al primo caricamento collega la scheda tenendo premuto BOOTSEL; l'Arduino IDE la trova come unità UF2. Nei caricamenti successivi basta scegliere la porta seriale che compare in Strumenti > Porta.
- Dopo il caricamento apri il Monitor seriale a 115200 baud e leggi l'indirizzo IP.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <LEAmDNS.h>
4
5const char* ssid = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
6const char* password = "Sifre123"; // Wi-Fi şifren / your Wi-Fi password
7
8WebServer server(80);
9bool ledOn = false;
10
11void sendPage() {
12 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
13 "<meta name='viewport' content='width=device-width, initial-scale=1'>"
14 "<title>Pico W</title></head>"
15 "<body style='font-family:sans-serif;text-align:center'><h1>Pico W LED</h1>";
16 html += "<p>Durum / State: <b>";
17 html += ledOn ? "AÇIK / ON" : "KAPALI / OFF";
18 html += "</b></p><p><a href='/on'><button>AÇ / ON</button></a> ";
19 html += "<a href='/off'><button>KAPAT / OFF</button></a></p>";
20 html += "<p>Sıcaklık / Temp: ";
21 html += String(analogReadTemp(), 1); // dahili sensör / internal sensor
22 html += " °C</p></body></html>";
23 server.send(200, "text/html", html);
24}
25
26void setup() {
27 Serial.begin(115200);
28 pinMode(LED_BUILTIN, OUTPUT); // Pico W'de kablosuz yongadaki LED / the LED on the wireless chip
29 WiFi.mode(WIFI_STA);
30 WiFi.begin(ssid, password);
31 while (WiFi.status() != WL_CONNECTED) {
32 delay(500);
33 Serial.print(".");
34 }
35 Serial.println();
36 Serial.print("IP: ");
37 Serial.println(WiFi.localIP()); // bu adresi telefonda aç / open this address on your phone
38
39 MDNS.begin("picow"); // http://picow.local
40 server.on("/", sendPage);
41 server.on("/on", []() { ledOn = true; digitalWrite(LED_BUILTIN, HIGH); sendPage(); });
42 server.on("/off", []() { ledOn = false; digitalWrite(LED_BUILTIN, LOW); sendPage(); });
43 server.onNotFound([]() { server.send(404, "text/plain", "404"); });
44 server.begin();
45}
46
47void loop() {
48 server.handleClient();
49 MDNS.update();
50}Questo sketch fa la stessa cosa della pagina LED in MicroPython e aggiunge la temperatura interna letta con analogReadTemp(). Sul Pico W LED_BUILTIN comanda automaticamente il LED collegato al chip wireless, e grazie alla riga MDNS.begin("picow") la pagina si apre anche all'indirizzo http://picow.local. Il driver WiFi aggiunge circa 220 KB al programma compilato, quindi la prima compilazione può richiedere un po' di tempo. Nella scelta tra MicroPython e Arduino tieni presente questo: con MicroPython salvi il codice e lo provi subito; con Arduino aspetti la compilazione, ma ottieni codice più veloce e un'ampia scelta di librerie.
Idee di progetti con il Raspberry Pi Pico W
- Termometro WiFi: controlla dallo smartphone temperatura e umidità misurate con un DHT11 o DHT22.
- Lampada dallo smartphone: aggiungi un modulo relè alla pagina LED di questo articolo e accendi o spegni la lampada della scrivania.
- Monitor dell'umidità delle piante: mostra sulla pagina il valore del sensore di umidità del terreno e ricevi un avviso quando la terra si secca.
- Allarme di movimento: quando un sensore PIR rileva qualcuno, invia un messaggio Telegram al tuo smartphone con urequests.
- Orologio da internet: mostra l'ora NTP con data e giorno della settimana su un display OLED.
- Domotica: installa la libreria umqtt.simple con mip e invia le tue misure a Home Assistant tramite MQTT; il principio è spiegato in ESP32 MQTT.
- Dashboard in tempo reale: per pagine che si aggiornano più velocemente, adatta al Pico W le idee dell'articolo web server asincrono con ESP32, basato su WebSocket.
Errori comuni e soluzioni
| Sintomo o errore | Causa | Soluzione |
|---|---|---|
| ImportError: no module named 'network' | Sul Pico W è stato caricato il firmware del Pico normale | Carica l'UF2 RPI_PICO_W (RPI_PICO2_W per il Pico 2 W) |
| wlan.status() resta a -2 | Rete non visibile: 5 GHz, nome della rete sbagliato o segnale debole | Attiva la banda a 2,4 GHz, cerca la rete con wlan.scan(), avvicina la scheda al router |
| wlan.status() restituisce -3 | Password sbagliata | Riscrivila facendo attenzione a maiuscole, minuscole e spazi |
| OSError: [Errno 98] EADDRINUSE | Il socket del server precedente occupa ancora la porta 80 | Usa SO_REUSEADDR e riavvia con Ctrl+D |
| La pagina non si apre sullo smartphone | Lo smartphone è sulla rete dati, sulla rete ospiti o il router ha l'isolamento dei client attivo | Collega lo smartphone allo stesso WiFi e scrivi l'indirizzo con http, non https |
| OSError: -2 (urequests) | Impossibile risolvere il nome: WiFi non collegato o problema DNS | Chiama prima wifi.connect() e controlla l'URL |
| OSError: [Errno 12] ENOMEM | Memoria piena | Usa response.close() e gc.collect(), chiedi risposte più piccole |
| La connessione cade dopo qualche ora | Risparmio energetico o riavvio del router | Usa pm=network.WLAN.PM_NONE, controlla wlan.isconnected() nel ciclo e ricollegati |
| Non funziona scollegato dal computer | Il codice non è salvato come main.py o wifi.py manca sul Pico | Salva entrambi i file sul Pico |
Come hai visto, collegare il Raspberry Pi Pico W al WiFi, pubblicare una pagina web e prendere dati da internet richiede solo un paio di file: wifi.py gestisce la connessione e main.py il progetto vero e proprio. Per consolidare le basi del Pico, nell'app BlueGrays trovi progetti con il Raspberry Pi Pico per accendere LED, un semaforo, PWM e LED RGB, e sul fronte ESP32 progetti di connessione WiFi, web server asincrono, orologio NTP e API meteo, tutti con schema del circuito e codice passo passo.
Domande frequenti
Il Raspberry Pi Pico W si collega al WiFi a 5 GHz?
No. Il chip CYW43439 del Pico W e del Pico 2 W funziona solo nella banda a 2,4 GHz e non vede le reti a 5 GHz. Assicurati che la banda a 2,4 GHz del router sia attiva; se le due bande hanno lo stesso nome e hai problemi, dare un nome separato alla 2,4 GHz di solito risolve.
Come si installa MicroPython sul Pico W?
Scarica da micropython.org il file .uf2 della scheda RPI_PICO_W. Tieni premuto BOOTSEL mentre colleghi il Pico W al computer e trascina il file sull'unità RPI-RP2 che compare. La scheda si riavvia ed è pronta per Thonny; anche la finestra "Install or update MicroPython" di Thonny fa la stessa cosa.
Come trovo l'indirizzo IP del Pico W?
Dopo la connessione, wlan.ifconfig()[0] restituisce l'indirizzo IP, e il file wifi.py di questo articolo lo stampa nella Shell. Se la scheda non è collegata al computer, guarda l'elenco dei dispositivi connessi nelle impostazioni del router oppure prova http://picow.local sui dispositivi che supportano mDNS.
Perché il LED integrato del Pico W non si accende con Pin(25)?
Sul Pico W il LED integrato è collegato al chip wireless e non al processore, e GP25 è usato come linea di selezione di quel chip. Con Pin("LED", Pin.OUT) in MicroPython o LED_BUILTIN nell'Arduino IDE il LED si accende correttamente. Questa forma funziona anche sul Pico normale, quindi puoi usarla sempre.
Posso accedere al web server del Pico W da internet?
Tecnicamente sì, con il port forwarding del router, ma non è consigliato, perché un semplice server MicroPython non ha cifratura né autenticazione. Per il controllo da remoto, un intermediario come MQTT, un bot Telegram o un servizio IoT in cloud è molto più sicuro.
Meglio il Pico W o l'ESP32 per i progetti WiFi?
Entrambi offrono WiFi a 2,4 GHz e Bluetooth. Se vuoi lavorare con MicroPython, una documentazione ordinata e pin senza sorprese, scegli il Pico W; se ti servono più velocità, molti ingressi analogici e un'ampia scelta di librerie Arduino, l'ESP32 è più adatto. Per semplici web server, sensori e chiamate API vanno benissimo entrambi.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Lampeggio LED Integrato Raspberry Pi Pico (Pico e Pico W)
Il progetto di apertura della serie Raspberry Pi Pico! Facciamo lampeggiare il LED verde integrato per verificare che la scheda funzioni — un classico primo esperimento "Hello World". NESSUN componente esterno, solo Pico e cavo USB. Il codice è scritto in MicroPython (il linguaggio ufficialmente supportato dalla Raspberry Pi Foundation). Impara la classe machine.Pin, la modalità Pin.OUT, i metodi led.on()/off() e time.sleep() in Thonny IDE. Segui ogni commutazi

Accensione di un LED esterno con Raspberry Pi Pico (breadboard)
Il passo successivo dopo il LED integrato di Pico: collegare un LED esterno alla breadboard e controllarlo tramite il pin GP14. Con questo progetto imparerai come utilizzare qualsiasi pin GPIO generico del Pico come uscita, la polarità del LED (stelo lungo = anodo/+, stelo corto = catodo/–) e perché è indispensabile un resistore di limitazione della corrente (220 Ω). Se non inserisci il resistore, l’LED riceverà una corrente eccessiva e potrebbe bruciarsi. Il circuito è molto semplice: Pico GP14

Simulatore Semaforo Raspberry Pi Pico (3 LED Sequenziali)
Simuliamo un vero semaforo con LED rosso, giallo e verde. Verde 4 sec "vai", giallo 1,5 sec "preparati", rosso 3 sec "fermati" e rosso+giallo 1 sec "partenza" (pattern europeo). Impara la definizione di funzione, la logica della macchina a stati e la sincronizzazione multi-GPIO. Circuito semplice: 3 LED su GP11/GP12/GP13.

Raspberry Pi Pico PWM LED Fade (Effetto Respiro)
Il LED non lampeggia più — respira! Con il PWM (modulazione di larghezza d'impulso) del Raspberry Pi Pico, la luminosità sale e scende lentamente. Impara la classe machine.PWM, duty_u16() (luminosità a 16 bit 0–65535), la frequenza PWM, i cicli range() e l'uscita quasi analogica. Base per miscelazione colori RGB, controllo motori, servo e buzzer.

Server web asincrono ESP32 (con indicazione dell'IP sul display LCD)
In questo progetto trasformiamo l'ESP32 in un server web asincrono che potrete controllare dal vostro telefono o computer collegato alla stessa rete Wi-Fi. Grazie alla libreria ESPAsyncWebServer, il server è in grado di elaborare più richieste contemporaneamente (a differenza del classico WebServer.h, che si blocca su una singola richiesta).

Connessione Wi-Fi STA con ESP32 (con display LCD)
In questo progetto colleghiamo l'ESP32 alla rete Wi-Fi domestica in modalità Station (STA) in modo sicuro e tollerante agli errori. Separiamo SSID e password in un file secrets.h per impedire fughe su Git, impostiamo un meccanismo di riconnessione automatica e visualizziamo il livello del segnale RSSI e l'indirizzo IP su un display LCD I2C. Il LED interno funge da indicatore di stato.

ESP32: ora reale da Internet tramite NTP
L'ESP32 si connette al Wi-Fi e recupera l'ora reale con precisione al millisecondo dai server NTP (Network Time Protocol). Grazie a configTzTime(), il fuso orario della Turchia (TRT, UTC+3) viene applicato automaticamente e il passaggio all'ora legale è gestito tramite la stringa POSIX TZ. L'ora viene mostrata sul Serial Monitor e su un display LCD I2C opzionale. configTzTime() avvia il servizio SNTP; vengono eseguite risincronizzazioni periodiche finché è disponibile l'accesso alla rete, e

ESP32 HTTPClient + API meteo (con schermo LCD)
In questo progetto, utilizzando l'ESP32, effettuiamo una chiamata REST all'API meteo (wttr.in) tramite Internet utilizzando HTTPClient.h. Analizziamo la risposta JSON restituita tramite ArduinoJson v7 e visualizziamo le informazioni relative a città, temperatura, umidità, condizioni meteorologiche e vento sul display LCD I2C sia in turco che in inglese. wttr.in è gratuito e non richiede una chiave API: basta digitare il nome di una città qualsiasi per ottenere le condizioni meteorologiche in t
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 200 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

