Casa domotica con Arduino: plastico, sensori, codice e app
Progetto di casa domotica con Arduino passo passo: plastico, luce con PIR, allarme gas e incendio, porta RFID, relè e controllo dallo smartphone con ESP32.
Un progetto di casa domotica con Arduino rende automatiche, grazie ai sensori, le luci, la porta, la finestra e gli allarmi di un plastico e, se vuoi, ti permette di controllare tutto anche dallo smartphone. Non a caso è uno dei progetti scolastici più amati. Una luce del corridoio che si accende quando rileva un movimento, un allarme che suona in caso di fuga di gas, una ventola che parte quando fa caldo e una porta che si apre con una tessera formano una copia in miniatura, ma funzionante, di un vero impianto domotico. Con un Arduino Uno o un ESP32, una decina di moduli e un fine settimana puoi farlo anche tu.
In questa guida partiamo dal progetto del plastico: quale modulo va in quale stanza, dove finisce il budget, come pianificare l'alimentazione e come distribuire i pin. Poi montiamo e collaudiamo ogni modulo uno alla volta e scriviamo lo sketch Arduino completo che li fa funzionare tutti insieme senza usare delay(). Nelle ultime sezioni vedrai come controllare la casa dallo smartphone con un web server sull'ESP32 o con Blynk, come risolvere gli errori più comuni e come fare colpo sulla commissione durante la presentazione a scuola.






Come funziona una casa domotica?
Ogni casa domotica funziona con lo stesso ciclo in tre parti. I sensori misurano l'ambiente: qualcuno si muove, è buio, quanti gradi ci sono, c'è gas o una fiamma in cucina, quale tessera è stata avvicinata alla porta? Il controllore, cioè l'Arduino o l'ESP32, confronta queste informazioni con delle regole: "se è buio e c'è movimento, accendi la luce", "se la temperatura supera i 28 °C, avvia la ventola". Gli attuatori eseguono la decisione: il relè accende la lampada e la ventola, il servo muove la porta e la finestra, il buzzer suona e il display mostra lo stato. Il controllo dallo smartphone aggiunge semplicemente un ingresso in più a questo ciclo; questa volta a decidere è il tuo dito invece di una regola.
| Stanza / zona | Modulo | Cosa fa |
|---|---|---|
| Porta d'ingresso | RFID RC522 + servo SG90 | Apre la porta quando legge una tessera autorizzata e la richiude dopo 5 secondi |
| Corridoio / soggiorno | PIR HC-SR501 + LDR + relè | Accende la lampada quando rileva un movimento al buio e la spegne dopo 20 secondi senza movimento |
| Cucina | Sensore di gas MQ-2 + sensore di fiamma + buzzer | Fa suonare un allarme intermittente se rileva gas o una fiamma |
| Finestra | Servo SG90 | Apre la finestra per arieggiare quando rileva gas |
| Camera da letto | DHT11 + relè + ventola | Avvia la ventola a 28 °C e la ferma a 26 °C |
| Locale tecnico | Arduino, display LCD I2C, alimentatore | Mostra temperatura, umidità, il valore del gas e i messaggi di stato |
Progettare il plastico
Progetta il plastico attorno all'elettronica; non cercare di infilarci l'elettronica alla fine. Una base di circa 50×40 cm basta per due o tre stanze e un ingresso. Per le pareti, il cartonpiuma (foam board) da 5 mm o il PVC espanso (tipo Forex) si tagliano facilmente con il taglierino; l'MDF da 3–4 mm è più robusto, ma richiede un seghetto o il taglio laser. La scala 1:20 è un buon punto di partenza: un soffitto di 2,6 m diventa una parete di 13 cm e una porta di 90 cm diventa larga 4,5 cm. Fai il tetto rimovibile oppure non metterlo; la commissione vorrà vedere l'interno delle stanze.
- Locale tecnico o doppio fondo: metti Arduino, breadboard, modulo relè e ingresso dell'alimentazione in un vano sul retro della casa o sotto un doppio fondo alto 3–4 cm. Se lo copri con plexiglas trasparente, il circuito è protetto e allo stesso tempo visibile.
- Passaggi per i cavi: pratica un foro da 6–8 mm sotto ogni sensore e fai passare i cavi sotto la base fino al locale tecnico. Invece di giuntare cavetti corti, scegli fin dall'inizio cavi abbastanza lunghi per i sensori.
- Porta: fissa la porta alla parete con una piccola cerniera o del nastro e collega la squadretta del SG90 alla porta con un filo ricavato da una graffetta piegata. Incolla l'RC522 sul lato interno della parete esterna; di solito il lettore legge la tessera anche attraverso un pannello da 5 mm.
- Cucina: nelle case vere, il rilevatore di metano va vicino al soffitto perché il metano è più leggero dell'aria, mentre quello di GPL va vicino al pavimento perché il GPL è più pesante; nel plastico basta una posizione vicina al soffitto. Orienta il sensore di fiamma verso i fornelli.
- Altri sensori: metti il PIR in un angolo che veda di lato il percorso d'ingresso, la LDR su una parete esterna o su una finestra dove non arrivi la luce della lampada e il DHT11 lontano dalla lampada e dal corpo caldo dell'MQ-2.
Lista dei materiali e costi
| Componente | Quantità | Funzione | Fascia di prezzo |
|---|---|---|---|
| Arduino Uno R3 (va bene un clone) o ESP32 DevKit | 1 | Il cervello della casa | Media |
| Breadboard e kit di cavetti jumper (maschio-maschio, maschio-femmina) | 1 kit | Collegamenti | Bassa |
| Sensore di movimento PIR HC-SR501 | 1 | Luce del corridoio | Bassa |
| Fotoresistenza LDR e resistenza da 10 kΩ | 1 + 1 | Rilevare il buio | Molto bassa |
| Modulo sensore di gas MQ-2 | 1 | Allarme gas e fumo | Bassa |
| Modulo sensore di fiamma (LM393) | 1 | Allarme incendio | Bassa |
| Modulo di temperatura e umidità DHT11 | 1 | Controllo della ventola | Bassa |
| Modulo RFID RC522 (con tessera e portachiavi) | 1 | Porta con tessera | Bassa |
| Servomotore SG90 | 2 | Porta e finestra | Bassa |
| Modulo a 2 relè da 5 V | 1 | Lampada e ventola | Bassa |
| Buzzer attivo | 1 | Suono dell'allarme | Molto bassa |
| Display LCD 16x2 I2C | 1 | Display di stato | Bassa – media |
| Mini ventola da 5 V e lampada LED da 5 V o striscia LED | 1 + 1 | Carichi dei relè | Bassa |
| Alimentatore 5 V 2–3 A con jack DC o morsetto | 1 | Alimentazione di servo, relè e sensori | Media |
| Cartonpiuma o PVC espanso, taglierino, colla a caldo | – | Struttura della casa | Media |
I prezzi cambiano spesso a seconda del venditore e nel tempo, quindi non indichiamo cifre; la tabella mostra il peso di ogni componente nel budget. Presi singolarmente, sensori e moduli costano poco; la parte maggiore del budget va nella scheda, nel display LCD, nell'alimentatore e nel materiale per il plastico. Se hai uno starter kit Arduino, hai già scheda, breadboard, cavetti, LDR, buzzer e spesso anche un servo e un display LCD. Con un budget ridotto puoi fare a meno del display e del secondo servo: usi il monitor seriale al posto del display e rimandi la finestra a una seconda fase. Un DHT22, più preciso del DHT11, costa un po' di più ma rende le tue misure più convincenti durante la presentazione.
Piano di alimentazione: perché un alimentatore da 5 V a parte?
Nei plastici di casa domotica, quasi tutti i problemi del tipo "ogni tanto si riavvia", "il servo trema" o "sul display compaiono caratteri strani" nascono dall'alimentazione. La porta USB di un computer fornisce circa 500 mA e, quando la scheda è alimentata via USB, anche il pin 5V dell'Uno dipende da questo limite. Sommando i valori qui sotto vedrai che la corrente totale supera facilmente 1 A quando i due servo si muovono insieme.
| Componente | Corrente indicativa a 5 V |
|---|---|
| Arduino Uno | 45–50 mA |
| MQ-2 (riscaldatore sempre acceso) | Circa 150 mA |
| Modulo relè (per canale, relè eccitato) | 70–80 mA |
| Servo SG90 (in movimento / sotto sforzo) | 100–250 mA / fino a 0,5–0,7 A |
| LCD I2C (retroilluminazione accesa) | 20–30 mA |
| RC522 (dal pin 3,3 V) | 13–26 mA |
| Buzzer attivo, DHT11, PIR e sensore di fiamma | 30–40 mA in tutto |
| Mini ventola da 5 V e lampada LED | 100–400 mA a seconda del modello |
Piano dei pin: Arduino Uno ed ESP32
Con così tanti moduli l'Uno resta quasi senza pin, quindi conviene pianificarli fin dall'inizio. L'RC522 usa l'SPI hardware, perciò le linee MOSI, MISO e SCK sono fisse su D11, D12 e D13. Il display usa solo A4 e A5 tramite I2C; per questo abbiamo scelto un LCD con modulo I2C invece di uno collegato in parallelo. Quando serve, i pin analogici funzionano anche come pin digitali, ed è così che possiamo collegare il servo della finestra ad A2. Lascia liberi D0 e D1: questa linea seriale serve per caricare il codice e per leggere i numeri delle tessere nel monitor seriale. Puoi vedere la piedinatura della tua scheda nello strumento Pinout.
| Pin del modulo | Arduino Uno | ESP32 |
|---|---|---|
| PIR OUT | D2 | GPIO 16 |
| Sensore di fiamma DO | D3 | GPIO 17 |
| DHT11 DATA | D4 | GPIO 13 |
| Buzzer attivo (+) | D5 | GPIO 25 |
| Servo della porta (segnale) | D6 | GPIO 32 |
| Relè IN1 (lampada) | D7 | GPIO 26 |
| Relè IN2 (ventola) | D8 | GPIO 27 |
| RC522 RST | D9 | GPIO 4 |
| RC522 SDA (SS) | D10 | GPIO 5 |
| RC522 MOSI / MISO / SCK | D11 / D12 / D13 | GPIO 23 / 19 / 18 |
| MQ-2 AO | A0 | GPIO 34 (con partitore di tensione) |
| Punto centrale del partitore della LDR | A1 | GPIO 35 (partitore alimentato da 3V3) |
| Servo della finestra (segnale) | A2 | GPIO 33 |
| LCD I2C SDA / SCL | A4 / A5 | GPIO 21 / 22 |
Montaggio passo passo
- Costruisci la struttura del plastico e prepara le posizioni dei moduli e i fori per i cavi; l'elettronica si monta per ultima.
- Prepara la linea di alimentazione: collega l'alimentatore da 5 V alle linee di alimentazione della breadboard, unisci il suo GND al GND di Arduino e controlla i 5 V con un multimetro.
- Collega il display LCD I2C e fai comparire un testo. Se non trovi l'indirizzo del display, usa lo sketch scanner dell'articolo sul display LCD I2C.
- Aggiungi i sensori uno alla volta: DHT11, LDR, PIR, MQ-2 e sensore di fiamma. Prova ciascuno con un breve sketch nel monitor seriale e annota i valori in aria pulita, al buio e alla luce.
- Aggiungi gli attuatori: prova prima i relè senza carico osservando lo scatto e il loro LED, poi i servo con l'alimentazione esterna e infine collega l'RC522. Avvicina le tue tessere e annota i loro numeri.
- Carica lo sketch principale e regola le soglie GAS_LIMIT, DARK_LIMIT e FAN_ON in base ai tuoi appunti.
- Fissa i cavi con la colla a caldo ed etichettali; lascia il sistema acceso per mezz'ora e controlla se ci sono riavvii, surriscaldamenti o falsi allarmi.
Luce automatica con PIR e LDR
Il sensore PIR HC-SR501 rileva le variazioni della radiazione infrarossa emessa dal corpo umano e porta la sua uscita a HIGH quando vede un movimento. Con il solo PIR la lampada si accenderebbe anche di giorno, quindi la nostra regola ha due condizioni: accendere se c'è movimento ed è buio. La LDR si collega come partitore di tensione con una resistenza da 10 kΩ (5V → LDR → A1 → 10 kΩ → GND) e il valore su A1 scende man mano che fa buio. Il codice memorizza il momento dell'ultimo movimento e spegne la lampada dopo 20 secondi senza nuovi movimenti; finché qualcuno cammina nella stanza, il tempo riparte ogni volta. Metti il jumper del sensore su H (attivazione ripetuta) e il trimmer Tx al minimo, e lascia che sia il codice a decidere la durata. Maggiori dettagli negli articoli sul sensore di movimento PIR e sul sensore di luce LDR.
Allarme gas e incendio
All'interno dell'MQ-2 c'è uno strato di biossido di stagno mantenuto caldo da un riscaldatore; GPL, metano, butano, idrogeno, alcol e fumo ne modificano la resistenza. Il pin AO del modulo fornisce una tensione che sale all'aumentare della concentrazione di gas. Il sensore deve scaldarsi ogni volta che viene acceso, per questo il codice ignora gli allarmi gas nei primi 60 secondi. Il sensore di fiamma rileva la luce infrarossa a 760–1100 nm emessa dal fuoco; nella maggior parte dei moduli l'uscita DO va a LOW e si accende un secondo LED sulla scheda quando vede una fiamma, ma verifica sempre il tuo modulo con un accendino tenuto a distanza di sicurezza. Se rileva gas, l'allarme suona e la finestra si apre per arieggiare; se rileva una fiamma, la finestra resta chiusa, perché l'aria fresca alimenta il fuoco. La regolazione della soglia e gli altri sensori MQ sono spiegati nell'articolo sul sensore di gas MQ-2.
Temperatura, umidità e ventola automatica
Il DHT11 misura la temperatura da 0 a 50 °C con una precisione di ±2 °C e l'umidità dal 20 al 90 % con ±5 %, e può essere letto al massimo una volta al secondo; il codice lo legge ogni due secondi. Per la ventola, invece di una sola soglia usiamo l'isteresi: parte a 28 °C ma si ferma solo quando la temperatura scende a 26 °C. Con una sola soglia il relè scatterebbe di continuo mentre la temperatura oscilla tra 27 e 28 °C, logorando sia sé stesso sia la ventola. Se il sensore sbaglia una lettura e restituisce "nan", il codice scarta quella misura e mantiene l'ultimo valore valido. Per misure più precise il DHT22 funziona con lo stesso codice: basta scrivere DHT22 al posto di DHT11. Maggiori dettagli nell'articolo sul sensore di temperatura e umidità DHT11.
Porta con tessera RFID e servo
L'RC522 legge tessere e portachiavi MIFARE a 13,56 MHz da 3–5 cm di distanza. Ogni tessera ha un proprio numero identificativo (UID) e il codice confronta l'UID letto con un elenco di tessere autorizzate. Se corrisponde, il servo apre la porta a 90 gradi, si sente un breve bip e il display mostra "Hos geldin!" ("Benvenuto!" in turco); dopo 5 secondi la porta si richiude da sola. Una tessera sconosciuta riceve un bip lungo. Per scoprire l'UID delle tue tessere, carica il codice, apri il monitor seriale a 9600 baud e avvicina una tessera: vedrai una riga come "UID: A1 B2 C3 D4". Scrivi questi byte nell'elenco CARDS nel formato 0xA1, aggiungendo uno zero davanti ai byte mostrati con una sola cifra (0x05 invece di 5). Una serratura che controlla solo l'UID va bene per imparare, ma non offre una vera sicurezza; spieghiamo perché nell'articolo sull'RFID RC522.
Finestra e tenda
Per la finestra basta un secondo SG90: colleghi una piccola finestra in plexiglas con cerniera alla squadretta del servo tramite un filo; 0 gradi vuol dire chiusa e 90 gradi aperta. Chiamare write(0) prima di attach() evita che il servo scatti a 90 gradi all'accensione sbattendo la finestra. Una tenda richiede una corsa più lunga: bisogna avvolgere il tessuto su un'asticella sottile e farla ruotare. Per questo un motore passo passo 28BYJ-48 con driver ULN2003 è silenzioso e preciso, ma richiede 4 pin; dato che sull'Uno non ne restano, conviene lasciare la tenda alla versione con ESP32 o a un Arduino Mega. Se deve bastare un solo pin, va bene anche un servo a rotazione continua FS90R, ma poiché non conosce la sua posizione apri e chiudi la tenda a tempo. Aggiungere un sensore di pioggia che chiude automaticamente la finestra quando piove è un'altra bella estensione.
Lampada e ventola con il relè

Un pin di Arduino può fornire in sicurezza solo circa 20 mA (il limite assoluto è 40 mA), mentre una ventola o una lampada ne chiedono molti di più. Per questo in mezzo si mette un modulo relè: il segnale sul pin IN eccita un elettromagnete che chiude i contatti di un circuito separato. Collega il carico ai morsetti COM e NO, così la lampada resta spenta mentre Arduino è spento o si sta riavviando. La maggior parte di questi moduli è attiva bassa, cioè il relè scatta quando scrivi LOW; a questo servono le costanti RELAY_ON e RELAY_OFF del codice. In setup() il codice scrive HIGH prima di impostare il pin come uscita, così il relè non scatta nemmeno per un istante all'avvio di Arduino. Abbiamo usato l'isteresi perché la ventola non si accenda e spenga troppo spesso, mentre la lampada resta accesa finché non scade il tempo del PIR.
Lo sketch completo (Arduino Uno)
La regola più importante nel codice di una casa domotica è che nessun modulo aspetti un altro. Se tenessi la porta aperta 5 secondi con delay(5000), in quel tempo l'allarme gas non funzionerebbe e il PIR non verrebbe letto. Per questo ogni modulo ha la sua funzione, e loop() chiama queste funzioni una dopo l'altra centinaia di volte al secondo. Tutto ciò che riguarda il tempo si misura con millis(), e lo stato di ogni modulo è conservato in variabili come lightOn, fanOn, doorOpen e alarmOn. Tutte le impostazioni stanno in cima al codice come costanti, quindi non devi frugare nel codice per cambiare una soglia. La logica di questo approccio è spiegata nell'articolo millis() o delay(). Per compilare il codice, installa dal gestore librerie MFRC522, la DHT sensor library di Adafruit e LiquidCrystal I2C di Frank de Brabander, e quando richiesto installa tutte le dipendenze. Servo, SPI e Wire sono già incluse nell'IDE di Arduino.
1#include <SPI.h>
2#include <MFRC522.h>
3#include <Servo.h>
4#include <DHT.h>
5#include <Wire.h>
6#include <LiquidCrystal_I2C.h>
7
8// Pinler / Pins
9const byte PIR_PIN = 2, FLAME_PIN = 3, DHT_PIN = 4, BUZZER_PIN = 5, DOOR_PIN = 6;
10const byte LAMP_RELAY = 7, FAN_RELAY = 8, RST_PIN = 9, SS_PIN = 10;
11const byte GAS_PIN = A0, LDR_PIN = A1, WINDOW_PIN = A2;
12
13// Ayarlar / Settings
14const byte RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
15const byte FLAME_ACTIVE = LOW; // alev görünce DO LOW olur / DO goes LOW on flame
16const int GAS_LIMIT = 400; // temiz havaya göre ayarla / tune in clean air
17const int DARK_LIMIT = 300; // bunun altı karanlık / below this is dark
18const float FAN_ON = 28.0, FAN_OFF = 26.0; // fan histerezisi (°C) / fan hysteresis (°C)
19const unsigned long LIGHT_MS = 20000; // son hareketten sonra ışık / light after last motion
20const unsigned long DOOR_MS = 5000; // kapı açık kalma süresi / door open time
21const unsigned long WARMUP_MS = 60000; // MQ-2 ve PIR ısınması / MQ-2 and PIR warm-up
22
23const byte CARDS[][4] = { // yetkili kart UID'leri / authorised card UIDs
24 {0xA1, 0xB2, 0xC3, 0xD4},
25 {0x12, 0x34, 0x56, 0x78}
26};
27
28MFRC522 rfid(SS_PIN, RST_PIN);
29Servo door, window;
30DHT dht(DHT_PIN, DHT11);
31LiquidCrystal_I2C lcd(0x27, 16, 2);
32
33float tempC = 0, hum = 0;
34int gas = 0;
35bool lightOn = false, fanOn = false, doorOpen = false, alarmOn = false;
36unsigned long lastMotion = 0, doorAt = 0, lastDht = 0, lastLcd = 0, beepUntil = 0;
37
38void setup() {
39 Serial.begin(9600);
40 digitalWrite(LAMP_RELAY, RELAY_OFF); pinMode(LAMP_RELAY, OUTPUT); // açılışta kapalı / off at boot
41 digitalWrite(FAN_RELAY, RELAY_OFF); pinMode(FAN_RELAY, OUTPUT);
42 pinMode(PIR_PIN, INPUT);
43 pinMode(FLAME_PIN, INPUT);
44 pinMode(BUZZER_PIN, OUTPUT);
45 door.write(0); door.attach(DOOR_PIN); // önce açı, sonra attach / angle first, then attach
46 window.write(0); window.attach(WINDOW_PIN);
47 dht.begin();
48 SPI.begin();
49 rfid.PCD_Init();
50 lcd.init();
51 lcd.backlight();
52 lcd.print(F("BlueGrays Ev"));
53}
54
55void loop() {
56 unsigned long now = millis();
57 handleLight(now);
58 handleClimate(now);
59 handleSafety(now);
60 handleDoor(now);
61 bool beep = (long)(beepUntil - now) > 0;
62 digitalWrite(BUZZER_PIN, beep || (alarmOn && (now / 250) % 2)); // alarmda kesik bip / pulsed beep on alarm
63 updateLcd(now);
64}
65
66// 1) Hareketle ışık / motion light
67void handleLight(unsigned long now) {
68 if (now < WARMUP_MS) return; // PIR ısınıyor / PIR warming up
69 if (digitalRead(PIR_PIN) == HIGH) {
70 lastMotion = now;
71 if (analogRead(LDR_PIN) < DARK_LIMIT) lightOn = true; // yalnız karanlıkta yak / only when dark
72 }
73 if (lightOn && now - lastMotion > LIGHT_MS) lightOn = false;
74 digitalWrite(LAMP_RELAY, lightOn ? RELAY_ON : RELAY_OFF);
75}
76
77// 2) Sıcaklık ve fan / temperature and fan
78void handleClimate(unsigned long now) {
79 if (now - lastDht < 2000) return; // DHT11'i sık okuma / don't read DHT11 too often
80 lastDht = now;
81 float t = dht.readTemperature();
82 float h = dht.readHumidity();
83 if (isnan(t) || isnan(h)) return; // okuma hatası / read error
84 tempC = t;
85 hum = h;
86 if (tempC >= FAN_ON) fanOn = true;
87 if (tempC <= FAN_OFF) fanOn = false;
88 digitalWrite(FAN_RELAY, fanOn ? RELAY_ON : RELAY_OFF);
89}
90
91// 3) Gaz ve yangın / gas and fire
92void handleSafety(unsigned long now) {
93 gas = analogRead(GAS_PIN);
94 bool gasAlarm = now > WARMUP_MS && gas > GAS_LIMIT;
95 bool fire = digitalRead(FLAME_PIN) == FLAME_ACTIVE;
96 alarmOn = gasAlarm || fire;
97 window.write(gasAlarm && !fire ? 90 : 0); // gazda aç, yangında kapalı tut / open on gas, shut on fire
98}
99
100// 4) RFID kapı / RFID door
101void handleDoor(unsigned long now) {
102 if (doorOpen && now - doorAt > DOOR_MS) {
103 door.write(0); // süre dolunca kapat / close when time is up
104 doorOpen = false;
105 }
106 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
107 Serial.print(F("UID:")); // yeni kartın UID'sini öğren / learn a new card's UID
108 for (byte i = 0; i < rfid.uid.size; i++) {
109 Serial.print(' ');
110 Serial.print(rfid.uid.uidByte[i], HEX);
111 }
112 Serial.println();
113 if (isAllowed(rfid.uid.uidByte)) {
114 door.write(90);
115 doorOpen = true;
116 doorAt = now;
117 beepUntil = now + 100; // kısa bip: hoş geldin / short beep: welcome
118 } else {
119 beepUntil = now + 800; // uzun bip: yetkisiz kart / long beep: unknown card
120 }
121 rfid.PICC_HaltA();
122}
123
124bool isAllowed(const byte *uid) {
125 for (byte i = 0; i < sizeof(CARDS) / 4; i++) {
126 if (memcmp(uid, CARDS[i], 4) == 0) return true;
127 }
128 return false;
129}
130
131// 5) Ekran / display
132void updateLcd(unsigned long now) {
133 if (now - lastLcd < 1000) return;
134 lastLcd = now;
135 lcd.setCursor(0, 0);
136 lcd.print(F("T:"));
137 lcd.print(tempC, 0);
138 lcd.print(F("C Nem:%"));
139 lcd.print(hum, 0);
140 lcd.print(F(" "));
141 lcd.setCursor(0, 1);
142 if (alarmOn) {
143 lcd.print(F("!! ALARM !! "));
144 } else if (doorOpen) {
145 lcd.print(F("Hos geldin! "));
146 } else {
147 lcd.print(F("Gaz:"));
148 lcd.print(gas);
149 lcd.print(F(" "));
150 }
151}| Funzione | Compito | Ogni quanto? |
|---|---|---|
| handleLight() | Accende il relè della lampada in base a PIR e LDR e lo spegne dopo 20 secondi senza movimento | A ogni ciclo (esclusi i primi 60 secondi) |
| handleClimate() | Legge il DHT11 e comanda la ventola con isteresi 28/26 °C | Ogni 2 secondi |
| handleSafety() | Legge l'MQ-2 e il sensore di fiamma, gestisce l'allarme e la finestra | A ogni ciclo |
| handleDoor() | Legge la tessera, scrive l'UID nel monitor seriale, apre e chiude la porta | A ogni ciclo |
| updateLcd() | Mostra temperatura, umidità, il valore del gas o un messaggio di stato | Una volta al secondo |
| Riga del buzzer dentro loop() | Produce il bip della tessera e il suono intermittente dell'allarme | A ogni ciclo |
Una volta compilato, questo codice occupa circa il 38 % della memoria di programma dell'Uno e il 28 % della sua RAM; c'è quindi ancora memoria libera, ma tra i pin resta libero solo A3. Ad A3 puoi collegare un pulsante o un sensore di pioggia; per aggiungere altro dovrai passare a un Arduino Mega o a un ESP32. Scrivere i testi fissi dentro F() è il modo più semplice per tenere basso l'uso della RAM.
Controllo dallo smartphone: web server sull'ESP32

L'Uno non ha il Wi-Fi; il modo più semplice per controllare la casa dallo smartphone è sostituire il cervello con un ESP32. Il codice qui sotto collega l'ESP32 alla rete di casa e avvia un piccolo web server. Con lo smartphone sulla stessa rete Wi-Fi, apri nel browser l'indirizzo IP mostrato nel monitor seriale e vedrai quattro grandi pulsanti per lampada, ventola, porta e finestra, oltre a temperatura, umidità e valore del gas attuali; la pagina si ricarica da sola ogni 10 secondi. Ogni pulsante invia all'ESP32 una breve richiesta che indica quale dispositivo commutare; l'ESP32 cambia lo stato e ti riporta alla pagina principale. Per i servo installa dal gestore librerie la libreria ESP32Servo, perché la libreria Servo standard non funziona sull'ESP32.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <ESP32Servo.h>
4#include <DHT.h>
5
6const char* ssid = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
7const char* password = "Sifre123"; // Wi-Fi şifren / your Wi-Fi password
8
9const int LAMP_RELAY = 26, FAN_RELAY = 27;
10const int DOOR_PIN = 32, WINDOW_PIN = 33;
11const int DHT_PIN = 13, GAS_PIN = 34; // GPIO 34: ADC1, bölücüyle / ADC1, through a divider
12const int RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
13
14WebServer server(80);
15Servo door, window;
16DHT dht(DHT_PIN, DHT11);
17
18bool lamp = false, fan = false, doorOpen = false, windowOpen = false;
19float tempC = NAN, hum = NAN;
20unsigned long lastDht = 0;
21
22void apply() { // durumu donanıma uygula / push the state to the hardware
23 digitalWrite(LAMP_RELAY, lamp ? RELAY_ON : RELAY_OFF);
24 digitalWrite(FAN_RELAY, fan ? RELAY_ON : RELAY_OFF);
25 door.write(doorOpen ? 90 : 0);
26 window.write(windowOpen ? 90 : 0);
27}
28
29String button(const char* id, const char* label, bool on) {
30 return String("<a class='b ") + (on ? "on" : "off") + "' href='/set?d=" + id +
31 "&v=" + (on ? "0" : "1") + "'>" + label + (on ? ": ON" : ": OFF") + "</a>";
32}
33
34void handleRoot() {
35 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
36 "<meta name='viewport' content='width=device-width,initial-scale=1'>"
37 "<meta http-equiv='refresh' content='10'><title>BlueGrays Ev</title>"
38 "<style>body{font-family:sans-serif;text-align:center}"
39 ".b{display:block;margin:12px auto;padding:18px;max-width:320px;border-radius:10px;"
40 "color:#fff;text-decoration:none;font-size:20px}"
41 ".on{background:#2e7d32}.off{background:#607d8b}</style></head><body>"
42 "<h2>BlueGrays Akıllı Ev</h2>";
43 html += "<p>" + String(tempC, 1) + " °C | %" + String(hum, 0) +
44 " | Gaz/Gas: " + String(analogRead(GAS_PIN)) + "</p>";
45 html += button("lamp", "Lamba / Lamp", lamp);
46 html += button("fan", "Fan", fan);
47 html += button("door", "Kapı / Door", doorOpen);
48 html += button("window", "Pencere / Window", windowOpen);
49 html += "</body></html>";
50 server.send(200, "text/html", html);
51}
52
53void handleSet() { // /set?d=lamp&v=1
54 String d = server.arg("d");
55 bool v = server.arg("v") == "1";
56 if (d == "lamp") lamp = v;
57 else if (d == "fan") fan = v;
58 else if (d == "door") doorOpen = v;
59 else if (d == "window") windowOpen = v;
60 apply();
61 server.sendHeader("Location", "/"); // ana sayfaya dön / back to the main page
62 server.send(303);
63}
64
65void setup() {
66 Serial.begin(115200);
67 door.attach(DOOR_PIN, 500, 2400);
68 window.attach(WINDOW_PIN, 500, 2400);
69 pinMode(LAMP_RELAY, OUTPUT);
70 pinMode(FAN_RELAY, OUTPUT);
71 apply(); // her şey kapalı başlar / everything starts off
72 dht.begin();
73 WiFi.begin(ssid, password);
74 while (WiFi.status() != WL_CONNECTED) {
75 delay(500);
76 Serial.print('.');
77 }
78 Serial.println();
79 Serial.println(WiFi.localIP()); // bu adresi telefonda aç / open this address on your phone
80 server.on("/", handleRoot);
81 server.on("/set", handleSet);
82 server.begin();
83}
84
85void loop() {
86 server.handleClient();
87 if (millis() - lastDht > 2000) { // 2 sn'de bir ölç / measure every 2 s
88 lastDht = millis();
89 float t = dht.readTemperature();
90 float h = dht.readHumidity();
91 if (!isnan(t) && !isnan(h)) {
92 tempC = t;
93 hum = h;
94 }
95 }
96}Questo codice contiene solo le parti controllate a distanza. Puoi però portare qui anche le funzioni handleLight(), handleSafety() e handleDoor() dello sketch dell'Uno: cambia i numeri dei pin secondo la colonna ESP32 della tabella, usa ESP32Servo al posto di Servo e misura di nuovo le soglie GAS_LIMIT e DARK_LIMIT, perché l'ADC dell'ESP32 restituisce valori da 0 a 4095. La pagina non ha password, quindi chiunque sulla tua rete potrebbe aprire la porta; aggiungere una password semplice con la funzione authenticate() della libreria WebServer è una buona abitudine. Per un pannello che si aggiorna in tempo reale, leggi l'articolo su ESP32 e WebSocket.
Controllo da ovunque con Blynk
Il web server dell'ESP32 è raggiungibile solo dalla stessa rete. Se vuoi controllare la casa anche da fuori con i dati mobili, una piattaforma cloud come Blynk IoT ti semplifica la vita: costruisci l'interfaccia con il trascinamento nell'app dello smartphone e l'ESP32 si collega al server di Blynk. Crea un modello (template) su Blynk.Cloud, aggiungi tre datastream chiamati V0 (intero, 0–1, lampada), V1 (decimale, temperatura) e V2 (decimale, umidità), crea un dispositivo e incolla in cima al codice i valori Template ID, Template Name e Auth Token che ti vengono forniti. Nell'app basta collegare uno Switch a V0 e un Gauge ciascuno a V1 e V2. Il piano gratuito limita il numero di dispositivi, di datastream e di messaggi al mese, per questo inviamo i dati dei sensori ogni cinque secondi invece che ogni secondo. La configurazione completa è nella guida Blynk IoT con ESP32.
1#define BLYNK_TEMPLATE_ID "TMPLxxxxxxx" // Blynk konsolundan kopyala / copy from the Blynk console
2#define BLYNK_TEMPLATE_NAME "Akilli Ev"
3#define BLYNK_AUTH_TOKEN "TokenBuraya"
4
5#include <WiFi.h>
6#include <BlynkSimpleEsp32.h>
7#include <DHT.h>
8
9const int LAMP_RELAY = 26; // aktif LOW röle / active-LOW relay
10DHT dht(13, DHT11);
11BlynkTimer timer;
12
13BLYNK_WRITE(V0) { // uygulamadaki anahtar / switch widget in the app
14 digitalWrite(LAMP_RELAY, param.asInt() ? LOW : HIGH);
15}
16
17BLYNK_CONNECTED() {
18 Blynk.syncVirtual(V0); // bağlanınca son durumu al / restore the last state
19}
20
21void sendSensors() {
22 float t = dht.readTemperature();
23 float h = dht.readHumidity();
24 if (isnan(t) || isnan(h)) return;
25 Blynk.virtualWrite(V1, t); // sıcaklık / temperature
26 Blynk.virtualWrite(V2, h); // nem / humidity
27}
28
29void setup() {
30 pinMode(LAMP_RELAY, OUTPUT);
31 digitalWrite(LAMP_RELAY, HIGH); // açılışta kapalı / off at boot
32 dht.begin();
33 Blynk.begin(BLYNK_AUTH_TOKEN, "AgAdi", "Sifre123");
34 timer.setInterval(5000L, sendSensors); // 5 sn'de bir: mesaj kotasını korur / every 5 s saves quota
35}
36
37void loop() {
38 Blynk.run();
39 timer.run();
40}Quale metodo di controllo scegliere?
| Metodo | Cosa serve | Da fuori casa | Difficoltà | Ideale per |
|---|---|---|---|---|
| Web server sull'ESP32 | ESP32 e Wi-Fi di casa | No, solo dalla stessa rete | Media | Presentazioni scolastiche, dimostrazioni senza internet, codice tutto tuo |
| Blynk IoT | ESP32, internet e un account Blynk | Sì | Facile | Interfaccia pronta, grafici e notifiche |
| Bluetooth (HC-05) | Uno, HC-05 e un'app Android | No, circa 10 m | Facile | Chi vuole restare sull'Uno (non funziona con iPhone) |
| Bot di Telegram | ESP32 e internet | Sì | Media | Notifiche di allarme e comandi brevi |
| MQTT + Home Assistant | ESP32 e un server locale (es. Raspberry Pi) | Sì, con configurazione | Avanzata | Domotica vera |
Per una presentazione a scuola, il web server sull'ESP32 è la scelta più sicura: non dipende da internet né dal cloud e funziona con la sua rete anche se in aula non c'è Wi-Fi. Se vuoi restare sull'Uno e aggiungere solo il Bluetooth, puoi creare la tua app Android con App Inventor; ma poiché sull'Uno non restano pin, per fare spazio all'HC-05 dovrai rinunciare al display o al servo della finestra. Ricevere un messaggio sullo smartphone quando scatta l'allarme è possibile con un bot Telegram con ESP32, mentre per collegare la casa a dispositivi veri c'è MQTT con Home Assistant.
Casa domotica con Raspberry Pi Pico
Puoi realizzare lo stesso sistema anche in MicroPython con un Raspberry Pi Pico, e il Pico W, dotato di Wi-Fi, si controlla dallo smartphone proprio come l'ESP32 (vedi il web server con Pico W). Dato che il Pico funziona a 3,3 V, valgono anche qui le regole dell'ESP32: alimenta il partitore della LDR da 3V3, riduci con un partitore le uscite analogiche a 5 V e scegli un modulo relè comandabile a 3,3 V. Gli unici ingressi analogici sono GP26, GP27 e GP28. Il codice qui sotto è la versione MicroPython del modulo luce con sensore di movimento:
1from machine import Pin, ADC
2import time
3
4pir = Pin(15, Pin.IN) # PIR OUT (3,3 V çıkış / 3.3 V output)
5ldr = ADC(26) # GP26: bölücü 3V3'ten / divider fed from 3V3
6relay = Pin(14, Pin.OUT, value=1) # aktif LOW röle, kapalı başla / active-LOW relay, start off
7
8LIGHT_MS = 20000 # son hareketten sonra ışık / light after last motion
9DARK = 20000 # bunun altı karanlık / below this is dark
10last = time.ticks_ms()
11on = False
12
13while True:
14 now = time.ticks_ms()
15 if pir.value():
16 last = now
17 if ldr.read_u16() < DARK: # yalnız karanlıkta yak / only when dark
18 on = True
19 if on and time.ticks_diff(now, last) > LIGHT_MS:
20 on = False
21 relay.value(0 if on else 1)
22 time.sleep_ms(50)Consigli per la presentazione a scuola
- Parti da un problema: descrivi in una frase un problema reale, come "luci accese in una casa vuota, una fuga di gas che nessuno nota, anziani che perdono le chiavi", poi mostra come il tuo plastico risponde.
- Prepara uno schema a blocchi: sensori a sinistra, Arduino al centro e attuatori a destra; etichetta le frecce con le regole ("buio + movimento → lampada"). La commissione non leggerà il tuo codice, ma si ricorderà di questo schema.
- Prepara una dimostrazione dal vivo: avvicina la tessera e mostra la porta che si apre, muovi la mano davanti al PIR, avvicina all'MQ-2 un batuffolo di cotone con alcol (anche l'alcol attiva il sensore) e scalda il DHT11 con le dita. Ogni dimostrazione dovrebbe durare 10–20 secondi.
- Niente fiamme libere: non accendere accendini o candele dentro un plastico di cartone. La maggior parte dei sensori di fiamma reagisce anche alla luce infrarossa di un telecomando della TV tenuto vicino; provalo prima e usalo durante la dimostrazione.
- Adatta le soglie all'aula: se il giorno della presentazione in aula ci sono 22 °C, aspettare i 28 °C rovinerà la dimostrazione della ventola; imposta FAN_ON 2–3 gradi sopra la temperatura ambiente, così la ventola parte quando scaldi il sensore con le dita.
- Misura e porta numeri: per esempio, registra per un giorno quanti minuti la lampada resta accesa con e senza PIR e indica il risparmio in percentuale. Un risultato con dei numeri convince molto più di un "funziona".
- Prepara un piano B: registra un video del sistema in funzione, porta cavi, un servo e un alimentatore di scorta e scrivi su un foglio i numeri delle tessere e i dati del Wi-Fi.
- Preparati alle domande della commissione: per "Come funzionerebbe in una casa vera?" tieni pronte risposte brevi sulla sicurezza della tensione di rete, sui rilevatori certificati, sulla sicurezza dell'RFID e su cosa fa la porta se manca la corrente.
Errori comuni e come risolverli
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| Arduino si riavvia o il display impazzisce quando un servo si muove | Servo e relè sono alimentati dal pin 5V di Arduino | Alimentatore separato da 5 V 2–3 A, massa comune, condensatore da 470–1000 µF sull'alimentazione dei servo |
| Il relè funziona al contrario ed è eccitato all'accensione | Il modulo è attivo basso | Scambia i valori di RELAY_ON e RELAY_OFF |
| L'allarme scatta a ogni accensione | L'MQ-2 si sta scaldando e il PIR sta imparando l'ambiente | Mantieni l'attesa WARMUP_MS; lascia l'MQ-2 acceso a lungo prima del primo utilizzo |
| La lampada si accende di giorno o si spegne e si riaccende subito | DARK_LIMIT sbagliato o la LDR vede la luce della lampada | Regola la soglia in base ai valori del monitor seriale e sposta la LDR su una parete esterna |
| Le tessere non vengono lette | Cablaggio dell'RC522 errato o modulo collegato a 5 V | Controlla i pin SPI e prova il modulo con l'esempio DumpInfo |
| Il DHT11 restituisce nan | Cavo DATA sul pin sbagliato o manca la resistenza di pull-up sul sensore nudo | Controlla il pin, usa un modulo o metti 10 kΩ tra DATA e VCC |
| Il servo ogni tanto trema | Alimentazione debole; durante la lettura del DHT11 gli interrupt si fermano per un attimo | Potenzia l'alimentazione; se serve, scollega il servo con detach() a movimento finito |
| Sull'ESP32 il valore del gas è sempre 0 o 4095 | Un pin ADC2 va in conflitto con il Wi-Fi o manca il partitore | Usa un pin ADC1 come GPIO 34 o 35 e un partitore di tensione |
| Lo smartphone non apre la pagina dell'ESP32 | Lo smartphone è sulla rete ospiti o con i dati mobili, oppure la rete è a 5 GHz | Collegati alla stessa rete a 2,4 GHz e prendi l'indirizzo IP dal monitor seriale |
Un progetto di casa domotica con Arduino riunisce in un solo montaggio la lettura dei sensori, le decisioni, il comando di motori e relè, la pianificazione dell'alimentazione e il controllo senza fili; per questo è un argomento ottimo sia per imparare sia per presentare. Parti da un modulo, collauda ogni passaggio e fai crescere il sistema un po' alla volta. Nell'app BlueGrays trovi passo passo, con schemi e codice, i progetti di illuminazione intelligente delle scale, illuminazione intelligente con PIR e LDR, allarme fiamma e gas, serratura RFID per la porta e web server con ESP32.
Domande frequenti
Cosa serve per un progetto di casa domotica con Arduino?
Per un plastico di base bastano un Arduino Uno o un ESP32, un sensore di movimento PIR, una LDR, un sensore di gas MQ-2, un sensore di fiamma, un DHT11, un modulo RFID RC522, due servo SG90, un modulo a 2 relè, un buzzer e un display LCD I2C. A questi si aggiungono breadboard, cavetti jumper, un alimentatore da 5 V 2–3 A e il materiale per il plastico. La maggior parte dei moduli costa poco; scheda, display, alimentatore e plastico assorbono gran parte del budget.
Per una casa domotica è meglio Arduino o ESP32?
Se non ti serve il controllo dallo smartphone, l'Arduino Uno è più semplice: funziona direttamente con i moduli a 5 V e la maggior parte degli esempi è scritta per lui. Scegli l'ESP32 se ti servono il controllo via Wi-Fi dallo smartphone, le notifiche o più pin; dato che i suoi pin lavorano a 3,3 V, però, dovrai fare più attenzione con i moduli relè e i sensori analogici a 5 V.
Come controllo una casa domotica Arduino dallo smartphone?
Il modo più semplice è usare un ESP32 con un web server: così comandi lampada, ventola e porta con dei pulsanti dal browser di uno smartphone collegato allo stesso Wi-Fi. Per l'accesso da fuori casa puoi usare un'app cloud come Blynk IoT e, se vuoi restare sull'Arduino Uno, un modulo Bluetooth HC-05 con un'app Android.
Con che materiale si fa il plastico di una casa domotica?
Il materiale più pratico è il cartonpiuma o il PVC espanso da 5 mm: si taglia con il taglierino e si incolla con la colla a caldo. Per una struttura più robusta puoi usare MDF da 3–4 mm. Una base di circa 50×40 cm, un tetto rimovibile e un vano tecnico separato per l'elettronica semplificano molto il lavoro.
Arduino può accendere una lampada a 230 V?
Sì, con un modulo relè da 5 V, che separa elettricamente il circuito di rete da Arduino. Ma la tensione di rete può uccidere: fai i collegamenti con la spina staccata, metti il circuito in una scatola chiusa e isolante e, in un progetto di studenti, non lavorarci mai senza la supervisione di un adulto. Per un plastico bastano lampade da 5 V o 12 V.
Una casa domotica con Arduino va bene per la maturità o una fiera della scienza?
La casa domotica è un argomento molto diffuso, quindi un plastico funzionante spesso non basta da solo. Se colleghi il progetto a una domanda di ricerca misurabile, per esempio quanta energia fa risparmiare l'illuminazione con sensore di movimento o quanto velocemente reagisce l'allarme gas, risulterà molto più solido agli occhi della commissione.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Temperatura e umidità con DHT11
Quanti gradi ci sono nella tua stanza, e l'aria è umida o secca? Il sensore DHT11 misura temperatura e umidità, e l'Arduino scrive i valori su uno schermo LCD a due righe, aggiornandoli ogni paio di s

Illuminazione intelligente di scale e corridoi
Metti piede sulle scale o nel corridoio e le luci si accendono gradino dopo gradino nella direzione in cui cammini. A ogni estremità c'è un sensore di distanza; davanti a qualunque dei due passi, gli

Illuminazione Intelligente ESP32 (PIR + LDR + Relè + OLED)
Trasforma il tuo corridoio, bagno o dispensa in illuminazione intelligente con ESP32! Utilizzando un sensore di movimento PIR, un sensore di luce LDR e un modulo relè, costruiamo lo scenario classico "la luce si accende quando viene rilevato movimento al buio" — se l'ambiente è già luminoso, il movimento NON attiva la luce, risparmiando energia durante il giorno. La luce rimane accesa per 30 secondi; se il movimento continua, il timer si azzera e la luce rimane accesa più a lungo. Il display OLE

Campanello e luce con sensore di movimento
Quando qualcuno si avvicina alla tua porta, lo sai prima ancora che suoni. Appena il sensore di movimento rileva qualcuno, il LED si accende e il buzzer suona un campanello di tre note, dalla più acut

Allarme del sensore di fiamma e gas
Un piccolo guardiano che ti avvisa subito se c'è una fuga di gas o compare una fiamma da qualche parte. Il sensore di gas controlla l'aria e il sensore di fiamma cerca la luce del fuoco; finché va tut

Serratura RFID ESP32 (RC522 + servomotore + OLED + cicalino + LED)
Realizziamo una serratura intelligente utilizzando un modulo RFID RC522 con ESP32, un servomotore SG90, un display OLED SSD1306, un cicalino attivo e 2 LED. Quando viene letta una tessera, il codice UID viene confrontato con l’elenco delle tessere autorizzate definito nel sistema: se autorizzata, il servomotore ruota sbloccando la serratura (LED verde + 2 brevi bip); dopo 5 secondi, la serratura si blocca automaticamente. In caso di tessera non autorizzata, si accende il LED rosso, viene emesso

Accendere una lampadina 220V con il telecomando
Accendi e spegni una vera lampadina di casa con un telecomando, senza alzarti dal divano. L'Arduino legge il segnale di luce invisibile del telecomando; il tasto di accensione fa scattare il relè e ac

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).
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 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

