Webserver con Arduino Uno ed Ethernet Shield per controllare 4 relè
Creiamo una pagina web ospitata direttamente su Arduino per accendere e spegnere quattro uscite dalla rete locale usando un normale browser, anche da smartphone collegato al Wi-Fi di casa.
Cosa imparerai
- assegnare un indirizzo IP statico ad Arduino;
- avviare un webserver sulla porta 80;
- leggere una richiesta HTTP proveniente dal browser;
- generare una semplice pagina HTML direttamente da Arduino;
- controllare quattro uscite dalla rete locale;
- capire il rapporto tra Ethernet, LAN, browser e indirizzi IP.
Materiale necessario
đ§° Kit Arduino consigliato
Un kit completo è utile per avere breadboard, cavetti, resistenze, LED e molti componenti di base per sperimentare con Arduino.
đ Guarda il kit Arduino consigliatoLink di affiliazione Amazon: in qualitĂ di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
đ Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti piĂš completi, puoi dare unâocchiata anche ai miei libri dedicati ad Arduino. Allâinterno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.
đ Scopri i miei libri su ArduinoLink di affiliazione Amazon: in qualitĂ di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
Schema del circuito
Arduino Uno, Ethernet Shield e modulo relè a quattro canali.
Pin consigliati
| Funzione | Pin Arduino |
|---|---|
| Relè 1 | D2 |
| Relè 2 | D3 |
| Relè 3 | D5 |
| Relè 4 | D6 |
| CS Ethernet | D10 |
| SPI MOSI / MISO / SCK | D11 / D12 / D13 |
Video dimostrativo
Scegliere l’indirizzo IP
Nell’esempio Arduino utilizza 192.168.1.89. L’indirizzo deve appartenere alla stessa sottorete del router e non deve essere giĂ utilizzato da un altro dispositivo.
IPAddress ip(192, 168, 1, 89);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);Codice Arduino commentato
/*
WEBSERVER CON ARDUINO UNO + ETHERNET SHIELD
Controllo di 4 uscite dalla rete locale tramite browser.
Uscite consigliate:
Relè 1 -> D2
Relè 2 -> D3
Relè 3 -> D5
Relè 4 -> D6
Nota:
molti Ethernet Shield con slot microSD utilizzano D4 come
Chip Select della SD. Per evitare conflitti, qui NON usiamo D4
come uscita relè.
Ethernet Shield:
- SPI su D11, D12, D13
- CS Ethernet normalmente su D10
IP di esempio: 192.168.1.89
*/
#include <SPI.h>
#include <Ethernet.h>
// ---------------------------
// Uscite relè
// ---------------------------
const byte RELAY_1 = 2;
const byte RELAY_2 = 3;
const byte RELAY_3 = 5;
const byte RELAY_4 = 6;
// Imposta questi due valori in base al tuo modulo relè.
// Molti moduli sono active LOW.
const byte RELAY_ON = HIGH;
const byte RELAY_OFF = LOW;
// ---------------------------
// Configurazione di rete
// ---------------------------
byte mac[] = {
0xDE, 0xAD, 0xBE,
0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 89);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(80);
// Buffer semplice per la prima riga HTTP
String richiesta;
void setup() {
Serial.begin(9600);
pinMode(RELAY_1, OUTPUT);
pinMode(RELAY_2, OUTPUT);
pinMode(RELAY_3, OUTPUT);
pinMode(RELAY_4, OUTPUT);
// Tutte le uscite partono spente
digitalWrite(RELAY_1, RELAY_OFF);
digitalWrite(RELAY_2, RELAY_OFF);
digitalWrite(RELAY_3, RELAY_OFF);
digitalWrite(RELAY_4, RELAY_OFF);
// Avvia Ethernet con IP statico
Ethernet.begin(mac, ip, gateway, gateway, subnet);
server.begin();
Serial.print("Webserver disponibile su: http://");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (!client) {
return;
}
richiesta = "";
bool rigaVuota = true;
// Legge la richiesta HTTP con un piccolo timeout
unsigned long inizio = millis();
while (client.connected() && millis() - inizio < 1000UL) {
if (!client.available()) {
continue;
}
char c = client.read();
// Salva solo una quantitĂ limitata di dati
if (richiesta.length() < 120) {
richiesta += c;
}
// Fine header HTTP: riga vuota
if (c == '\n' && rigaVuota) {
break;
}
if (c == '\n') {
rigaVuota = true;
}
else if (c != '\r') {
rigaVuota = false;
}
}
// ---------------------------
// Interpreta i comandi
// ---------------------------
gestisciComando(richiesta);
// ---------------------------
// Risposta HTTP
// ---------------------------
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println("Connection: close");
client.println();
client.println(F("<!DOCTYPE html>"));
client.println(F("<html><head>"));
client.println(F("<meta name='viewport' content='width=device-width,initial-scale=1'>"));
client.println(F("<title>Arduino Webserver</title>"));
// CSS incorporato: non dipende da file esterni
client.println(F(
"<style>"
"body{font-family:Arial;background:#f5f7fb;color:#1f2937;"
"max-width:700px;margin:40px auto;padding:20px}"
".card{background:#fff;border-radius:16px;padding:24px;"
"box-shadow:0 8px 25px #0001}"
"a{display:inline-block;margin:6px;padding:12px 16px;"
"border-radius:9px;background:#2563eb;color:#fff;"
"text-decoration:none;font-weight:bold}"
"h1{margin-top:0}"
"</style>"
));
client.println(F("</head><body><div class='card'>"));
client.println(F("<h1>Controllo dispositivi</h1>"));
client.println(F("<p>Arduino Uno + Ethernet Shield</p>"));
stampaPulsanti(client, 1);
stampaPulsanti(client, 2);
stampaPulsanti(client, 3);
stampaPulsanti(client, 4);
client.println(F("</div></body></html>"));
delay(1);
client.stop();
}
// --------------------------------------------------
// Controlla quale comando è presente nell'URL
// --------------------------------------------------
void gestisciComando(const String &req) {
if (req.indexOf("GET /?r1=on") >= 0)
digitalWrite(RELAY_1, RELAY_ON);
if (req.indexOf("GET /?r1=off") >= 0)
digitalWrite(RELAY_1, RELAY_OFF);
if (req.indexOf("GET /?r2=on") >= 0)
digitalWrite(RELAY_2, RELAY_ON);
if (req.indexOf("GET /?r2=off") >= 0)
digitalWrite(RELAY_2, RELAY_OFF);
if (req.indexOf("GET /?r3=on") >= 0)
digitalWrite(RELAY_3, RELAY_ON);
if (req.indexOf("GET /?r3=off") >= 0)
digitalWrite(RELAY_3, RELAY_OFF);
if (req.indexOf("GET /?r4=on") >= 0)
digitalWrite(RELAY_4, RELAY_ON);
if (req.indexOf("GET /?r4=off") >= 0)
digitalWrite(RELAY_4, RELAY_OFF);
}
// --------------------------------------------------
// Crea i pulsanti ON / OFF per ogni uscita
// --------------------------------------------------
void stampaPulsanti(EthernetClient &client, byte numero) {
client.print(F("<p>Dispositivo "));
client.print(numero);
client.print(F(": "));
client.print(F("<a href='/?r"));
client.print(numero);
client.print(F("=on'>ON</a>"));
client.print(F("<a href='/?r"));
client.print(numero);
client.print(F("=off'>OFF</a>"));
client.println(F("</p>"));
}
Come funziona il webserver
1. EthernetServer sulla porta 80
EthernetServer server(80) mette Arduino in ascolto sulla porta HTTP standard.
2. Il browser apre una connessione
Quando digiti l’IP nel browser, Arduino riceve una richiesta HTTP attraverso EthernetClient.
3. I pulsanti modificano l’URL
Premendo ON o OFF il browser richiama indirizzi come /?r1=on oppure /?r1=off.
4. Arduino interpreta il comando
La funzione gestisciComando() cerca il comando nella richiesta e modifica lo stato del relativo pin digitale.
5. La pagina viene generata dalla scheda
Arduino invia al browser HTML e CSS essenziali. Non serve un server esterno: l’interfaccia è prodotta direttamente dalla scheda.
Accedere da smartphone tramite Wi-Fi
L’Ethernet Shield rimane collegato via cavo al router, ma uno smartphone o un notebook connesso al Wi-Fi della stessa LAN può raggiungere Arduino usando lo stesso indirizzo IP.
192.168.1.89, apri nel browser http://192.168.1.89.Relè active LOW
Molti moduli relè si attivano quando l’ingresso viene portato LOW. Se il tuo modulo si comporta al contrario, modifica queste due costanti:
const byte RELAY_ON = LOW;
const byte RELAY_OFF = HIGH;Sicurezza della rete
Controllare carichi a tensione di rete
Per le prove didattiche è preferibile utilizzare LED o carichi a bassa tensione. Se un relè deve comandare dispositivi collegati alla rete elettrica, servono isolamento, contenitore, cablaggi e protezioni adeguati.
Scarica lo sketch
âŹď¸ Scarica arduino_ethernet_shield_web_server_con_arduino_uno.ino
Debug rapido
- controlla che Arduino e il dispositivo con il browser siano nella stessa rete;
- verifica che l’IP scelto non sia giĂ occupato;
- controlla cavo Ethernet e LED di link sullo shield;
- se la pagina non si apre, verifica gateway, subnet e indirizzo IP;
- se i relè lavorano al contrario, configura correttamente
RELAY_ONeRELAY_OFF; - se lo shield ha microSD, evita di usare D4 senza verificare il relativo Chip Select;
- usa il Monitor Seriale per leggere l’indirizzo assegnato al server.
Varianti del progetto
- mostrare lo stato ON/OFF di ogni uscita nella pagina;
- aggiungere sensori di temperatura e umiditĂ ;
- usare DHCP invece dell’IP statico;
- aggiungere una pagina con valori analogici;
- salvare configurazioni su microSD;
- passare a ESP32 per Wi-Fi integrato e maggiori risorse;
- integrare il progetto in una rete domotica locale.
Cosa devi ricordare
- Arduino può ospitare una semplice pagina web direttamente sulla LAN.
- Ethernet Shield comunica tramite SPI.
- Il browser invia comandi attraverso richieste HTTP.
- Lo smartphone può raggiungere Arduino via Wi-Fi se è nella stessa rete.
- D4 può essere riservato alla microSD su molti shield.
- Questo webserver è adatto alla LAN, non all’esposizione diretta su Internet.
Domande frequenti
Posso aprire la pagina dallo smartphone?
SĂŹ. Lo smartphone deve essere collegato alla stessa rete locale di Arduino e deve poter raggiungere il suo indirizzo IP.
Devo usare per forza 192.168.1.89?
No. Ă soltanto un esempio. Devi scegliere un indirizzo valido nella tua rete e non utilizzato da altri dispositivi.
PerchÊ evitiamo D4 per un relè?
Su molti Ethernet Shield D4 è il Chip Select della microSD integrata. Usarlo come normale uscita può interferire con il bus SPI.
Posso controllarlo da fuori casa?
Non è consigliabile pubblicare direttamente questo semplice server HTTP su Internet. Per l’accesso remoto è preferibile utilizzare una VPN e mantenere Arduino accessibile soltanto dalla LAN.

