Tutorial · Intermedio · 1.5 ore
Controlla un robot dal browser con un server web ESP32
Trasforma un ESP32 in un access point Wi-Fi che serve una pagina di controllo: qualsiasi telefono può guidare il robot dal browser senza installare app.
Introduzione
Un HC-05 richiede un’app terminale seriale e una procedura di abbinamento. Un ESP32 può fare di meglio: diventare la propria rete e servire la propria pagina di controllo. Colleghi il telefono alla rete Wi-Fi del robot, apri un browser e guidi. Non devi installare nulla e funziona con qualsiasi dispositivo dotato di browser.
L’ESP32 integra nel chip Wi-Fi e Bluetooth, due core a 240 MHz e RAM sufficiente per conservare una pagina web nella flash e servirla. Ecco tutto il trucco.
Punto di accesso o rete esistente?
Ci sono due modalità e la scelta conta più di quanto sembri.
Punto di accesso (AP) — l’ESP32 crea la propria rete Wi-Fi e il telefono vi si collega.
- Funziona ovunque, senza un router. Il robot è autonomo.
- Il telefono perde la connessione a Internet durante la guida e alcuni telefoni tornano silenziosamente ai dati mobili, facendoti perdere il collegamento.
- L’indirizzo è sempre lo stesso, in genere
192.168.4.1.
Stazione (STA) — l’ESP32 si collega alla tua rete Wi-Fi esistente.
- Il telefono mantiene la connessione a Internet.
- L’IP del robot viene assegnato dal router e può cambiare tra un avvio e l’altro.
- È inutile fuori dalla portata di quella specifica rete, il che lo rende inadatto alle dimostrazioni.
Per un robot che porti con te, la modalità AP è quasi sempre la scelta giusta:
#include <WiFi.h>
#include <WebServer.h>
WebServer server(80);
void setup() {
WiFi.softAP("RobotCar", "drive1234"); // password must be 8+ characters
Serial.println(WiFi.softAPIP()); // 192.168.4.1
server.on("/", handleRoot);
server.on("/cmd", handleCommand);
server.begin();
}
void loop() {
server.handleClient();
applyDeadman(); // see below — this is not optional
}
Servire la pagina di controllo
La pagina risiede nella flash come stringa grezza. Mantienila piccola — ogni byte viene servito da un microcontrollore — e rendi i controlli compatibili con il tocco, perché tutto lo scopo è controllare il robot da un telefono.
const char PAGE[] PROGMEM = R"(
<!doctype html><meta name=viewport content="width=device-width,initial-scale=1">
<style>
body{font-family:system-ui;margin:0;display:grid;place-items:center;height:100vh}
button{width:90px;height:90px;font-size:24px;margin:4px;touch-action:manipulation}
</style>
<div>
<div style="text-align:center"><button data-c="F">▲</button></div>
<div><button data-c="L">◀</button><button data-c="S">■</button><button data-c="R">▶</button></div>
<div style="text-align:center"><button data-c="B">▼</button></div>
</div>
<script>
let held = null;
const send = c => fetch('/cmd?c=' + c);
for (const b of document.querySelectorAll('button')) {
// Repeat while held, so releasing and losing signal look the same to the robot.
b.onpointerdown = e => { held = b.dataset.c; send(held);
b.setPointerCapture(e.pointerId); };
b.onpointerup = b.onpointercancel = () => { held = null; send('S'); };
}
setInterval(() => held && send(held), 100);
</script>
)";
void handleRoot() { server.send_P(200, "text/html", PAGE); }
touch-action: manipulation sui pulsanti è importante: senza di esso, i browser mobili attendono circa 300 ms per capire se intendevi un doppio tocco e il robot sembra non funzionare.
Di nuovo il timeout di sicurezza
Tutto ciò che il tutorial Bluetooth dice sulla perdita del collegamento vale anche qui, e a maggior ragione: la portata Wi-Fi termina improvvisamente anziché in modo graduale.
unsigned long lastCommandAt = 0;
void handleCommand() {
char c = server.arg("c")[0];
drive(c);
lastCommandAt = millis();
server.send(200, "text/plain", "ok");
}
void applyDeadman() {
if (millis() - lastCommandAt > 400) stop();
}
Il browser invia il comando tenuto premuto ogni 100 ms, quindi un timeout di 400 ms tollera tre richieste perse prima di fermarsi. Questa proporzione è ciò che devi regolare: se è troppo stretto, il robot avanza a scatti su un collegamento debole; se è troppo ampio, continua a muoversi dopo che hai perso il collegamento.
Quando passare ai WebSocket
L’approccio con fetch appena descritto apre una nuova connessione HTTP per ogni comando. È semplice, facile da eseguire nel debug nella scheda di rete del browser e va bene a 10 comandi al secondo.
Smette di andare bene quando vuoi ricevere telemetria. Il polling dei valori dei sensori con ulteriori richieste HTTP raddoppia il traffico e aggiunge latenza in entrambe le direzioni. Un WebSocket mantiene aperta una sola connessione e permette a entrambe le parti di comunicare in qualsiasi momento:
#include <WebSocketsServer.h>
WebSocketsServer ws(81);
void onWsEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t len) {
if (type == WStype_TEXT) { drive(payload[0]); lastCommandAt = millis(); }
if (type == WStype_DISCONNECTED) stop(); // the link closing IS a stop command
}
L’ultima riga è il vero miglioramento. Con HTTP il robot può solo dedurre una connessione persa dal silenzio; un WebSocket ti avvisa nel momento in cui si chiude, così il robot si ferma immediatamente invece che dopo un timeout.
Inizia con HTTP. Passa ai WebSocket quando vuoi che il robot risponda.
Come alimentarlo
L’ESP32 è un componente da 3.3 V e assorbe corrente a impulsi intensi quando la radio trasmette — ben oltre 200 mA al picco. Ne conseguono due aspetti:
Non alimentarlo dal pin 3.3 V di Arduino. Quel regolatore non può fornire i picchi di trasmissione e il sintomo è una scheda che si riavvia ogni volta che il Wi-Fi è congestionato, cosa che sembra un bug del codice ma non lo è.
I suoi pin GPIO non tollerano 5 V. Qualsiasi segnale in ingresso all’ESP32 proveniente da logica a 5 V richiede un divisore di tensione o un traslatore di livelli, come per la linea RX dell’HC-05.
Forniscigli un’alimentazione adeguata dal pacco batteria tramite un proprio regolatore, tenendo separata l’alimentazione dei motori.
Verifica prima di metterti in movimento
- Serve la pagina. Collega un telefono a
RobotCar, aprihttp://192.168.4.1e verifica che compaiano i pulsanti. - Osserva i comandi. Stampa ogni comando ricevuto via USB. Tieni premuto un pulsante e verifica che le ripetizioni arrivino all’incirca a 10 al secondo.
- Interrompi il collegamento. Tieni premuto avanti, poi disattiva il Wi-Fi del telefono. Il robot deve fermarsi entro il timeout.
Poi montalo su un robot: il progetto del robot controllato dal telefono realizza tutto l’insieme, via radio o altro, su un telaio che può anche muoversi autonomamente.
Esplora il grafo
Fa parte di queste costruzioni
Progetti e percorsi di apprendimento che includono questo tutorial.
Per approfondire