Sensore pioggia Arduino: schema, codice e finestra automatica
Sensore pioggia con Arduino: collegamento FC-37/YL-83, uscite AO e DO, soglia, evitare la corrosione, allarme pioggia, finestra con servo, codice ESP32 e Pico.
Un sensore pioggia permette ad Arduino di rilevare le gocce d'acqua e di segnalare "ha iniziato a piovere" in pochi millisecondi: è uno dei sensori più economici e divertenti in assoluto. È formato da una piastra sensibile su cui cade l'acqua e da una piccola scheda di controllo con un comparatore LM393, e si collega ad Arduino con soli quattro fili. Un promemoria per ritirare il bucato prima che si bagni, una finestra o una tenda da sole che si chiude da sola quando piove, un impianto di irrigazione che salta i giorni di pioggia e una piccola stazione meteo partono tutti da questo modulo.
In questa guida scoprirai cosa c'è dentro il modulo sensore pioggia venduto come FC-37, YL-83 o MH-RD, la differenza tra l'uscita analogica (AO) e quella digitale (DO), come regolare la soglia con il trimmer e l'argomento più trascurato di tutti: come evitare che la piastra si corroda. Poi costruiremo passo passo un allarme pioggia a livelli di intensità con Arduino, una chiusura automatica della finestra con un servomotore, le notifiche sul telefono con l'ESP32 e un esempio in MicroPython per il Raspberry Pi Pico.

Che cos'è un sensore pioggia e come funziona?
Sulla piastra sensibile ci sono due piste conduttive intrecciate come i denti di due pettini, che però non si toccano mai. Quando la piastra è asciutta, la resistenza tra le piste è nell'ordine dei megaohm, quindi il circuito è praticamente aperto. Quando una goccia cade a cavallo di due piste, l'acqua crea un ponte tra loro e la resistenza scende. Più gocce cadono e più superficie si bagna, più la resistenza diminuisce. Sulla scheda di controllo la piastra forma un partitore di tensione insieme a una resistenza, da 10 kΩ nella maggior parte dei modelli: con la piastra asciutta la tensione sul pin AO è vicina all'alimentazione (VCC) e cala man mano che la piastra si bagna. Puoi provare tu stesso come cambia l'uscita con resistenze diverse usando il calcolatore del partitore di tensione.
L'LM393 sulla scheda è un integrato comparatore che confronta due tensioni. A un ingresso arriva la tensione della piastra, all'altro una tensione di riferimento che regoli con il trimmer. Nel momento in cui la tensione della piastra scende sotto il riferimento, cioè quando viene rilevata abbastanza acqua, l'uscita DO passa a LOW e il LED DO sulla scheda si accende. L'LM393 ha un'uscita a collettore aperto; grazie a una resistenza di pull-up sulla scheda, DO resta HIGH quando non piove. L'altro LED (PWR) indica soltanto che il modulo è alimentato.
| Caratteristica | Valore |
|---|---|
| Piastra sensibile | Circa 5,4 × 4 cm; piste intrecciate su FR4, nichelate nella maggior parte dei modelli |
| Scheda di controllo | Circa 3 × 1,5 cm, comparatore LM393 |
| Tensione di alimentazione | 3,3–5 V |
| Assorbimento | Circa 8 mA (a 5 V con entrambi i LED accesi) |
| Uscita analogica (AO) | Tra 0 V e VCC; scende quando la piastra si bagna |
| Uscita digitale (DO) | HIGH da asciutto, LOW una volta superata la soglia |
| Indicatori | LED PWR (alimentazione) e LED DO (pioggia rilevata) |
| Regolazione | Trimmer della sensibilità (cambia solo la soglia di DO) |
| Collegamenti | 2 pin lato piastra (senza polarità), 4 pin lato Arduino: VCC, GND, DO, AO |
FC-37, YL-83 e MH-RD: ci sono differenze?
In breve, no. FC-37, YL-83 e MH-RD sono i nomi che produttori diversi danno allo stesso circuito; tutti hanno una piastra sensibile e una scheda di controllo con LM393 e funzionano con lo stesso codice. Le differenze riguardano di solito le dimensioni della piastra, piccole variazioni nel disegno delle piste e la qualità del rivestimento. La scheda di controllo è quasi identica a quella del sensore di umidità del terreno, quindi le schede dei due moduli sono intercambiabili. I due pin tra piastra e scheda non hanno positivo né negativo, perciò non importa in che verso colleghi il cavo. Quando la piastra si consuma col tempo, basta sostituire solo la piastra.
Uscita analogica (AO) e digitale (DO): le differenze
Quale uscita usare dipende dal tuo progetto. DO dice solo "piove" o "non piove"; la soglia si imposta con il trimmer sulla scheda e su Arduino basta un digitalRead(). AO, invece, fornisce un numero da 0 a 1023 che indica quanto è bagnata la piastra: così puoi distinguere una pioggerella da un acquazzone, cambiare la soglia nel codice e decidere quando la pioggia inizia o finisce guardando letture consecutive. Puoi anche usare entrambe le uscite contemporaneamente.
| Caratteristica | DO (digitale) | AO (analogica) |
|---|---|---|
| Cosa indica | Piove / non piove | Quanto è bagnata la piastra (0–1023 sull'Uno) |
| Regolazione della soglia | Trimmer sulla scheda | Nel codice, come preferisci |
| Pin di Arduino | Qualsiasi pin digitale | Pin analogico (A0–A5) |
| Distingue l'intensità | No | Sì (pioggerella, pioggia, acquazzone) |
| Uso con gli interrupt | Sì | No |
| Ideale per | Allarmi semplici, segnale di risveglio | Misura dei livelli, automazione con isteresi |
Collegamento del sensore pioggia: Arduino Uno, ESP32 e Pico
| Pin del modulo / componente | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | D7 (per alimentarlo solo durante la misura) o 5V | GPIO 25 o 3V3 | GP15 o 3V3(OUT) |
| GND | GND | GND | GND |
| AO | A0 | GPIO 34 (ADC1) | GP26 (ADC0) |
| DO | D2 | Facoltativo (es. GPIO 27) | GP14 |
| Buzzer attivo (+) | D8 | Facoltativo | GP13 |
| Filo di segnale del servo | D9 | Facoltativo | GP16 |
Avrai notato che nella tabella VCC va a un pin digitale invece che al 5V. Il modulo assorbe solo circa 8 mA a 5 V, quindi un pin di Arduino lo alimenta senza problemi (il limite consigliato è di 20 mA per pin). In questo modo accendi il modulo solo per i pochi millisecondi della misura e lo tieni spento per il resto del tempo. Vedremo perché è così importante nella sezione sulla corrosione. I pin del Pico sono impostati di default su una corrente di uscita di 4 mA; dato che il modulo a 3,3 V assorbe pochi mA, di solito basta, ma se le letture sono instabili puoi alimentarlo dal pin 3V3(OUT).
Regolare la sensibilità: impostare la soglia con il trimmer
- Asciuga bene la piastra e alimenta il modulo; il LED PWR deve essere acceso e il LED DO spento.
- Gira lentamente il trimmer con un piccolo cacciavite finché il LED DO non si accende. Se con la piastra asciutta è già acceso, gira nell'altro verso.
- Torna esattamente al punto in cui il LED si spegne. È la regolazione più sensibile con cui DO resta HIGH a piastra asciutta.
- Gira ancora un po' nello stesso verso per lasciare un margine di sicurezza; altrimenti anche l'aria umida o la rugiada possono far scattare l'allarme.
- Lascia cadere due o tre gocce d'acqua sulla piastra con il dito. Il LED DO deve accendersi; se non si accende, aumenta un po' la sensibilità.
- Asciuga la piastra e osserva quanto tempo impiega il LED a spegnersi: ti dà un'idea di quanto il tuo sistema dovrebbe aspettare prima di decidere che "ha smesso di piovere".
Passo passo: la prima lettura con Arduino
- Collega VCC del modulo a D7, GND a GND, AO ad A0 e DO a D2. Collega la piastra alla scheda con il cavo a due fili.
- Apri il codice qui sotto nell'Arduino IDE, scegli Arduino Uno come scheda e caricalo.
- Apri il Monitor seriale a 9600 baud e annota il valore di AO con la piastra asciutta.
- Fai cadere sulla piastra prima qualche goccia d'acqua, poi di più, e annota ogni volta il valore di AO.
- Annota anche il valore con la piastra completamente bagnata: questi valori diventeranno le costanti DRY e WET degli sketch successivi.
1// Yağmur sensörü: AO ve DO okuma / Rain sensor: reading AO and DO
2const int SENSOR_POWER = 7; // modülün VCC'si bu pinden beslenir / module VCC is fed from this pin
3const int RAIN_AO = A0; // analog çıkış / analog output
4const int RAIN_DO = 2; // dijital çıkış / digital output
5
6void setup() {
7 Serial.begin(9600);
8 pinMode(SENSOR_POWER, OUTPUT);
9 digitalWrite(SENSOR_POWER, LOW); // başlangıçta kapalı / off at start-up
10 pinMode(RAIN_DO, INPUT);
11}
12
13void loop() {
14 digitalWrite(SENSOR_POWER, HIGH); // modülü aç / power the module
15 delay(50); // değerin oturmasını bekle / let the reading settle
16 int analogValue = analogRead(RAIN_AO); // 0-1023: kuruyken yüksek / high when dry
17 bool raining = digitalRead(RAIN_DO) == LOW; // yağmurda DO = LOW / DO goes LOW in rain
18 digitalWrite(SENSOR_POWER, LOW); // modülü kapat / power it off
19
20 Serial.print(F("AO: "));
21 Serial.print(analogValue);
22 Serial.print(F(" DO: "));
23 Serial.println(raining ? F("YAGMUR / RAIN") : F("KURU / DRY"));
24 delay(2000); // 2 sn'de bir ölç / measure every 2 s
25}Prima di ogni misura il codice porta D7 a HIGH per accendere il modulo, attende 50 ms che i condensatori della scheda si carichino e che il valore si stabilizzi, legge AO e DO e spegne subito il modulo. Così il modulo resta alimentato solo 50 ms per ogni ciclo di 2 secondi, cioè il 2,5% del tempo. Dato che con la pioggia DO va a LOW, abbiamo scritto la condizione come digitalRead(RAIN_DO) == LOW. Le parole turche nei messaggi stampati sono scritte senza caratteri speciali perché alcuni terminali li visualizzano male.
| Stato della piastra | AO indicativo (Uno, 5 V) | DO (scheda regolata) |
|---|---|---|
| Asciutta e pulita | 1000–1023 | HIGH |
| Qualche goccia | 750–950 | HIGH o LOW a seconda della regolazione |
| Pioggerella, piastra bagnata in parte | 500–750 | LOW |
| Pioggia intensa | 300–500 | LOW |
| Completamente bagnata, acqua del rubinetto | 150–350 | LOW |
Questi numeri sono solo indicativi: le dimensioni della piastra, lo stato del rivestimento, la purezza dell'acqua e la polvere li cambiano in modo evidente. Persino i valori dello stesso modulo si spostano dopo qualche mese all'aperto. Per questo negli sketch successivi non usiamo direttamente il valore grezzo, ma lo convertiamo in una percentuale di bagnato da 0 a 100 usando i valori asciutto (DRY) e bagnato (WET) che hai misurato tu; così ti basta aggiornare queste due costanti senza toccare le soglie.
Allarme pioggia con Arduino: livelli di intensità e buzzer
Ora trasformiamo la misura in un allarme utile. Il codice esegue 8 letture consecutive di AO, ne calcola la media, la converte in percentuale di bagnato con map() e la assegna a uno di quattro livelli: asciutto, pioggerella, pioggia e acquazzone. Quando la pioggia aumenta, il buzzer attivo suona tante volte quanto il numero del livello: una volta per la pioggerella, due per la pioggia e tre per l'acquazzone. Collega il terminale positivo del buzzer a D8 e quello negativo a GND; la differenza tra buzzer attivo e passivo la trovi in Cos'è un buzzer?.
1// Yağmur şiddeti seviyeleri ve sesli alarm / Rain intensity levels and audible alarm
2const int SENSOR_POWER = 7; // modülün VCC'si / module VCC
3const int RAIN_AO = A0; // analog çıkış / analog output
4const int BUZZER = 8; // aktif buzzer / active buzzer
5const int DRY = 1015; // kuru panel değeri / dry pad reading (kendin ölç / measure yours)
6const int WET = 350; // tamamen ıslak panel / fully wet pad (kendin ölç / measure yours)
7
8const char* const LEVEL_NAMES[] = {"Kuru / Dry", "Ciseleme / Drizzle", "Yagmur / Rain", "Saganak / Downpour"};
9int lastLevel = 0;
10
11int readWetness() {
12 digitalWrite(SENSOR_POWER, HIGH);
13 delay(50);
14 long sum = 0;
15 for (int i = 0; i < 8; i++) sum += analogRead(RAIN_AO); // 8 ölçümün ortalaması / average of 8 readings
16 digitalWrite(SENSOR_POWER, LOW);
17 return constrain(map(sum / 8, DRY, WET, 0, 100), 0, 100); // % ıslaklık / % wetness
18}
19
20void beep(int count) {
21 for (int i = 0; i < count; i++) {
22 digitalWrite(BUZZER, HIGH);
23 delay(150);
24 digitalWrite(BUZZER, LOW);
25 delay(150);
26 }
27}
28
29void setup() {
30 Serial.begin(9600);
31 pinMode(SENSOR_POWER, OUTPUT);
32 pinMode(BUZZER, OUTPUT);
33}
34
35void loop() {
36 int wet = readWetness();
37 int level;
38 if (wet < 10) level = 0; // kuru / dry
39 else if (wet < 40) level = 1; // çiseleme / drizzle
40 else if (wet < 75) level = 2; // yağmur / rain
41 else level = 3; // sağanak / downpour
42
43 Serial.print(F("Islaklik / Wetness: %"));
44 Serial.print(wet);
45 Serial.print(F(" "));
46 Serial.println(LEVEL_NAMES[level]);
47
48 if (level > lastLevel) beep(level); // şiddet artınca seviye kadar bip / beep once per level when it gets heavier
49 lastLevel = level;
50 delay(3000); // 3 sn'de bir ölç / measure every 3 s
51}Questa percentuale indica quanta parte della piastra è bagnata; non è una misura delle precipitazioni in millimetri all'ora come quella usata in meteorologia. Nella pratica, però, è utilissima: una pioggerella leggera collega solo poche piste, mentre un acquazzone copre quasi tutta la superficie. Puoi modificare i limiti dei livelli (10, 40 e 75) in base alle tue osservazioni. Siccome il buzzer suona solo quando il livello sale, non sentirai un bip ogni 3 secondi finché la pioggia resta della stessa intensità.
Corrosione: perché la piastra si ossida e come farla durare?
Il problema principale dei sensori pioggia è l'usura nel tempo. Se la piastra riceve corrente continua (DC) in modo permanente, l'acqua tra le piste si comporta come un elettrolita e inizia l'elettrolisi: il metallo della pista collegata al positivo si scioglie lentamente, la nichelatura si assottiglia e il rame sottostante annerisce o diventa verde. Di conseguenza la resistenza della piastra asciutta cala, i valori si spostano e alla fine le piste si interrompono. Una piastra lasciata all'aperto con 5 V fissi può consumarsi in modo evidente in poche settimane. La buona notizia: l'usura è proporzionale al tempo in cui la piastra è alimentata, e quel tempo lo controlli tu.
- Alimentalo solo durante la misura: Prendi VCC da un pin digitale e tieni acceso il modulo solo 50 ms per lettura. In un sistema che misura ogni 2 secondi, la piastra è alimentata il 2,5% del tempo, e l'usura rallenta di circa 40 volte.
- Misura meno spesso: La pioggia non cambia nel giro di pochi secondi. Per finestre o notifiche basta una lettura ogni 5–30 secondi; un sistema che misura ogni 30 secondi tiene la piastra alimentata solo lo 0,2% circa del tempo.
- Inverti la polarità (livello avanzato): Se colleghi la piastra direttamente a due pin digitali e a ogni lettura cambi quale estremo è HIGH, l'usura si distribuisce in modo uguale sulle due piste. Con questo metodo non usi la scheda di controllo: costruisci da te il partitore con una resistenza e fai una lettura in ciascun verso.
- Tieni pulita la piastra: Polvere, polline ed escrementi di uccelli aumentano la conduttività e abbassano il valore da asciutto. Pulisci la piastra ogni tanto con alcol isopropilico e un pennello morbido; carta vetrata o spugne abrasive graffiano il rivestimento.
- Proteggi la scheda, non la piastra: Metti la scheda di controllo in una scatola stagna o coprila con vernice protettiva. La piastra, invece, non va mai coperta con vernice, silicone o nastro: l'acqua deve toccare le piste.
- Tieni una piastra di ricambio: La piastra è un consumabile economico. Quando i valori si spostano molto o le piste si scuriscono, sostituisci solo la piastra e misura di nuovo DRY e WET.
Chiudere automaticamente una finestra o una tenda con un servomotore
L'applicazione più amata del sensore pioggia è un sistema che chiude da solo una finestra, una tenda da sole o il tetto di una serra quando inizia a piovere. Puoi realizzarlo su un modellino con un servomotore SG90. Qui contano due regole. La prima è la conferma: una singola goccia o un insetto sulla piastra non devono chiudere la finestra, perciò prima di chiudere aspettiamo 3 letture bagnate di fila. La seconda è l'isteresi: quando smette di piovere la piastra non si asciuga subito e il valore oscilla intorno alla soglia. Perché la finestra non si apra e chiuda di continuo usiamo due soglie distinte per "piove" e "asciutto", e riapriamo la finestra solo dopo che la piastra è rimasta asciutta per 10 minuti di fila. Per il collegamento del servo e il controllo dell'angolo consulta Cos'è un servomotore?.


1// Yağmurda pencereyi servo ile kapatan sistem / Closes a window with a servo when it rains
2#include <Servo.h>
3
4const int SENSOR_POWER = 7; // modülün VCC'si / module VCC
5const int RAIN_AO = A0; // analog çıkış / analog output
6const int BUZZER = 8; // aktif buzzer / active buzzer
7const int SERVO_PIN = 9; // servo sinyal kablosu / servo signal wire
8
9const int DRY = 1015; // kuru panel / dry pad (kendin ölç / measure yours)
10const int WET = 350; // ıslak panel / wet pad (kendin ölç / measure yours)
11const int RAIN_ON = 25; // %25 ve üstü: yağıyor / 25% and above: raining
12const int RAIN_OFF = 8; // %8 ve altı: panel kurudu / 8% and below: pad is dry
13const int CONFIRM_COUNT = 3; // art arda 3 ıslak ölçüm / 3 wet readings in a row
14const unsigned long SAMPLE_MS = 2000UL; // 2 sn'de bir ölç / measure every 2 s
15const unsigned long DRY_MS = 600000UL; // 10 dk kuru kalmalı / must stay dry for 10 min
16
17const int OPEN_ANGLE = 90; // pencere açık / window open
18const int CLOSED_ANGLE = 0; // pencere kapalı / window closed
19
20Servo windowServo;
21bool closed = false;
22int wetCount = 0;
23unsigned long lastSample = 0;
24unsigned long drySince = 0;
25
26int readWetness() {
27 digitalWrite(SENSOR_POWER, HIGH);
28 delay(50); // değerin oturmasını bekle / let it settle
29 int raw = analogRead(RAIN_AO);
30 digitalWrite(SENSOR_POWER, LOW);
31 return constrain(map(raw, DRY, WET, 0, 100), 0, 100); // % ıslaklık / % wetness
32}
33
34void beep(int count) {
35 for (int i = 0; i < count; i++) {
36 digitalWrite(BUZZER, HIGH);
37 delay(150);
38 digitalWrite(BUZZER, LOW);
39 delay(150);
40 }
41}
42
43void setup() {
44 Serial.begin(9600);
45 pinMode(SENSOR_POWER, OUTPUT);
46 pinMode(BUZZER, OUTPUT);
47 windowServo.write(OPEN_ANGLE); // attach'tan önce açı ver, servo zıplamasın / set the angle before attach to avoid a jump
48 windowServo.attach(SERVO_PIN);
49}
50
51void loop() {
52 unsigned long now = millis();
53 if (now - lastSample < SAMPLE_MS) return; // ölçüm zamanı gelmedi / not time to measure yet
54 lastSample = now;
55
56 int wet = readWetness();
57 Serial.print(F("Islaklik / Wetness: %"));
58 Serial.println(wet);
59
60 if (wet >= RAIN_ON) {
61 drySince = now; // kuruma sayacını sıfırla / reset the drying timer
62 if (wetCount < CONFIRM_COUNT) wetCount++;
63 if (!closed && wetCount >= CONFIRM_COUNT) {
64 closed = true;
65 beep(3);
66 windowServo.write(CLOSED_ANGLE); // pencereyi kapat / close the window
67 Serial.println(F("Yagmur: pencere kapandi / Rain: window closed"));
68 }
69 } else {
70 wetCount = 0;
71 if (wet > RAIN_OFF) {
72 drySince = now; // ara bölge kuru sayılmaz / the middle zone does not count as dry
73 } else if (closed && now - drySince >= DRY_MS) {
74 closed = false;
75 windowServo.write(OPEN_ANGLE); // 10 dk kuruysa aç / open after 10 dry minutes
76 Serial.println(F("Kuru: pencere acildi / Dry: window opened"));
77 }
78 }
79}| Costante | Funzione | Valore iniziale |
|---|---|---|
| DRY / WET | I valori di piastra asciutta e bagnata che hai misurato tu | 1015 / 350 |
| RAIN_ON | Da questa percentuale in su si considera che "piove" | 25% |
| RAIN_OFF | Fino a questa percentuale inclusa la piastra è considerata "asciutta" | 8% |
| CONFIRM_COUNT | Letture bagnate consecutive necessarie per chiudere la finestra | 3 (circa 6 s) |
| DRY_MS | Per quanto tempo la piastra deve restare asciutta prima di riaprire | 10 minuti |
| OPEN_ANGLE / CLOSED_ANGLE | Angolo del servo in posizione aperta e chiusa | 90° / 0° |
Avvisi di pioggia sul telefono con l'ESP32
Per sapere che ha iniziato a piovere quando non sei a casa puoi usare un ESP32. Il codice qui sotto invia su Telegram il messaggio "ritira il bucato" quando inizia a piovere e "ha smesso di piovere" quando la piastra è rimasta asciutta per 15 minuti. Devi installare le librerie UniversalTelegramBot e ArduinoJson dal Gestore librerie. Come creare il bot e trovare il tuo chat ID lo spieghiamo passo passo in Bot Telegram con ESP32.
1// ESP32 yağmur bildirimi (Telegram) / ESP32 rain notification (Telegram)
2#include <WiFi.h>
3#include <WiFiClientSecure.h>
4#include <UniversalTelegramBot.h> // ArduinoJson kütüphanesi de gerekir / also needs the ArduinoJson library
5
6const char* WIFI_SSID = "WIFI_ADI"; // Wi-Fi ağının adı / your Wi-Fi name
7const char* WIFI_PASS = "WIFI_SIFRESI"; // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:ABCdefGhIJKlmNoPQRstuVWXyz" // BotFather'dan / from BotFather
9#define CHAT_ID "123456789" // senin chat ID'n / your chat ID
10
11const int SENSOR_POWER = 25; // modülün VCC'si (3,3 V) / module VCC (3.3 V)
12const int RAIN_AO = 34; // ADC1 pini, Wi-Fi ile çalışır / ADC1 pin, works with Wi-Fi
13const int DRY = 4095; // kuru panel / dry pad (kendin ölç / measure yours)
14const int WET = 1500; // ıslak panel / wet pad (kendin ölç / measure yours)
15const int RAIN_ON = 25; // %25 ve üstü: yağıyor / 25% and above: raining
16const int RAIN_OFF = 8; // %8 ve altı: kuru / 8% and below: dry
17const unsigned long SAMPLE_MS = 5000UL; // 5 sn'de bir ölç / measure every 5 s
18const unsigned long DRY_MS = 900000UL; // 15 dk kuru: yağmur bitti / 15 dry minutes: rain is over
19
20WiFiClientSecure client;
21UniversalTelegramBot bot(BOT_TOKEN, client);
22
23bool raining = false;
24int wetCount = 0;
25unsigned long lastSample = 0;
26unsigned long drySince = 0;
27
28int readWetness() {
29 digitalWrite(SENSOR_POWER, HIGH);
30 delay(50); // değerin oturmasını bekle / let it settle
31 int raw = analogRead(RAIN_AO); // 0-4095
32 digitalWrite(SENSOR_POWER, LOW);
33 return constrain(map(raw, DRY, WET, 0, 100), 0, 100);
34}
35
36void connectWiFi() {
37 WiFi.mode(WIFI_STA);
38 WiFi.begin(WIFI_SSID, WIFI_PASS);
39 unsigned long start = millis();
40 while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) { // en fazla 15 sn bekle / wait up to 15 s
41 delay(500);
42 }
43}
44
45void notify(const String& text) {
46 if (WiFi.status() != WL_CONNECTED) connectWiFi(); // bağlantı koptuysa yeniden bağlan / reconnect if dropped
47 if (WiFi.status() == WL_CONNECTED) {
48 bot.sendMessage(CHAT_ID, text, "");
49 }
50}
51
52void setup() {
53 Serial.begin(115200);
54 pinMode(SENSOR_POWER, OUTPUT);
55 digitalWrite(SENSOR_POWER, LOW);
56 client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // api.telegram.org kök sertifikası / root certificate
57 connectWiFi();
58 notify("Yagmur sensoru devrede / Rain sensor is online");
59}
60
61void loop() {
62 unsigned long now = millis();
63 if (now - lastSample < SAMPLE_MS) return;
64 lastSample = now;
65
66 int wet = readWetness();
67 Serial.printf("Islaklik / Wetness: %%%d\n", wet);
68
69 if (!raining) {
70 wetCount = (wet >= RAIN_ON) ? wetCount + 1 : 0;
71 if (wetCount >= 2) { // art arda 2 ıslak ölçüm (~10 sn) / 2 wet readings in a row (~10 s)
72 raining = true;
73 drySince = now;
74 String msg = "Yagmur basladi, camasirlari topla! / It's raining, bring in the laundry! %";
75 msg += wet;
76 notify(msg);
77 }
78 } else {
79 if (wet > RAIN_OFF) {
80 drySince = now; // hâlâ ıslak / still wet
81 } else if (now - drySince >= DRY_MS) {
82 raining = false;
83 wetCount = 0;
84 notify("Yagmur durdu / The rain has stopped");
85 }
86 }
87}L'ADC dell'ESP32 è a 12 bit, quindi i valori vanno da 0 a 4095; con il modulo alimentato a 3,3 V una piastra asciutta di solito legge quasi 4095, ma i valori DRY e WET devi comunque misurarli tu. Poiché l'invio di un messaggio può richiedere un paio di secondi, abbiamo fissato l'intervallo di misura a 5 secondi e usiamo la variabile raining perché lo stesso acquazzone non generi un messaggio dopo l'altro. Se vuoi far funzionare il sistema a batteria puoi mettere l'ESP32 in deep sleep tra una misura e l'altra, e se usi Home Assistant puoi inviare i dati via MQTT.
Sensore pioggia con Raspberry Pi Pico e MicroPython
Sul Raspberry Pi Pico la logica è la stessa. Alimenta il modulo a 3,3 V tramite GP15 e collega AO a GP26, DO a GP14, il buzzer attivo a GP13 e il filo di segnale del servo a GP16. L'ADC del Pico restituisce valori da 0 a 65535 con read_u16(). Il codice qui sotto suona tre volte quando rileva la pioggia e ritira una tenda con il servo; quando la piastra è rimasta asciutta per 10 minuti, la riapre.
1# Raspberry Pi Pico yağmur sensörü + servo tente / Raspberry Pi Pico rain sensor + servo awning
2from machine import Pin, ADC, PWM
3import time
4
5power = Pin(15, Pin.OUT, value=0) # modülün VCC'si (3,3 V) / module VCC (3.3 V)
6rain_ao = ADC(26) # GP26 = ADC0, AO çıkışı / AO output
7rain_do = Pin(14, Pin.IN) # DO: yağmurda 0 / DO: 0 in rain
8buzzer = Pin(13, Pin.OUT, value=0) # aktif buzzer / active buzzer
9servo = PWM(Pin(16))
10servo.freq(50) # servolar 50 Hz ister / servos expect 50 Hz
11
12DRY, WET = 65000, 24000 # kendi değerlerinle değiştir / replace with your readings
13RAIN_ON, RAIN_OFF = 25, 8 # % eşikler / % thresholds
14DRY_MS = 10 * 60 * 1000 # 10 dk kuru kalmalı / must stay dry for 10 min
15OPEN_ANGLE, CLOSED_ANGLE = 90, 0
16
17def set_angle(deg):
18 us = 544 + deg * (2400 - 544) // 180 # Arduino Servo ile aynı aralık / same range as Arduino Servo
19 servo.duty_u16(us * 65535 // 20000) # 20 ms periyodun oranı / share of the 20 ms period
20
21def read_sensor():
22 power.value(1)
23 time.sleep_ms(50) # değerin oturmasını bekle / let it settle
24 raw = rain_ao.read_u16() # 0-65535
25 do_wet = rain_do.value() == 0
26 power.value(0)
27 pct = (DRY - raw) * 100 // (DRY - WET)
28 return max(0, min(100, pct)), do_wet
29
30def beep(count):
31 for _ in range(count):
32 buzzer.value(1)
33 time.sleep_ms(150)
34 buzzer.value(0)
35 time.sleep_ms(150)
36
37closed = False
38wet_count = 0
39dry_since = time.ticks_ms()
40set_angle(OPEN_ANGLE) # tente açık başlar / awning starts open
41
42while True:
43 wet, do_wet = read_sensor()
44 print("Islaklik / Wetness: %", wet, " DO:", "YAGMUR / RAIN" if do_wet else "KURU / DRY")
45 now = time.ticks_ms()
46 if wet >= RAIN_ON:
47 dry_since = now # kuruma sayacını sıfırla / reset the drying timer
48 wet_count += 1
49 if not closed and wet_count >= 3: # art arda 3 ıslak ölçüm / 3 wet readings in a row
50 closed = True
51 beep(3)
52 set_angle(CLOSED_ANGLE) # tenteyi kapat / retract the awning
53 else:
54 wet_count = 0
55 if wet > RAIN_OFF:
56 dry_since = now
57 elif closed and time.ticks_diff(now, dry_since) >= DRY_MS:
58 closed = False
59 set_angle(OPEN_ANGLE) # 10 dk kuruysa aç / open after 10 dry minutes
60 time.sleep(2)MicroPython non ha una classe pronta per i servo, quindi convertiamo da soli l'angolo in larghezza d'impulso: i servo si posizionano con impulsi lunghi circa 0,5–2,5 ms che arrivano ogni 20 ms. La funzione set_angle() trasforma 0–180 gradi nello stesso intervallo di 544–2400 microsecondi usato dalla libreria Servo di Arduino e poi converte questo tempo in una frazione da 0 a 65535 per duty_u16(). Se salvi il codice sul Pico come main.py con Thonny, partirà automaticamente a ogni accensione.
Installazione all'aperto: consigli per il posizionamento
- Monta la piastra inclinata: Un'inclinazione di 20–45 gradi fa scivolare via le gocce e aiuta la piastra ad asciugarsi prima quando smette di piovere. Su una piastra piana l'acqua ristagna e il sistema può continuare a dire "piove" per ore.
- Scegli un punto a cielo aperto: Non mettere la piastra sotto una gronda, un albero o lo sgocciolio di un condizionatore; lì perde la pioggia vera e scatta con gocce estranee.
- Tieni l'elettronica al riparo: All'esterno deve restare solo la piastra. Metti la scheda di controllo e Arduino in una scatola stagna e sigilla l'ingresso del cavo con un pressacavo o del silicone.
- Usa cavi corti: Il cavo tra piastra e scheda si può allungare fino a qualche metro; con cavi più lunghi aumentano i disturbi. Fare la media delle letture riduce queste oscillazioni.
- Attenzione a rugiada e nebbia: Nelle notti fresche l'umidità che si condensa sulla piastra può dare un piccolo valore di bagnato. Una soglia RAIN_ON un po' più alta e la conferma con letture consecutive evitano la maggior parte di questi falsi allarmi.
- Rileva la neve in ritardo: La neve asciutta non conduce elettricità; il sensore reagisce solo quando si scioglie in acqua. Nei climi freddi consideralo affidabile soltanto per la pioggia.
Sensore pioggia, di umidità del terreno e di livello dell'acqua: le differenze
| Sensore | Cosa misura? | Uscita | Uso tipico |
|---|---|---|---|
| Sensore pioggia (FC-37, YL-83) | Gocce d'acqua che cadono sulla superficie | AO e DO | Allarme pioggia, automazione di finestre e tende |
| Sensore di umidità del terreno | Umidità nel terreno | AO e DO (stessa scheda LM393) | Irrigazione delle piante |
| Sensore di livello dell'acqua (piste parallele) | Altezza dell'acqua in un contenitore | Analogica (S) | Livello di serbatoi e acquari |
| Pluviometro a bascula | Quantità di pioggia (mm) | Un impulso per ogni ribaltamento | Stazione meteo |


Un sensore pioggia non può rispondere alla domanda "quanto ha piovuto?": per questo serve il pluviometro a bascula usato nelle stazioni meteo. L'acqua raccolta da un imbuto riempie una piccola vaschetta che si ribalta a una quantità fissa (nei kit per stazioni meteo più comuni un ribaltamento corrisponde a 0,2794 mm di pioggia), e a ogni ribaltamento un magnete chiude per un istante un interruttore reed. Arduino conta questi impulsi con un interrupt e moltiplica il numero per il valore della vaschetta per ottenere la pioggia in millimetri. Ha senso anche usare i due sensori insieme: il sensore pioggia segnala subito l'inizio della pioggia, il pluviometro registra il totale. Se vuoi misurare l'altezza dell'acqua raccolta in un contenitore, un sensore di livello dell'acqua è la scelta migliore.
Idee di progetti con il sensore pioggia
- Avviso bucato: Un buzzer che suona e un LED che si accende quando inizia a piovere; con un ESP32 ricevi anche un messaggio sul telefono.
- Tetto della serra intelligente: Chiudi la finestra del tetto con un servo quando piove e aprila in base alla temperatura per arieggiare. Trovi i dettagli nel progetto di serra intelligente.
- Niente irrigazione quando piove: Fai in modo che l'irrigazione automatica costruita con un sensore di umidità del terreno non accenda la pompa mentre piove.
- Mini stazione meteo: Mostra lo stato della pioggia su un display OLED insieme a temperatura, umidità e pressione misurate con un BME280.
- Modellino di tergicristallo: Un progetto divertente che imita i tergicristalli automatici delle auto muovendo un servo tanto più veloce quanto più forte piove.
- Scenario casa intelligente: Per un sistema che chiude le finestre, ritira la tenda e ti avvisa quando inizia a piovere, puoi seguire la guida al progetto di casa intelligente con Arduino.
Errori comuni e soluzioni
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| AO è sempre 1023 e non cambia mai | Il cavo della piastra è scollegato o rotto; ad A0 è collegato DO invece di AO | Controlla i due fili tra piastra e scheda e il collegamento su A0 |
| AO è molto basso anche con la piastra asciutta | Piastra sporca o ancora bagnata; qualcosa collega le piste; la lettura avviene prima di alimentare il modulo | Pulisci e asciuga la piastra; nel codice leggi solo dopo aver alimentato e atteso |
| DO non cambia mai | Il trimmer è girato fino a fine corsa | Ripeti dall'inizio i passi di regolazione della sensibilità |
| Allarme pioggia con tempo asciutto | Rugiada, nebbia, piastra sporca o soglia troppo sensibile | Alza RAIN_ON, conferma con letture consecutive, pulisci la piastra |
| Ha smesso di piovere ma il sistema dice ancora "piove" | La piastra è montata in piano e si asciuga lentamente | Monta la piastra inclinata, regola RAIN_OFF e DRY_MS |
| I valori si sono spostati in poche settimane e le piste sono scure | Corrosione da alimentazione continua | Alimenta il modulo da un pin, misura meno spesso, sostituisci la piastra |
| Sull'ESP32 le letture impazziscono quando si attiva il Wi-Fi | AO è collegato a un pin ADC2 | Sposta AO su un pin tra GPIO 32 e 39 |
| Il servo trema o Arduino si riavvia | La corrente del servo fa calare la linea a 5 V | Alimenta il servo con una sorgente a 5 V separata, collega le masse e aggiungi un condensatore da 470 µF sull'alimentazione |
Il sensore pioggia è un modulo economico ma molto istruttivo, che ti insegna insieme partitori di tensione, comparatori, isteresi e problemi reali come la corrosione. Se ricordi di alimentare la piastra solo durante la misura e di regolare le soglie in base alle tue letture, ti servirà a lungo. Nell'app BlueGrays trovi progetti passo passo con schemi elettrici e codice che usano i componenti di questo articolo, come buzzer, servomotore, una stazione di irrigazione intelligente e un allarme Telegram con ESP32, e puoi aggiungervi facilmente il sensore pioggia.
Domande frequenti
Come funziona un sensore pioggia?
Le due piste conduttive intrecciate della piastra sensibile sono isolate tra loro quando sono asciutte. Quando le gocce di pioggia le collegano, la resistenza della piastra scende e l'uscita (AO) del partitore di tensione sulla scheda di controllo diminuisce. Il comparatore LM393 confronta questa tensione con la soglia impostata dal trimmer e porta l'uscita DO a LOW quando viene superata.
Il sensore pioggia misura la quantità di pioggia?
No. Il sensore pioggia indica quanta parte della piastra è bagnata: basta per capire che ha iniziato a piovere e, a grandi linee, con quale intensità, ma non fornisce le precipitazioni in millimetri. Per misurare la quantità di pioggia si usa un pluviometro a bascula, che genera un impulso tramite un interruttore reed a ogni ribaltamento.
Perché il sensore pioggia si corrode e quanto dura?
Quando la piastra riceve corrente continua in modo permanente, nell'acqua tra le piste avviene l'elettrolisi e il metallo della pista dal lato positivo si scioglie. Una piastra lasciata all'aperto con 5 V fissi può consumarsi in modo evidente in poche settimane. Se alimenti il modulo da un pin digitale e lo accendi solo per pochi millisecondi a ogni lettura, la piastra dura molto di più, spesso molti mesi senza problemi.
Il sensore pioggia dà LOW o HIGH quando piove?
Nei comuni moduli con LM393 l'uscita DO è HIGH da asciutto; quando l'acqua sulla piastra supera la soglia impostata con il trimmer passa a LOW e il LED DO si accende. L'uscita AO è al massimo da asciutto e scende man mano che la piastra si bagna; su Arduino Uno una piastra asciutta di solito legge più di 1000.
Il sensore pioggia funziona con l'ESP32 e a 3,3 V?
Sì, il modulo funziona tra 3,3 e 5 V. Sull'ESP32 e sul Raspberry Pi Pico devi alimentarlo a 3,3 V, così anche le uscite AO e DO non superano mai 3,3 V. Sull'ESP32 collega AO a uno dei pin ADC1 (GPIO 32–39), che funzionano anche con il Wi-Fi attivo.
Il sensore pioggia rileva neve, rugiada o nebbia?
La neve asciutta non conduce elettricità, quindi il sensore la rileva solo quando si scioglie. Rugiada e nebbia fitta, invece, possono lasciare un sottile velo d'umidità sulla piastra, producendo un piccolo valore di bagnato e a volte un falso allarme. Per evitarlo tieni la soglia un po' più alta, conferma l'allarme con più letture consecutive e monta la piastra inclinata.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Uso del cicalino
Ti sei mai chiesto come fa un campanello o un allarme a suonare? L'Arduino fa suonare un piccolo cicalino a intervalli brevi: bip, pausa, bip, pausa. Vedi come l'elettricità diventa suono e fai il pri

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

Utilizzo del servomotore
Il braccio di un piccolo servomotore ruota a turno in tre posizioni: tutto all'inizio, esattamente a metà e tutto alla fine, aspettando due secondi a ogni fermata. L'Arduino dice al motore a quale ang

Stazione di irrigazione intelligente
Un giardiniere che annaffia le tue piante da solo, così non si seccano mentre sei in vacanza. Un sensore di umidità misura quanto è bagnata la terra; quando diventa secca, l'Arduino accende la pompa d

Utilizzo del sensore di fiamma
Un piccolo guardiano che si accorge del fuoco prima di te, in cucina o in laboratorio. Il sensore di fiamma cattura la luce invisibile che il fuoco emette; se va tutto bene è acceso il LED verde, quan

Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
Un sistema di allarme di sicurezza intelligente che attiva buzzer e LED quando il sensore PIR rileva movimento, inviando contemporaneamente una notifica istantanea al proprietario tramite Telegram. Dispone di un tempo di attesa di 30 secondi per limitare la frequenza degli allarmi ripetuti; questo meccanismo non verifica la validità dei rilevamenti del sensore PIR né elimina le false attivazioni. Adatto a sicurezza domestica, monitoraggio di garage, magazzini o studi. Con l'ESP32-CAM è possibile

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

