Componenti · 16 min di lettura

Reed switch con Arduino: sensore porta, allarme e tachimetro bici

Come funziona il reed switch e come collegarlo ad Arduino: NA/NC, distanza del magnete, pull-up e antirimbalzo, allarme porta, tachimetro bici, ESP32 e Pico.

Il reed switch (interruttore reed o sensore magnetico) è un sensore semplicissimo che chiude un circuito quando un magnete porta a contatto due sottili lamelle metalliche chiuse in un'ampolla di vetro, e da solo non consuma alcuna energia. Su Arduino si legge esattamente come un pulsante: con il magnete vicino il contatto si chiude, allontanandolo si riapre. Questa piccola ampolla di vetro si trova dentro gli allarmi per porte e finestre, i contachilometri da bici, gli interruttori a galleggiante e gli anemometri.

In questa guida imparerai passo passo che cosa c'è dentro un reed switch, i tipi NA e NC, a quale distanza e con quale orientamento il magnete funziona meglio e come collegarlo ad Arduino con una resistenza di pull-up. Poi eliminerai il rimbalzo del contatto via software, costruirai un allarme per porta aperta e un tachimetro per bici, invierai al tuo telefono un avviso di "porta aperta" con un ESP32 e farai funzionare lo stesso circuito su un Raspberry Pi Pico con MicroPython. Nelle ultime sezioni confrontiamo il reed con un sensore a effetto Hall e raccogliamo gli errori più comuni.

Modulo sensore reed e reed switch in ampolla di vetro
Modulo reed switch: l'ampolla di vetro a sinistra contiene due lamelle metalliche; il comparatore LM393 e il trimmer sulla scheda forniscono un segnale digitale pulito sul pin DO.

Che cos'è un reed switch e come funziona?

Il cuore di un reed switch è una piccola ampolla di vetro riempita con un gas inerte, come l'azoto, oppure sotto vuoto. Dalle due estremità entrano due lamelle flessibili in lega di ferro e nichel che si sovrappongono al centro con una distanza minima; la parola inglese "reed" (ancia) si riferisce proprio a loro. Le punte sono rivestite di metalli duri come rodio o rutenio, che mantengono bassa la resistenza di contatto e riducono l'usura. Quando si avvicina un magnete, le due lamelle si magnetizzano, sulle punte sovrapposte si formano poli opposti e le lamelle si attraggono fino a toccarsi. Quando il magnete si allontana, l'elasticità delle lamelle separa di nuovo i contatti. Poiché il vetro protegge i contatti da polvere, umidità e ossidazione, un reed switch può commutare centinaia di milioni di volte con correnti basse.

Spesso questo componente viene chiamato "relè reed", ma tecnicamente l'ampolla di vetro da sola è un reed switch (interruttore reed). Un vero relè reed è la stessa ampolla con una bobina avvolta intorno; lì è la corrente nella bobina, e non un magnete, a chiudere i contatti. Questo articolo tratta l'interruttore azionato da un magnete e i moduli sensore che lo montano. Il suo vantaggio più grande è che non consuma energia: lo attraversa solo la corrente del tuo circuito, per questo è ideale per dispositivi che funzionano per mesi a batteria.

Caratteristiche tecniche del reed switch

CaratteristicaValore tipico (piccolo reed in vetro)
Tipo di contattoForma A (NA, normalmente aperto), il più comune
Ampolla di vetroCirca 2 mm di diametro, 10–15 mm di lunghezza
Potenza commutabileFino a 10 W
Tensione commutabileFino a 100–200 V DC
Corrente commutabileCirca 0,5 A
Resistenza di contattoMeno di 0,1 Ω
Tempo di interventoMeno di 1 ms (rimbalzi inclusi)
Sensibilità10–40 AT (amperspire)
DurataDa 100 milioni a 1 miliardo di commutazioni con corrente bassa
Consumo proprioNessuno (componente passivo)

La sensibilità si indica in AT (amperspire): la corrente moltiplicata per il numero di spire necessarie a chiudere il reed in una bobina di prova standard. Più il valore è basso, più debole può essere il magnete e quindi maggiore è la distanza di intervento. C'è anche un'isteresi: il campo necessario a chiudere i contatti (attrazione) è più forte di quello che basta a tenerli chiusi. Per esempio, un reed che il magnete chiude a 15 mm può riaprirsi solo intorno ai 20 mm. Questa differenza riduce le aperture e chiusure dovute a piccole vibrazioni, ma nel tuo progetto il magnete deve allontanarsi anche oltre la distanza di rilascio.

Tipi NA, NC e in scambio (Forma A, B e C)

I reed switch esistono in tre configurazioni di contatto. Le sigle NA (normalmente aperto, NO in inglese) e NC (normalmente chiuso) descrivono sempre lo stato del contatto senza magnete.

TipoSenza magneteMagnete vicinoPiediniDove si usa?
Forma A (NA)ApertoChiuso2Sensori porta, contatori di velocità, la maggior parte dei moduli
Forma B (NC)ChiusoAperto2Applicazioni che devono chiudere il circuito quando il magnete si allontana
Forma C (in scambio)COM–NC chiusoCOM–NO chiuso3Circuiti che richiedono sia un'uscita aperta sia una chiusa
I contatti magnetici per allarmi (come il diffuso modello MC-38) vengono spesso venduti come "NC". Qui NC significa che il circuito è chiuso a porta chiusa, cioè con il magnete accanto; all'interno c'è in realtà un reed di Forma A (NA). Per questo prova prima il sensore con la funzione di continuità (bip) del multimetro, con e senza magnete; se scrivi il codice basandoti solo sull'etichetta rischi di avere la logica invertita.

Attivazione con il magnete: distanza, orientamento e sensibilità

Il modo migliore per attivare un reed switch è un piccolo magnete al neodimio. Un disco al neodimio da 10×3 mm attiva di solito un reed comune a 10–20 mm; un magnete in ferrite nera delle stesse dimensioni dimezza circa questa distanza. I sensori porta in commercio lavorano tipicamente a 15–25 mm. La distanza non dipende solo dalla forza del magnete ma anche dal suo orientamento: se l'asse nord-sud del magnete è parallelo all'ampolla e si avvicina al suo centro, ottieni una sola chiusura pulita. Se il magnete è perpendicolare all'ampolla, può non attivarla affatto esattamente al centro e attivarla invece in due punti vicino alle estremità. Facendo scorrere un magnete parallelo lungo l'ampolla si formano inoltre piccole zone di chiusura extra ai lati di quella principale. Quando il magnete passa davanti al reed, il contatto può quindi chiudersi e aprirsi due o tre volte; è il motivo più comune per cui i progetti di conteggio registrano un giro come due o tre.

Tipi di magneti al neodimio: disco, cubo, blocco e svasato
I magneti al neodimio sono ideali per attivare un reed switch; quelli con foro svasato si avvitano facilmente alla porta o al telaio.
  • La polarità non conta: Il reed reagisce allo stesso modo al polo nord e al polo sud; girare il magnete non cambia il risultato.
  • Allinea il magnete al centro dell'ampolla: Nei sensori porta, il magnete e il corpo del reed devono stare affiancati e paralleli, con la distanza più piccola possibile.
  • Le porte in acciaio accorciano la distanza: Il ferro concentra su di sé il campo del magnete. Solleva sensore e magnete con uno spessore in plastica da 5–10 mm oppure usa un magnete più forte.
  • Misura prima la distanza: Con il monitor seriale aperto, avvicina e allontana lentamente il magnete. A porta chiusa il magnete deve trovarsi ben dentro la distanza di attrazione; con la porta socchiusa deve essere oltre la distanza di rilascio.
  • Tienilo lontano da campi forti: Altoparlanti, motori e altri magneti possono chiudere il reed involontariamente; non montarlo proprio accanto a loro.

Collegare il reed switch ad Arduino: perché serve una resistenza di pull-up?

Poiché il reed switch si comporta come un pulsante, da solo non produce alcuna tensione; si limita a collegare o scollegare i suoi due piedini. Con il contatto aperto il pin non è collegato a nulla (resta flottante) e leggi valori HIGH e LOW casuali dovuti ai disturbi. La soluzione è una resistenza di pull-up: il pin viene portato a 5 V (o 3,3 V) tramite una resistenza e il reed si collega tra il pin e GND. Senza magnete il pin legge HIGH; quando il magnete chiude il contatto, il pin è collegato direttamente a GND e legge LOW. L'Arduino Uno ha una pull-up interna da 20–50 kΩ, quindi basta scrivere pinMode(pin, INPUT_PULLUP) e non serve una resistenza esterna. Trovi i dettagli di questa logica nella guida come collegare un pulsante ad Arduino.

CollegamentoArduino UnoESP32Raspberry Pi Pico
Piedino 1 del reed (reed singolo)D2GPIO 27GP15 (pin fisico 20)
Piedino 2 del reed (reed singolo)GNDGNDGND
Pull-upInterna (INPUT_PULLUP)Interna (INPUT_PULLUP)Interna (Pin.PULL_UP)
VCC del modulo5V3V33V3(OUT) (pin fisico 36)
GND del moduloGNDGNDGND
DO del moduloD2GPIO 27GP15
LED di statoD13 (LED sulla scheda)GPIO 2 (LED sulla scheda)LED integrato
Buzzer attivo (+)D8Non usatoGP14
Non collegare mai il reed switch direttamente tra 5V e GND o a un pin impostato come OUTPUT: appena si avvicina un magnete si crea un cortocircuito, i sottili contatti possono saldarsi e restare chiusi e il regolatore della scheda può danneggiarsi. Sull'ESP32 i GPIO 34–39 sono solo ingressi e non hanno pull-up interne; se colleghi il reed a questi pin, aggiungi una resistenza di pull-up esterna da 10 kΩ.

Primo circuito passo passo: rilevare il magnete

  1. Collega un piedino del reed switch al pin D2 di Arduino e l'altro a GND. Un reed singolo non ha polarità, quindi il verso dei piedini non conta.
  2. Se usi un modulo, collega VCC a 5V, GND a GND e l'uscita DO a D2.
  3. Carica il codice qui sotto e apri il monitor seriale a 9600 baud.
  4. Avvicina lentamente il magnete tenendolo parallelo all'ampolla di vetro; il LED sulla scheda deve accendersi e sullo schermo deve comparire "magnet detected".
  5. Allontanando il magnete, misura con un righello a che distanza si spegne il LED; questa è la tua distanza di rilascio.
C++ (Arduino IDE)
1const byte REED_PIN = 2;             // reed: D2 ile GND arasında / reed between D2 and GND
2const byte LED_PIN = 13;             // karttaki LED / onboard LED
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(REED_PIN, INPUT_PULLUP);   // dahili pull-up: mıknatıs yokken HIGH / internal pull-up: HIGH without a magnet
7  pinMode(LED_PIN, OUTPUT);
8}
9
10void loop() {
11  if (digitalRead(REED_PIN) == LOW) {       // kontak kapalı: mıknatıs yakında / contacts closed: magnet nearby
12    digitalWrite(LED_PIN, HIGH);
13    Serial.println(F("Miknatis var / magnet detected"));
14  } else {                                  // kontak açık: mıknatıs uzakta / contacts open: magnet away
15    digitalWrite(LED_PIN, LOW);
16    Serial.println(F("Miknatis yok / no magnet"));
17  }
18  delay(200);
19}

L'unica cosa a cui fare attenzione nel codice è la logica invertita: poiché usi INPUT_PULLUP, leggi LOW quando c'è il magnete e HIGH quando non c'è. Anche nei moduli a 3 pin con LM393 l'uscita di solito va a LOW quando il magnete si avvicina e il LED DO sulla scheda si accende; dato che può cambiare da modello a modello, verifica prima il tuo modulo nel monitor seriale. Il trimmer del modulo regola la soglia del comparatore; poiché il reed funziona già come aperto o chiuso, influisce poco sulla distanza di rilevamento e di solito basta lasciarlo a metà corsa. I mini moduli come il KY-021 non hanno comparatore; sulla scheda ci sono solo il reed e una resistenza da 10 kΩ.

Antirimbalzo: rimbalzi del contatto e vibrazioni

Come ogni contatto meccanico, anche il reed può rimbalzare qualche volta mentre si chiude. Nel reed questo rimbalzo è brevissimo, di solito sotto 1 ms, ma il vero problema è un altro. Se il magnete si muove lentamente al limite della distanza di attrazione, o se la porta vibra per il vento, il contatto può aprirsi e chiudersi molte volte in un secondo. Per questo un sistema che avvisa all'apertura della porta può inviare cinque messaggi per una sola apertura. La soluzione è aspettare che lo stato resti invariato per un certo tempo invece di accettare subito ogni cambiamento. Per un sensore porta bastano 50–100 ms; in un contatore di velocità conviene usare come tempo di blocco l'intervallo più breve fisicamente possibile tra due impulsi.

Se preferisci una soluzione hardware, puoi mettere un condensatore da 100 nF tra il pin e GND. Insieme a una pull-up da 10 kΩ si ottiene una costante di tempo τ = R × C = 10 kΩ × 100 nF = 1 ms, che smorza i rimbalzi molto brevi. Puoi provare altre coppie di resistenza e condensatore con il calcolatore della costante di tempo RC. Con la pull-up interna la resistenza è di 20–50 kΩ, quindi il tempo sale a 2–5 ms. Nei sensori porta con diversi metri di cavo, una pull-up esterna da 4,7–10 kΩ e questo condensatore proteggono anche dai disturbi.

Sensore di porta e finestra aperta: progetto di allarme

Il progetto con reed più diffuso è il sensore porta. Fissa il magnete sull'anta mobile e il reed sul telaio; a porta chiusa i due sono affiancati, il contatto è chiuso e il pin legge LOW. Quando la porta si apre, il magnete si allontana e il pin va a HIGH. Questa disposizione ha un utile effetto collaterale: se qualcuno taglia il cavo del sensore, il pin va comunque a HIGH e il sistema lo interpreta come "porta aperta". È per questo che gli allarmi usano circuiti ad anello chiuso. Il codice qui sotto conta ogni apertura, misura per quanto tempo la porta resta aperta e fa suonare il buzzer a intermittenza se resta aperta per più di 30 secondi; perfetto per la porta del frigorifero o del congelatore.

C++ (Arduino IDE)
1const byte REED_PIN = 2;                  // reed: D2 ile GND arası / reed between D2 and GND
2const byte BUZZER_PIN = 8;                // aktif buzzer artı ucu / active buzzer positive leg
3const byte LED_PIN = 13;                  // karttaki LED / onboard LED
4const unsigned long STABLE_MS = 50;       // debounce: 50 ms değişmeden kalmalı / debounce: must hold for 50 ms
5const unsigned long OPEN_LIMIT = 30000;   // 30 sn'den uzun açık kalırsa alarm / alarm if open longer than 30 s
6
7bool doorOpen = false;                    // onaylanmış durum / confirmed state
8bool lastReading = false;                 // son ham okuma / last raw reading
9unsigned long lastChange = 0;             // ham okumanın son değiştiği an / when the raw reading last changed
10unsigned long openedAt = 0;               // kapının açıldığı an / when the door was opened
11unsigned int openCount = 0;               // toplam açılış / total openings
12
13void setup() {
14  Serial.begin(9600);
15  pinMode(REED_PIN, INPUT_PULLUP);
16  pinMode(BUZZER_PIN, OUTPUT);
17  pinMode(LED_PIN, OUTPUT);
18  doorOpen = (digitalRead(REED_PIN) == HIGH);   // açılıştaki durumu al / take the state at boot
19  lastReading = doorOpen;
20}
21
22void loop() {
23  unsigned long now = millis();
24  bool reading = (digitalRead(REED_PIN) == HIGH);   // HIGH: mıknatıs uzak, kapı açık / HIGH: magnet away, door open
25
26  if (reading != lastReading) {           // ham değer değişti, sayacı yeniden başlat / raw value changed, restart the timer
27    lastReading = reading;
28    lastChange = now;
29  }
30
31  if (reading != doorOpen && now - lastChange >= STABLE_MS) {   // 50 ms kararlı: gerçek değişim / stable for 50 ms: real change
32    doorOpen = reading;
33    if (doorOpen) {
34      openedAt = now;
35      openCount++;
36      Serial.print(F("Kapi acildi / door opened, sayac / count: "));
37      Serial.println(openCount);
38    } else {
39      Serial.print(F("Kapi kapandi / door closed, sure / duration (s): "));
40      Serial.println((now - openedAt) / 1000);
41    }
42  }
43
44  digitalWrite(LED_PIN, doorOpen ? HIGH : LOW);     // LED kapı açıkken yanar / LED is on while the door is open
45
46  // Uzun süre açık kalırsa çeyrek saniyede bir öt / beep every quarter second if left open too long
47  bool alarm = doorOpen && (now - openedAt > OPEN_LIMIT);
48  digitalWrite(BUZZER_PIN, (alarm && (now / 250) % 2) ? HIGH : LOW);
49}

Poiché il codice non usa delay(), il ciclo controlla il pin di continuo e non perde nessuna apertura; spieghiamo questa tecnica in dettaglio nell'articolo millis invece di delay. Ogni volta che la lettura grezza cambia, il tempo lastChange viene aggiornato, e lo stato doorOpen cambia solo se il valore resta uguale per 50 ms. La parte del buzzer divide millis() per 250 per accenderlo e spegnerlo ogni quarto di secondo. Per trasformarlo in un vero allarme puoi inserirlo e disinserirlo con un tastierino e una password, e aggiungere un sensore di movimento PIR nella stanza. Per un sistema più completo, dai un'occhiata all'articolo sistema di allarme con Arduino.

Tachimetro per bici: contare i giri con un reed switch

La maggior parte dei contachilometri per bici è composta da un reed switch e da un piccolo magnete fissato a un raggio. A ogni giro della ruota, il magnete passa una volta davanti al reed sulla forcella e genera un impulso. Se misuri il tempo tra due impulsi ottieni la velocità, se conti gli impulsi la distanza: velocità (km/h) = circonferenza (mm) / tempo (ms) × 3,6. Qui mm/ms equivale esattamente a m/s, e moltiplicando per 3,6 si passa ai km/h. Per esempio, su una ruota 700x25C con circonferenza di 2105 mm, 253 ms tra due impulsi danno 2105 / 253 × 3,6 ≈ 30 km/h. Il modo più preciso per misurare la circonferenza è far rotolare la ruota per un giro esatto con la valvola in basso e misurare la distanza tra i due segni a terra.

Misura dello pneumaticoCirconferenza approssimativaTempo per giro a 30 km/h
20x1.75 (BMX, bici da bambino)1515 mm182 ms
26x2.1 (mountain bike)2068 mm248 ms
29x2.1 (mountain bike)2288 mm275 ms
700x25C (bici da corsa)2105 mm253 ms
700x28C (city bike, gravel)2136 mm256 ms
C++ (Arduino IDE)
1const byte REED_PIN = 2;                  // kesme pini D2 (INT0) / interrupt pin D2 (INT0)
2const float WHEEL_MM = 2105.0;            // 700x25C tekerlek çevresi (mm) / 700x25C wheel circumference (mm)
3const unsigned long LOCKOUT_MS = 80;      // daha sık darbe imkânsız (~95 km/sa) / faster pulses are impossible (~95 km/h)
4const unsigned long TIMEOUT_MS = 3000;    // 3 sn darbe yoksa hız 0 / no pulse for 3 s means speed 0
5
6volatile unsigned long lastPulseMs = 0;   // son geçerli darbe zamanı / time of the last valid pulse
7volatile unsigned long periodMs = 0;      // son iki darbe arası süre / time between the last two pulses
8volatile unsigned long revCount = 0;      // toplam tur / total revolutions
9
10void onMagnet() {                         // ISR: kısa ve hızlı / ISR: short and fast
11  unsigned long now = millis();
12  unsigned long dt = now - lastPulseMs;
13  if (dt < LOCKOUT_MS) return;            // sıçrama ya da çift darbe: yok say / bounce or double pulse: ignore
14  periodMs = (dt < TIMEOUT_MS) ? dt : 0;  // uzun duraklamadan sonraki ilk darbe hız vermez / first pulse after a stop gives no speed
15  lastPulseMs = now;
16  revCount++;
17}
18
19void setup() {
20  Serial.begin(9600);
21  pinMode(REED_PIN, INPUT_PULLUP);
22  attachInterrupt(digitalPinToInterrupt(REED_PIN), onMagnet, FALLING);   // mıknatıs gelince HIGH->LOW / HIGH->LOW when the magnet arrives
23}
24
25void loop() {
26  static unsigned long lastPrint = 0;
27  if (millis() - lastPrint < 500) return; // saniyede 2 kez yaz / print twice per second
28  lastPrint = millis();
29
30  noInterrupts();                         // çok baytlı değerleri güvenle kopyala / copy multi-byte values safely
31  unsigned long period = periodMs;
32  unsigned long last = lastPulseMs;
33  unsigned long revs = revCount;
34  interrupts();
35
36  float speedKmh = 0;
37  if (period > 0 && millis() - last < TIMEOUT_MS) {
38    speedKmh = WHEEL_MM / period * 3.6;   // mm/ms = m/s; 3,6 ile çarp = km/sa / multiply by 3.6 = km/h
39  }
40  float distanceKm = revs * WHEEL_MM / 1000000.0;   // tur x çevre / revolutions x circumference
41
42  Serial.print(F("Hiz / speed: "));
43  Serial.print(speedKmh, 1);
44  Serial.print(F(" km/h   Mesafe / distance: "));
45  Serial.print(distanceKm, 3);
46  Serial.println(F(" km"));
47}

Poiché l'impulso viene catturato con attachInterrupt, nessun giro va perso per quanto loop() sia occupato; sull'Arduino Uno solo i pin D2 e D3 offrono questo tipo di interrupt. Il valore LOCKOUT_MS è molto importante: 80 ms corrispondono a una velocità massima di circa 95 km/h su una ruota da 2105 mm (2105 / 80 × 3,6). Impulsi più ravvicinati sono fisicamente impossibili e vengono ignorati come rimbalzi, zone laterali del magnete o rimbalzi del contatto in apertura. Se per 3 secondi non arriva alcun impulso, la velocità viene considerata zero. Con la stessa struttura puoi misurare anche i giri di un motore o di una ruota: RPM = 60000 / tempo (ms). Per saperne di più sugli interrupt, consulta la guida interrupt con Arduino; per mostrare la velocità sul manubrio, abbina il codice a un display OLED.

Reed switch o sensore Hall?

Il secondo modo per rilevare un magnete è un sensore a effetto Hall. Il sensore Hall converte il campo magnetico in un segnale elettrico all'interno di un chip a semiconduttore; non ha parti in movimento ma ha bisogno di alimentazione per funzionare. La regola veloce: per un sensore di porta o finestra che funziona a lungo a batteria e scatta di rado, scegli il reed; per conteggi veloci e continui, come un motore, una ventola o un flussimetro che girano decine di volte al secondo, il sensore Hall è la scelta migliore.

CaratteristicaReed switchSensore Hall (A3144, US1881, 49E)
FunzionamentoContatto meccanico chiuso da un magneteSemiconduttore, converte il campo in segnale elettrico
AlimentazioneNon serve, non consuma energiaNecessaria (pochi mA)
Velocità di commutazioneCentinaia di volte al secondoFino a decine di migliaia di Hz
RimbalziSì (sotto 1 ms)No
DurataUsura meccanica, da 100 milioni a 1 miliardo di commutazioniNessuna parte in movimento, nessuna usura
Riconoscimento del poloNo, reagisce a entrambi i poliA seconda del modello: unipolare, bipolare o latch
Misura analogicaNo, solo aperto o chiusoI modelli lineari (49E) misurano l'intensità del campo
Commutazione di carichiPuò commutare direttamente piccoli carichi AC/DCSolo uscita di segnale
RobustezzaAmpolla di vetro sensibile a urti e piegatureContenitore in plastica, resistente alle vibrazioni

Avviso di porta aperta con ESP32 (Telegram)

Grazie al Wi-Fi dell'ESP32, il sensore porta può inviare un messaggio al tuo telefono nell'istante in cui la porta si apre. Per farlo devi creare un bot con BotFather su Telegram, ottenere il suo token e il tuo chat ID e installare le librerie UniversalTelegramBot e ArduinoJson nell'Arduino IDE; spieghiamo questi passaggi in dettaglio nell'articolo bot Telegram con ESP32. Collega un piedino del reed al GPIO 27 e l'altro a GND. Il codice invia un messaggio quando la porta si apre e si chiude, te lo ricorda se resta aperta più di 5 minuti e, se in quel momento il Wi-Fi è assente, riprova dopo 10 secondi.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WiFiClientSecure.h>
3#include <UniversalTelegramBot.h>
4#include <ArduinoJson.h>
5
6const char* WIFI_SSID = "AgAdi";          // Wi-Fi adın (yalnız 2,4 GHz) / your Wi-Fi name (2.4 GHz only)
7const char* WIFI_PASS = "Sifre123";       // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"   // BotFather'ın verdiği token / token from BotFather
9#define CHAT_ID   "123456789"             // bildirimin gideceği ID / the ID that receives alerts
10
11const int REED_PIN = 27;                  // reed: GPIO 27 ile GND arası / reed between GPIO 27 and GND
12const int LED_PIN  = 2;                   // çoğu DevKit'te dahili LED / onboard LED on most DevKits
13const unsigned long STABLE_MS = 100;      // değişim 100 ms sürmeli / a change must last 100 ms
14const unsigned long REMIND_MS = 300000;   // 5 dk açık kalırsa hatırlat / remind after 5 min open
15const unsigned long RETRY_MS  = 10000;    // gönderilemeyen mesajı 10 sn sonra dene / retry a failed message after 10 s
16
17WiFiClientSecure client;                  // şifreli (HTTPS) bağlantı / encrypted (HTTPS) connection
18UniversalTelegramBot bot(BOT_TOKEN, client);
19
20bool doorOpen = false;                    // onaylanmış kapı durumu / confirmed door state
21bool lastRaw = false;                     // son ham okuma / last raw reading
22unsigned long lastChange = 0;
23unsigned long openedAt = 0;
24bool reminded = false;
25String pending = "";                      // gönderilmeyi bekleyen mesaj / message waiting to be sent
26unsigned long lastTry = 0;
27
28void notify(const String& text) {
29  Serial.println(text);
30  if (WiFi.status() == WL_CONNECTED && bot.sendMessage(CHAT_ID, text)) {
31    pending = "";                         // gönderildi / sent
32  } else {
33    pending = text;                       // Wi-Fi yoksa sonra dene / no Wi-Fi: try again later
34    lastTry = millis();
35  }
36}
37
38void setup() {
39  Serial.begin(115200);
40  pinMode(REED_PIN, INPUT_PULLUP);        // dahili pull-up; GPIO 34-39'da yoktur / internal pull-up; GPIO 34-39 have none
41  pinMode(LED_PIN, OUTPUT);
42
43  WiFi.mode(WIFI_STA);
44  WiFi.begin(WIFI_SSID, WIFI_PASS);
45  Serial.print("Wi-Fi'ye baglaniyor / connecting to Wi-Fi");
46  while (WiFi.status() != WL_CONNECTED) {
47    delay(500);
48    Serial.print(".");
49  }
50  Serial.println();
51  Serial.println(WiFi.localIP());
52  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);   // api.telegram.org kök sertifikası / root certificate of api.telegram.org
53
54  doorOpen = (digitalRead(REED_PIN) == HIGH);    // HIGH = mıknatıs uzak = kapı açık / HIGH = magnet away = door open
55  lastRaw = doorOpen;
56  openedAt = millis();
57  digitalWrite(LED_PIN, doorOpen ? HIGH : LOW);
58  notify(String("Kapı sensörü hazır, kapı ") + (doorOpen ? "AÇIK" : "KAPALI") + " / door sensor ready");
59}
60
61void loop() {
62  unsigned long now = millis();
63  bool raw = (digitalRead(REED_PIN) == HIGH);
64
65  if (raw != lastRaw) {                   // ham değer değişti / raw value changed
66    lastRaw = raw;
67    lastChange = now;
68  }
69
70  if (raw != doorOpen && now - lastChange >= STABLE_MS) {   // kararlı değişim / stable change
71    doorOpen = raw;
72    digitalWrite(LED_PIN, doorOpen ? HIGH : LOW);
73    if (doorOpen) {
74      openedAt = now;
75      reminded = false;
76      notify("Kapı AÇILDI! / door OPENED!");
77    } else {
78      unsigned long sec = (now - openedAt) / 1000;
79      notify("Kapı kapandı / door closed (" + String(sec) + " sn)");
80    }
81  }
82
83  if (doorOpen && !reminded && now - openedAt > REMIND_MS) {   // açık unutuldu / left open
84    reminded = true;
85    notify("Kapı 5 dakikadır açık! / door open for 5 minutes!");
86  }
87
88  if (pending.length() > 0 && now - lastTry > RETRY_MS) {      // bekleyen mesajı yeniden dene / retry the pending message
89    String msg = pending;
90    notify(msg);
91  }
92}

Inviare un messaggio a Telegram può richiedere 1–2 secondi, durante i quali il ciclo resta in attesa; ma poiché la macchina a stati rilegge il pin al termine dell'invio, l'ultimo stato della porta non va mai perso. Se vuoi alimentare il sensore a batteria, metti l'ESP32 in deep sleep e usa esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, 1) per risvegliarlo quando la porta si apre e il pin va a HIGH. Se prima di dormire imposti il livello di risveglio all'opposto dello stato attuale del pin, la scheda si risveglia sia all'apertura sia alla chiusura. In questo caso considera anche la corrente che passa nella pull-up: a porta chiusa il reed è chiuso e in una resistenza da 10 kΩ scorrono di continuo 3,3 V / 10 kΩ = 330 µA; con 100 kΩ la corrente scende a 33 µA. In deep sleep è più sicuro usare una resistenza esterna invece della pull-up interna. Puoi stimare l'autonomia con il calcolatore di durata della batteria.

Reed switch con Raspberry Pi Pico e MicroPython

Leggere un reed switch sul Raspberry Pi Pico richiede solo poche righe di MicroPython. Collega il reed tra GP15 e GND, il polo positivo del buzzer attivo a GP14 e quello negativo a GND. Poiché il Pico lavora a 3,3 V, se usi un modulo alimentalo sempre dal pin 3V3(OUT); se lo alimenti a 5 V, l'uscita DO sale a 5 V e può danneggiare l'ingresso del Pico. La pull-up interna del Pico è di circa 50–80 kΩ ed è sufficiente per cavi corti.

MicroPython
1from machine import Pin
2import time
3
4reed = Pin(15, Pin.IN, Pin.PULL_UP)   # reed: GP15 ile GND arası / reed between GP15 and GND
5buzzer = Pin(14, Pin.OUT)             # aktif buzzer artı ucu / active buzzer positive leg
6led = Pin("LED", Pin.OUT)             # dahili LED (Pico ve Pico W) / onboard LED (Pico and Pico W)
7
8STABLE_MS = 50                        # debounce süresi / debounce time
9door_open = reed.value() == 1         # 1 = mıknatıs uzak = kapı açık / 1 = magnet away = door open
10last_raw = door_open
11last_change = time.ticks_ms()
12open_count = 0
13led.value(door_open)
14
15while True:
16    raw = reed.value() == 1
17    now = time.ticks_ms()
18    if raw != last_raw:                       # ham değer değişti / raw value changed
19        last_raw = raw
20        last_change = now
21    if raw != door_open and time.ticks_diff(now, last_change) >= STABLE_MS:
22        door_open = raw                       # 50 ms kararlı: gerçek değişim / stable for 50 ms: real change
23        led.value(door_open)
24        if door_open:
25            open_count += 1
26            print("Kapi acildi / door opened:", open_count)
27            buzzer.on()
28            time.sleep_ms(100)                # kısa bip / short beep
29            buzzer.off()
30        else:
31            print("Kapi kapandi / door closed")
32    time.sleep_ms(5)

Il codice realizza la stessa logica antirimbalzo di Arduino con time.ticks_ms() e time.ticks_diff(); ticks_diff restituisce la differenza corretta anche quando il contatore va in overflow. Per gli impulsi da non perdere, come in un tachimetro, puoi usare un interrupt con reed.irq(trigger=Pin.IRQ_FALLING, handler=...). Se hai un Pico W, aggiungi a questo codice l'esempio per Pico W dell'articolo sul bot Telegram per inviare lo stesso evento al telefono via Wi-Fi. Se usi il Pico per la prima volta, parti dalla guida che cos'è il Raspberry Pi Pico.

Idee di progetti con il reed switch

  • Sensore porte e finestre wireless: Segnala al telefono ogni apertura in casa con un ESP32 oppure inviala a Home Assistant tramite MQTT.
  • Avviso porta del frigorifero: Un bip intermittente quando la porta resta aperta più di 30 secondi.
  • Contachilometri per bici: Mostra su un display velocità istantanea, distanza totale e velocità media.
  • Anemometro e pluviometro: Nelle stazioni meteo l'anemometro a coppette genera un impulso reed per giro e il pluviometro a vaschetta basculante uno per ogni ribaltamento.
  • Interruttore a galleggiante: Il magnete nel galleggiante apre e chiude il reed nello stelo per segnalare che il serbatoio è pieno; dettagli nell'articolo sensore di livello dell'acqua.
  • Serratura segreta per cassetto: Costruisci una serratura a solenoide che si apre solo avvicinando un magnete nel punto giusto.
  • Avviso cassetta della posta: Un reed sullo sportello risveglia l'ESP32 dal deep sleep quando arriva la posta.

Errori comuni e soluzioni

  • Il pin legge valori casuali: Manca la pull-up. Imposta pinMode su INPUT_PULLUP oppure aggiungi una resistenza di pull-up esterna da 10 kΩ.
  • La logica è invertita: Con la pull-up si legge LOW quando c'è il magnete; forse il tuo codice si aspetta HIGH, oppure il tuo sensore è di tipo NC. Controlla con il multimetro.
  • Più conteggi per una sola apertura: Manca l'antirimbalzo oppure il magnete passa per le zone di chiusura laterali. Aggiungi un tempo di stabilità e allinea il magnete parallelo all'ampolla.
  • Il reed non si chiude mai: Il magnete è debole, la distanza è eccessiva, il magnete è perpendicolare al centro dell'ampolla oppure una porta in acciaio assorbe il campo. Usa un magnete al neodimio più potente e uno spessore in plastica.
  • Il reed resta sempre chiuso: I contatti potrebbero essersi saldati per una corrente eccessiva o un carico capacitivo. Non pilotare mai direttamente con un reed un motore, una lampada o la bobina di un relè; commuta i carichi con un modulo relè o un transistor.
  • L'ampolla di vetro si è incrinata: I piedini sono stati piegati troppo vicino al corpo. Tieni il piedino con una pinza, piegalo ad almeno 2–3 mm dal vetro e salda velocemente.
  • Falsi allarmi con cavi lunghi: La pull-up interna è troppo debole. Usa una pull-up esterna da 4,7–10 kΩ, un condensatore da 100 nF sul pin e un cavo a coppia intrecciata.
Prima di montare il reed switch nel circuito, provalo con la funzione di continuità (bip) del multimetro: con i puntali sui due piedini deve suonare quando avvicini il magnete e smettere quando lo allontani. Questo test di dieci secondi ti dice con certezza sia che il reed funziona sia se è NA o NC; è anche il modo più semplice per misurare con un righello la distanza di intervento del magnete.

Il reed switch è un sensore economico ed estremamente affidabile che rileva un magnete senza consumare energia; con il giusto orientamento del magnete, una resistenza di pull-up e poche righe di antirimbalzo funziona senza problemi per anni. Nell'app BlueGrays trovi i progetti Lettura del reed switch e Sensore porta con reed switch, oltre ad altri come l'allarme di movimento con ESP32 e il sistema di allarme con notifiche Telegram, con schemi e codice passo passo.

Domande frequenti

Come funziona un reed switch?

Un reed switch è formato da due lamelle di ferro-nichel dentro un'ampolla di vetro. Quando si avvicina un magnete, le lamelle si magnetizzano, si attraggono e il contatto si chiude; quando il magnete si allontana, la loro elasticità le separa. Non consuma energia e su Arduino si legge come un pulsante.

Il reed switch è normalmente aperto o chiuso?

I reed switch più comuni sono NA (normalmente aperti, Forma A): aperti senza magnete e chiusi con il magnete vicino. Esistono anche modelli NC (Forma B) e in scambio a tre piedini (Forma C). Nei contatti magnetici per allarmi, invece, l'etichetta "NC" indica che il circuito è chiuso a porta chiusa con il magnete accanto, quindi la cosa più sicura è verificarlo con il multimetro.

A che distanza rileva un reed switch?

Dipende dalla forza del magnete e dalla sensibilità del reed. Un piccolo magnete al neodimio attiva di solito i reed comuni a 1–2 cm, e i sensori porta in commercio lavorano a 15–25 mm; con i magneti in ferrite la distanza si riduce circa della metà. Tenere il magnete parallelo all'ampolla e lontano da superfici in acciaio aumenta la distanza.

Il reed switch ha bisogno di una resistenza?

L'ingresso di Arduino ha bisogno di una resistenza di pull-up o pull-down; altrimenti, con il contatto aperto, il pin resta flottante e legge valori casuali. Poiché Arduino, ESP32 e Pico hanno pull-up interne attivabili con INPUT_PULLUP o Pin.PULL_UP, di solito non serve una resistenza esterna. Con cavi lunghi una resistenza esterna da 4,7–10 kΩ dà risultati più stabili.

Che differenza c'è tra reed switch e sensore Hall?

Il reed è un contatto meccanico: non richiede alimentazione e può commutare direttamente piccoli carichi, ma ha rimbalzi e la sua ampolla di vetro è fragile. Il sensore Hall è un semiconduttore: va alimentato, non ha rimbalzi ed è molto più veloce. Per i sensori porta a batteria si preferisce il reed, per contare giri veloci il sensore Hall.

Un reed switch può accendere una lampada a 230 V?

I piccoli reed in vetro reggono di solito al massimo 10 W di potenza commutabile, quindi commutare direttamente una lampada o un motore a 230 V salda i contatti ed è pericoloso. Collega il reed ad Arduino solo come segnale, controlla il carico di rete con un modulo relè e rispetta sempre le norme di sicurezza quando lavori con i 230 V.

Vedi tutti i progetti
Lettura di un sensore reed
#37Principiante

Lettura di un sensore reed

Ti sei mai chiesto come funziona l'interruttore magnetico degli allarmi per porte e finestre? Quando una calamita si avvicina al modulo relè reed, il minuscolo interruttore al suo interno si chiude; l

4.4(21)
27
Sensore porta con contatto reed
#38Principiante
Premium

Sensore porta con contatto reed

Capisci se la tua porta è aperta o chiusa guardando una luce. Metti un piccolo magnete sulla porta e sul telaio un interruttore che sente i magneti; a porta chiusa stanno vicini e si accende il LED ve

4.7(34)
44
Accendere un LED con un pulsante (Push)
#9Principiante

Accendere un LED con un pulsante (Push)

Come un campanello: la luce resta accesa finché premi e si spegne quando lasci. L'Arduino ascolta il pulsante di continuo; mentre è premuto accende il LED, e appena togli il dito lo spegne. Con questo

4.8(113)
229
Controllo LED ESP32 con pulsante (Push)
#104Principiante

Controllo LED ESP32 con pulsante (Push)

Il LED si accende quando il pulsante viene premuto e si spegne quando viene rilasciato. Mostra come vengono utilizzati il pin di ingresso digitale dell'ESP32 e la resistenza di pull-up interna. Grazie alla modalità INPUT_PULLUP, non è necessaria alcuna resistenza esterna.

4.6(36)
55
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
Raspberry Pi Pico Pulsante Debounce: IRQ vs Software Polling
#159Intermedio
Premium

Raspberry Pi Pico Pulsante Debounce: IRQ vs Software Polling

Una pressione e il codice conta 3-4? È contact bounce! Confronta 2 metodi di conteggio in Serial: polling RAW (cattura bounce, conta male) vs IRQ + software debounce (preciso). Impara fisica del bounce, software debounce, Pin.irq() interrupt, IRQ_FALLING trigger, ISR handler, sicurezza delle variabili globali ISR.

0.0(0)
12
Sistema di sicurezza laser
#23Avanzato
Premium

Sistema di sicurezza laser

Come nelle scene di furti con i laser dei film: un raggio laser colpisce un sensore di luce, e appena qualcuno ci passa in mezzo e interrompe il raggio, si accende il LED rosso e il buzzer comincia a

4.8(60)
77