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.

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
| Caratteristica | Valore tipico (piccolo reed in vetro) |
|---|---|
| Tipo di contatto | Forma A (NA, normalmente aperto), il più comune |
| Ampolla di vetro | Circa 2 mm di diametro, 10–15 mm di lunghezza |
| Potenza commutabile | Fino a 10 W |
| Tensione commutabile | Fino a 100–200 V DC |
| Corrente commutabile | Circa 0,5 A |
| Resistenza di contatto | Meno di 0,1 Ω |
| Tempo di intervento | Meno di 1 ms (rimbalzi inclusi) |
| Sensibilità | 10–40 AT (amperspire) |
| Durata | Da 100 milioni a 1 miliardo di commutazioni con corrente bassa |
| Consumo proprio | Nessuno (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.
| Tipo | Senza magnete | Magnete vicino | Piedini | Dove si usa? |
|---|---|---|---|---|
| Forma A (NA) | Aperto | Chiuso | 2 | Sensori porta, contatori di velocità, la maggior parte dei moduli |
| Forma B (NC) | Chiuso | Aperto | 2 | Applicazioni che devono chiudere il circuito quando il magnete si allontana |
| Forma C (in scambio) | COM–NC chiuso | COM–NO chiuso | 3 | Circuiti che richiedono sia un'uscita aperta sia una chiusa |
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.

- 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.
| Collegamento | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Piedino 1 del reed (reed singolo) | D2 | GPIO 27 | GP15 (pin fisico 20) |
| Piedino 2 del reed (reed singolo) | GND | GND | GND |
| Pull-up | Interna (INPUT_PULLUP) | Interna (INPUT_PULLUP) | Interna (Pin.PULL_UP) |
| VCC del modulo | 5V | 3V3 | 3V3(OUT) (pin fisico 36) |
| GND del modulo | GND | GND | GND |
| DO del modulo | D2 | GPIO 27 | GP15 |
| LED di stato | D13 (LED sulla scheda) | GPIO 2 (LED sulla scheda) | LED integrato |
| Buzzer attivo (+) | D8 | Non usato | GP14 |
Primo circuito passo passo: rilevare il magnete
- 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.
- Se usi un modulo, collega VCC a 5V, GND a GND e l'uscita DO a D2.
- Carica il codice qui sotto e apri il monitor seriale a 9600 baud.
- Avvicina lentamente il magnete tenendolo parallelo all'ampolla di vetro; il LED sulla scheda deve accendersi e sullo schermo deve comparire "magnet detected".
- Allontanando il magnete, misura con un righello a che distanza si spegne il LED; questa è la tua distanza di rilascio.
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.
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 pneumatico | Circonferenza approssimativa | Tempo per giro a 30 km/h |
|---|---|---|
| 20x1.75 (BMX, bici da bambino) | 1515 mm | 182 ms |
| 26x2.1 (mountain bike) | 2068 mm | 248 ms |
| 29x2.1 (mountain bike) | 2288 mm | 275 ms |
| 700x25C (bici da corsa) | 2105 mm | 253 ms |
| 700x28C (city bike, gravel) | 2136 mm | 256 ms |
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.
| Caratteristica | Reed switch | Sensore Hall (A3144, US1881, 49E) |
|---|---|---|
| Funzionamento | Contatto meccanico chiuso da un magnete | Semiconduttore, converte il campo in segnale elettrico |
| Alimentazione | Non serve, non consuma energia | Necessaria (pochi mA) |
| Velocità di commutazione | Centinaia di volte al secondo | Fino a decine di migliaia di Hz |
| Rimbalzi | Sì (sotto 1 ms) | No |
| Durata | Usura meccanica, da 100 milioni a 1 miliardo di commutazioni | Nessuna parte in movimento, nessuna usura |
| Riconoscimento del polo | No, reagisce a entrambi i poli | A seconda del modello: unipolare, bipolare o latch |
| Misura analogica | No, solo aperto o chiuso | I modelli lineari (49E) misurano l'intensità del campo |
| Commutazione di carichi | Può commutare direttamente piccoli carichi AC/DC | Solo uscita di segnale |
| Robustezza | Ampolla di vetro sensibile a urti e piegature | Contenitore 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.
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.
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.
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.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
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

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

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

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.

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

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.

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

