Componenti · 16 min di lettura

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.

Modulo sensore pioggia (FC-37 / YL-83) con scheda di controllo LM393
Kit sensore pioggia: a sinistra la piastra sensibile YL-83 con le piste intrecciate, a destra la scheda di controllo con il comparatore LM393, il trimmer della sensibilità e i LED PWR e DO; in mezzo il cavo di collegamento.

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.

CaratteristicaValore
Piastra sensibileCirca 5,4 × 4 cm; piste intrecciate su FR4, nichelate nella maggior parte dei modelli
Scheda di controlloCirca 3 × 1,5 cm, comparatore LM393
Tensione di alimentazione3,3–5 V
AssorbimentoCirca 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
IndicatoriLED PWR (alimentazione) e LED DO (pioggia rilevata)
RegolazioneTrimmer della sensibilità (cambia solo la soglia di DO)
Collegamenti2 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.

CaratteristicaDO (digitale)AO (analogica)
Cosa indicaPiove / non pioveQuanto è bagnata la piastra (0–1023 sull'Uno)
Regolazione della sogliaTrimmer sulla schedaNel codice, come preferisci
Pin di ArduinoQualsiasi pin digitalePin analogico (A0–A5)
Distingue l'intensitàNoSì (pioggerella, pioggia, acquazzone)
Uso con gli interruptSìNo
Ideale perAllarmi semplici, segnale di risveglioMisura dei livelli, automazione con isteresi

Collegamento del sensore pioggia: Arduino Uno, ESP32 e Pico

Pin del modulo / componenteArduino UnoESP32Raspberry Pi Pico
VCCD7 (per alimentarlo solo durante la misura) o 5VGPIO 25 o 3V3GP15 o 3V3(OUT)
GNDGNDGNDGND
AOA0GPIO 34 (ADC1)GP26 (ADC0)
DOD2Facoltativo (es. GPIO 27)GP14
Buzzer attivo (+)D8FacoltativoGP13
Filo di segnale del servoD9FacoltativoGP16
I pin dell'ESP32 e del Raspberry Pi Pico sopportano al massimo 3,3 V. Se su queste schede alimenti il modulo da 5V, VIN o VBUS, con la piastra asciutta le uscite AO e DO salgono a 5 V e possono danneggiare gli ingressi. Alimenta il modulo a 3,3 V o tramite un pin GPIO. Sull'ESP32 collega sempre AO a uno dei pin ADC1 (GPIO 32–39): i pin ADC2 non si possono leggere con il Wi-Fi attivo.

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

  1. Asciuga bene la piastra e alimenta il modulo; il LED PWR deve essere acceso e il LED DO spento.
  2. 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.
  3. Torna esattamente al punto in cui il LED si spegne. È la regolazione più sensibile con cui DO resta HIGH a piastra asciutta.
  4. 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.
  5. 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à.
  6. 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".
Se fai le prove con l'acqua del rubinetto, prendi il risultato con cautela: i minerali disciolti la rendono di solito parecchie volte più conduttiva dell'acqua piovana. Una soglia che funziona perfettamente con l'acqua del rubinetto può reagire in ritardo a una vera pioggerella. La regolazione più precisa si fa il primo giorno di pioggia, leggendo i valori reali nel Monitor seriale; fino ad allora, nebulizzare goccioline sottili con uno spruzzino imita la pioggia molto meglio che mettere la piastra sotto il rubinetto.

Passo passo: la prima lettura con Arduino

  1. 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.
  2. Apri il codice qui sotto nell'Arduino IDE, scegli Arduino Uno come scheda e caricalo.
  3. Apri il Monitor seriale a 9600 baud e annota il valore di AO con la piastra asciutta.
  4. Fai cadere sulla piastra prima qualche goccia d'acqua, poi di più, e annota ogni volta il valore di AO.
  5. Annota anche il valore con la piastra completamente bagnata: questi valori diventeranno le costanti DRY e WET degli sketch successivi.
C++ (Arduino IDE)
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 piastraAO indicativo (Uno, 5 V)DO (scheda regolata)
Asciutta e pulita1000–1023HIGH
Qualche goccia750–950HIGH o LOW a seconda della regolazione
Pioggerella, piastra bagnata in parte500–750LOW
Pioggia intensa300–500LOW
Completamente bagnata, acqua del rubinetto150–350LOW

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?.

C++ (Arduino IDE)
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?.

SG90 servo motor
SG90 servo motor
Buzzer attivo
Buzzer attivo
C++ (Arduino IDE)
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}
CostanteFunzioneValore iniziale
DRY / WETI valori di piastra asciutta e bagnata che hai misurato tu1015 / 350
RAIN_ONDa questa percentuale in su si considera che "piove"25%
RAIN_OFFFino a questa percentuale inclusa la piastra è considerata "asciutta"8%
CONFIRM_COUNTLetture bagnate consecutive necessarie per chiudere la finestra3 (circa 6 s)
DRY_MSPer quanto tempo la piastra deve restare asciutta prima di riaprire10 minuti
OPEN_ANGLE / CLOSED_ANGLEAngolo del servo in posizione aperta e chiusa90° / 0°
Un SG90 in movimento può assorbire alcune centinaia di mA; se usi più servo o un modello grande come l'MG996R, alimentali con una sorgente a 5 V separata invece che dal pin 5V di Arduino e collega insieme le masse. Per una finestra o una tenda vere un servo non basta: servono un motoriduttore o un attuatore lineare, finecorsa a entrambe le estremità e una protezione contro lo schiacciamento. Questo codice serve a capire la logica che comanda il meccanismo e a provarla su un modellino.

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.

C++ (Arduino IDE)
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.

MicroPython
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

SensoreCosa misura?UscitaUso tipico
Sensore pioggia (FC-37, YL-83)Gocce d'acqua che cadono sulla superficieAO e DOAllarme pioggia, automazione di finestre e tende
Sensore di umidità del terrenoUmidità nel terrenoAO e DO (stessa scheda LM393)Irrigazione delle piante
Sensore di livello dell'acqua (piste parallele)Altezza dell'acqua in un contenitoreAnalogica (S)Livello di serbatoi e acquari
Pluviometro a basculaQuantità di pioggia (mm)Un impulso per ogni ribaltamentoStazione meteo
Sensore di umidità del terreno con la stessa scheda LM393
Sensore di umidità del terreno con la stessa scheda LM393
Sensore di livello dell’acqua
Sensore di livello dell’acqua

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

SintomoCausa probabileSoluzione
AO è sempre 1023 e non cambia maiIl cavo della piastra è scollegato o rotto; ad A0 è collegato DO invece di AOControlla i due fili tra piastra e scheda e il collegamento su A0
AO è molto basso anche con la piastra asciuttaPiastra sporca o ancora bagnata; qualcosa collega le piste; la lettura avviene prima di alimentare il moduloPulisci e asciuga la piastra; nel codice leggi solo dopo aver alimentato e atteso
DO non cambia maiIl trimmer è girato fino a fine corsaRipeti dall'inizio i passi di regolazione della sensibilità
Allarme pioggia con tempo asciuttoRugiada, nebbia, piastra sporca o soglia troppo sensibileAlza 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 lentamenteMonta la piastra inclinata, regola RAIN_OFF e DRY_MS
I valori si sono spostati in poche settimane e le piste sono scureCorrosione da alimentazione continuaAlimenta il modulo da un pin, misura meno spesso, sostituisci la piastra
Sull'ESP32 le letture impazziscono quando si attiva il Wi-FiAO è collegato a un pin ADC2Sposta AO su un pin tra GPIO 32 e 39
Il servo trema o Arduino si riavviaLa corrente del servo fa calare la linea a 5 VAlimenta il servo con una sorgente a 5 V separata, collega le masse e aggiungi un condensatore da 470 µF sull'alimentazione
Il modo più semplice per provare il sistema senza aspettare la pioggia è passare un dito bagnato o un fazzoletto umido sulle piste della piastra. Per una prova più realistica, spruzza la piastra alcune volte con uno spruzzino da 30–40 cm di distanza; nel Monitor seriale vedrai la percentuale di bagnato salire e poi scendere lentamente mentre la piastra si asciuga.

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.

Vedi tutti i progetti
Uso del cicalino
#13Principiante

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

4.7(89)
161
Temperatura e umidità con DHT11
#55Intermedio

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

4.7(47)
73
Utilizzo del servomotore
#35Principiante
Premium

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

4.7(48)
67
Stazione di irrigazione intelligente
#83Avanzato
Premium

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

5.0(42)
57
Utilizzo del sensore di fiamma
#50Intermedio
Premium

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

4.6(33)
44
Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
#145Avanzato
Premium

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

0.0(0)
9
ESP32 HTTPClient + API meteo (con schermo LCD)
#133Avanzato
Premium

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

4.7(13)
20