Capteur ILS (reed) Arduino : contact de porte, alarme, compteur
Comment fonctionne un ILS (interrupteur reed) et le brancher sur Arduino : NO/NF, distance de l'aimant, pull-up, anti-rebond, alarme de porte, ESP32 et Pico.
Un ILS (interrupteur à lame souple, ou reed switch) est un capteur tout simple qui ferme un circuit lorsqu'un aimant met en contact deux fines lames métalliques enfermées dans une ampoule de verre ; lui-même ne consomme aucune énergie. Sur un Arduino, il se lit exactement comme un bouton-poussoir : quand l'aimant est proche, le contact se ferme, quand il s'éloigne, il s'ouvre. Cette petite ampoule de verre se cache dans les détecteurs d'ouverture de portes et de fenêtres, les compteurs de vélo, les interrupteurs à flotteur et les anémomètres.
Dans ce guide, tu vas découvrir pas à pas ce qu'il y a dans un ILS, les types NO et NF, à quelle distance et dans quelle orientation l'aimant fonctionne le mieux et comment le brancher sur un Arduino avec une résistance de tirage (pull-up). Ensuite, tu élimineras les rebonds du contact par logiciel, tu construiras une alarme de porte ouverte et un compteur de vitesse pour vélo, tu enverras une notification « porte ouverte » sur ton téléphone avec un ESP32 et tu feras fonctionner le même montage sur un Raspberry Pi Pico en MicroPython. Les dernières parties comparent l'ILS à un capteur à effet Hall et regroupent les erreurs les plus fréquentes.

Qu'est-ce qu'un ILS (interrupteur reed) et comment fonctionne-t-il ?
Le cœur d'un ILS est une petite ampoule de verre remplie d'un gaz inerte comme l'azote, ou sous vide. Deux lames souples en alliage fer-nickel y entrent par chaque extrémité et se chevauchent au centre avec un très petit écart ; le mot anglais « reed » (anche) désigne ces lames. Leurs extrémités sont recouvertes d'un métal dur comme le rhodium ou le ruthénium, ce qui garde une faible résistance de contact et limite l'usure. Quand un aimant approche, les deux lames s'aimantent, des pôles opposés apparaissent aux extrémités qui se chevauchent et les lames s'attirent jusqu'à se toucher. Quand l'aimant s'éloigne, l'élasticité des lames sépare à nouveau les contacts. Comme le verre protège les contacts de la poussière, de l'humidité et de l'oxydation, un ILS peut commuter des centaines de millions de fois sous faible courant.
On l'appelle souvent « relais reed », mais techniquement l'ampoule de verre seule est un interrupteur reed, c'est-à-dire un ILS. Un vrai relais reed est la même ampoule entourée d'une bobine ; c'est alors le courant dans la bobine, et non un aimant, qui ferme les contacts. Cet article traite de l'interrupteur actionné par aimant et des modules capteurs qui l'intègrent. Son plus grand avantage est qu'il ne consomme aucune énergie : seul le courant de ton propre circuit le traverse, ce qui le rend idéal pour les appareils qui fonctionnent des mois sur piles.
Caractéristiques techniques d'un ILS
| Caractéristique | Valeur typique (petit ILS en verre) |
|---|---|
| Type de contact | Forme A (NO, normalement ouvert), le plus courant |
| Ampoule de verre | Environ 2 mm de diamètre, 10–15 mm de long |
| Pouvoir de coupure | Jusqu'à 10 W |
| Tension commutée | Jusqu'à 100–200 V DC |
| Courant commuté | Environ 0,5 A |
| Résistance de contact | Moins de 0,1 Ω |
| Temps de fermeture | Moins de 1 ms (rebonds compris) |
| Sensibilité | 10–40 AT (ampères-tours) |
| Durée de vie | 100 millions à 1 milliard de manœuvres sous faible courant |
| Consommation propre | Aucune (composant passif) |
La sensibilité s'exprime en AT (ampères-tours) : le courant multiplié par le nombre de spires nécessaires pour fermer l'ILS dans une bobine d'essai normalisée. Plus la valeur est faible, plus l'aimant peut être faible, donc plus la distance de déclenchement est grande. Il existe aussi une hystérésis : le champ nécessaire pour fermer les contacts (enclenchement) est plus fort que celui qui suffit à les maintenir fermés. Par exemple, un ILS que l'aimant ferme à 15 mm peut ne se rouvrir qu'aux alentours de 20 mm. Cet écart limite les ouvertures et fermetures dues aux petites vibrations, mais ton montage doit faire en sorte que l'aimant s'éloigne aussi au-delà de la distance de relâchement.
Types NO, NF et inverseur (forme A, B et C)
Les ILS existent en trois configurations de contact. Les mentions NO (normalement ouvert) et NF (normalement fermé, NC en anglais) décrivent toujours l'état du contact sans aimant.
| Type | Sans aimant | Aimant proche | Pattes | Utilisation |
|---|---|---|---|---|
| Forme A (NO) | Ouvert | Fermé | 2 | Détecteurs d'ouverture, compteurs de vitesse, la plupart des modules |
| Forme B (NF) | Fermé | Ouvert | 2 | Applications qui doivent fermer le circuit quand l'aimant s'éloigne |
| Forme C (inverseur) | COM–NF fermé | COM–NO fermé | 3 | Montages qui ont besoin d'une sortie ouverte et d'une sortie fermée |
Déclenchement par aimant : distance, orientation et sensibilité
Le meilleur moyen de déclencher un ILS est un petit aimant néodyme. Un disque néodyme de 10×3 mm actionne généralement un ILS courant à 10–20 mm ; un aimant en ferrite noir de même taille divise cette distance à peu près par deux. Les détecteurs d'ouverture du commerce fonctionnent typiquement à 15–25 mm. La distance ne dépend pas seulement de la force de l'aimant mais aussi de son orientation : si l'axe nord-sud de l'aimant est parallèle à l'ampoule et qu'il s'approche de son milieu, tu obtiens une seule fermeture, bien nette. Si l'aimant est perpendiculaire à l'ampoule, il peut ne pas déclencher du tout pile au milieu et déclencher en deux points proches des extrémités. Un aimant parallèle qu'on fait glisser le long de l'ampoule crée en outre de petites zones de fermeture supplémentaires de part et d'autre de la zone principale. Quand l'aimant passe devant l'ILS, le contact peut donc se fermer et s'ouvrir deux ou trois fois ; c'est la cause la plus fréquente des projets de comptage qui comptent un tour comme deux ou trois.

- La polarité n'a pas d'importance : Un ILS réagit de la même façon au pôle nord et au pôle sud ; retourner l'aimant ne change rien.
- Aligne l'aimant sur le milieu de l'ampoule : Sur un détecteur de porte, l'aimant et le boîtier de l'ILS doivent être côte à côte et parallèles, avec un écart aussi faible que possible.
- Les portes en acier réduisent la distance : Le fer concentre le champ de l'aimant en lui-même. Surélève le capteur et l'aimant avec une cale en plastique de 5–10 mm ou utilise un aimant plus puissant.
- Mesure d'abord la distance : Moniteur série ouvert, approche et éloigne lentement l'aimant. Porte fermée, l'aimant doit être largement à l'intérieur de la distance d'enclenchement ; porte entrouverte, il doit être au-delà de la distance de relâchement.
- Éloigne-le des champs forts : Haut-parleurs, moteurs et autres aimants peuvent fermer l'ILS sans le vouloir ; ne le monte pas juste à côté.
Branchement d'un ILS sur Arduino : pourquoi une résistance de pull-up est-elle indispensable ?
Comme un ILS se comporte comme un bouton-poussoir, il ne produit aucune tension tout seul ; il se contente de relier ou de séparer ses deux pattes. Contact ouvert, la broche n'est reliée à rien (elle est « flottante ») et tu lis des valeurs HIGH et LOW aléatoires à cause du bruit. La solution est une résistance de tirage (pull-up) : la broche est tirée vers 5 V (ou 3,3 V) par une résistance et l'ILS est branché entre la broche et GND. Sans aimant, la broche lit HIGH ; quand l'aimant ferme le contact, elle est reliée directement à GND et lit LOW. L'Arduino Uno possède une résistance de pull-up interne de 20–50 kΩ : il suffit d'écrire pinMode(pin, INPUT_PULLUP), aucune résistance externe n'est nécessaire. Tu trouveras le détail de cette logique dans le guide brancher un bouton sur Arduino.
| Branchement | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Patte 1 de l'ILS (ILS seul) | D2 | GPIO 27 | GP15 (broche physique 20) |
| Patte 2 de l'ILS (ILS seul) | GND | GND | GND |
| Pull-up | Interne (INPUT_PULLUP) | Interne (INPUT_PULLUP) | Interne (Pin.PULL_UP) |
| VCC du module | 5V | 3V3 | 3V3(OUT) (broche physique 36) |
| GND du module | GND | GND | GND |
| DO du module | D2 | GPIO 27 | GP15 |
| LED d'état | D13 (LED de la carte) | GPIO 2 (LED de la carte) | LED intégrée |
| Buzzer actif (+) | D8 | Non utilisé | GP14 |
Premier montage pas à pas : détecter l'aimant
- Relie une patte de l'ILS à la broche D2 de l'Arduino et l'autre à GND. Un ILS seul n'a pas de polarité, le sens des pattes n'a pas d'importance.
- Si tu utilises un module, relie VCC à 5V, GND à GND et la sortie DO à D2.
- Téléverse le code ci-dessous et ouvre le moniteur série à 9600 bauds.
- Approche lentement l'aimant, parallèle à l'ampoule de verre ; la LED de la carte doit s'allumer et « magnet detected » doit s'afficher.
- En éloignant l'aimant, mesure à la règle la distance à laquelle la LED s'éteint ; c'est ta distance de relâchement.
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}Le seul point d'attention dans le code est la logique inversée : comme tu utilises INPUT_PULLUP, tu lis LOW quand l'aimant est présent et HIGH quand il ne l'est pas. Sur les modules à 3 broches avec LM393, la sortie passe généralement aussi à LOW quand l'aimant approche et la LED DO de la carte s'allume ; comme cela peut varier d'un modèle à l'autre, vérifie d'abord ton module dans le moniteur série. Le potentiomètre du module règle le seuil du comparateur ; l'ILS fonctionnant déjà en tout ou rien, il influe peu sur la distance de détection et la position centrale suffit en général. Les mini-modules comme le KY-021 n'ont pas de comparateur ; la carte ne porte que l'ILS et une résistance de 10 kΩ.
Anti-rebond : rebonds du contact et vibrations
Comme tout contact mécanique, un ILS peut rebondir quelques fois en se fermant. Sur un ILS, ce rebond est très court, généralement moins de 1 ms, mais ce n'est pas le vrai problème. Si l'aimant bouge lentement à la limite de la distance d'enclenchement, ou si la porte tremble avec le vent, le contact peut s'ouvrir et se fermer de nombreuses fois en une seconde. Un système qui envoie une notification à l'ouverture de la porte peut ainsi envoyer cinq messages pour une seule ouverture. La solution consiste à attendre que l'état reste stable pendant un certain temps au lieu d'accepter chaque changement immédiatement. Pour un détecteur de porte, 50–100 ms suffisent ; pour un compteur de vitesse, utiliser comme temps de verrouillage l'intervalle le plus court physiquement possible entre deux impulsions donne de bons résultats.
Si tu préfères une solution matérielle, tu peux placer un condensateur de 100 nF entre la broche et GND. Avec une pull-up de 10 kΩ, on obtient une constante de temps τ = R × C = 10 kΩ × 100 nF = 1 ms qui lisse les rebonds très courts. Tu peux essayer d'autres couples résistance-condensateur avec le calculateur de constante de temps RC. Avec la pull-up interne, la résistance est de 20–50 kΩ, le temps passe donc à 2–5 ms. Sur les détecteurs de porte avec plusieurs mètres de câble, une pull-up externe de 4,7–10 kΩ associée à ce condensateur protège aussi contre les parasites.
Détecteur d'ouverture de porte et de fenêtre : projet d'alarme
Le projet ILS le plus courant est le détecteur d'ouverture de porte. Fixe l'aimant sur l'ouvrant de la porte et l'ILS sur le dormant ; porte fermée, ils sont côte à côte, le contact est fermé et la broche lit LOW. Quand la porte s'ouvre, l'aimant s'éloigne et la broche passe à HIGH. Cette disposition a un effet secondaire intéressant : si quelqu'un coupe le câble du capteur, la broche passe aussi à HIGH et le système l'interprète comme « porte ouverte ». C'est pour cela que les alarmes utilisent des boucles fermées. Le code ci-dessous compte chaque ouverture, mesure combien de temps la porte reste ouverte et fait biper le buzzer par intermittence si elle reste ouverte plus de 30 secondes ; idéal pour un réfrigérateur ou un congélateur.
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}Comme le code n'utilise pas delay(), la boucle vérifie la broche en permanence et ne rate aucune ouverture ; nous expliquons cette technique en détail dans l'article millis ou delay. Chaque fois que la lecture brute change, le temps lastChange est remis à jour, et l'état doorOpen ne change que si la valeur reste identique pendant 50 ms. La partie buzzer divise millis() par 250 pour l'allumer et l'éteindre tous les quarts de seconde. Pour en faire une vraie alarme, tu peux l'armer et la désarmer avec un clavier matriciel et un code, et ajouter un détecteur de mouvement PIR dans la pièce. Pour un montage plus complet, jette un œil à l'article système d'alarme Arduino.
Compteur de vitesse pour vélo : compter les tours avec un ILS
La plupart des compteurs de vélo se composent d'un ILS et d'un petit aimant fixé sur un rayon. À chaque tour de roue, l'aimant passe une fois devant l'ILS fixé sur la fourche et produit une impulsion. En mesurant le temps entre deux impulsions, tu obtiens la vitesse ; en comptant les impulsions, la distance : vitesse (km/h) = circonférence (mm) / temps (ms) × 3,6. Ici, des mm/ms valent exactement des m/s, et la multiplication par 3,6 convertit en km/h. Par exemple, sur une roue 700x25C de 2105 mm de circonférence, 253 ms entre deux impulsions donnent 2105 / 253 × 3,6 ≈ 30 km/h. La façon la plus précise de mesurer la circonférence est de faire rouler la roue d'un tour exact, valve en bas, puis de mesurer la distance entre les deux marques au sol.
| Taille de pneu | Circonférence approximative | Durée d'un tour à 30 km/h |
|---|---|---|
| 20x1.75 (BMX, vélo enfant) | 1515 mm | 182 ms |
| 26x2.1 (VTT) | 2068 mm | 248 ms |
| 29x2.1 (VTT) | 2288 mm | 275 ms |
| 700x25C (vélo de route) | 2105 mm | 253 ms |
| 700x28C (ville, 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}Comme l'impulsion est captée avec attachInterrupt, aucun tour n'est perdu, même si loop() est très occupée ; sur l'Arduino Uno, seules les broches D2 et D3 offrent ce type d'interruption. La valeur LOCKOUT_MS est très importante : 80 ms correspondent à une vitesse maximale d'environ 95 km/h sur une roue de 2105 mm (2105 / 80 × 3,6). Des impulsions plus rapprochées sont physiquement impossibles et sont ignorées comme rebonds, zones latérales de l'aimant ou rebond du contact à l'ouverture. Si aucune impulsion n'arrive pendant 3 secondes, la vitesse est considérée comme nulle. Avec la même structure, tu peux aussi mesurer la vitesse de rotation d'un moteur ou d'une roue : tr/min = 60000 / temps (ms). Pour en savoir plus sur les interruptions, consulte le guide interruptions Arduino ; pour afficher la vitesse sur le guidon, associe le code à un écran OLED.
ILS ou capteur à effet Hall ?
La deuxième façon de détecter un aimant est un capteur à effet Hall. Il convertit le champ magnétique en signal électrique dans une puce semi-conductrice ; il n'a aucune pièce mobile mais a besoin d'une alimentation pour fonctionner. La règle rapide : pour un détecteur de porte ou de fenêtre qui fonctionnera longtemps sur piles et se déclenche rarement, choisis un ILS ; pour des comptages rapides et continus, comme un moteur, un ventilateur ou un débitmètre d'eau qui tournent des dizaines de fois par seconde, le capteur à effet Hall est le meilleur choix.
| Caractéristique | ILS (interrupteur reed) | Capteur Hall (A3144, US1881, 49E) |
|---|---|---|
| Principe | Contact mécanique fermé par un aimant | Semi-conducteur, convertit le champ en signal électrique |
| Alimentation | Inutile, ne consomme rien | Nécessaire (quelques mA) |
| Vitesse de commutation | Des centaines de fois par seconde | Jusqu'à des dizaines de milliers de Hz |
| Rebonds | Oui (moins de 1 ms) | Non |
| Durée de vie | Usure mécanique, 100 millions à 1 milliard de manœuvres | Aucune pièce mobile, pas d'usure |
| Détection du pôle | Non, réagit aux deux pôles | Selon le modèle : unipolaire, bipolaire ou à verrouillage (latch) |
| Mesure analogique | Non, seulement ouvert ou fermé | Les modèles linéaires (49E) mesurent l'intensité du champ |
| Commutation de charges | Peut commuter directement de petites charges AC/DC | Sortie de signal uniquement |
| Robustesse | Ampoule en verre sensible aux chocs et à la flexion | Boîtier plastique, résistant aux vibrations |
Notification de porte ouverte avec l'ESP32 (Telegram)
Grâce au Wi-Fi de l'ESP32, le détecteur de porte peut envoyer un message sur ton téléphone dès que la porte s'ouvre. Pour cela, tu dois créer un bot avec BotFather dans Telegram, récupérer son jeton (token) et ton propre chat ID, puis installer les bibliothèques UniversalTelegramBot et ArduinoJson dans l'IDE Arduino ; nous détaillons ces étapes dans l'article bot Telegram ESP32. Relie une patte de l'ILS au GPIO 27 et l'autre à GND. Le code envoie un message à l'ouverture et à la fermeture de la porte, te le rappelle si elle reste ouverte plus de 5 minutes et, si le Wi-Fi est coupé à ce moment-là, réessaie 10 secondes plus tard.
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}L'envoi d'un message à Telegram peut prendre 1–2 secondes, pendant lesquelles la boucle attend ; mais comme la machine à états relit la broche une fois l'envoi terminé, le dernier état de la porte n'est jamais perdu. Si tu veux alimenter le capteur sur piles, mets l'ESP32 en sommeil profond et utilise esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, 1) pour qu'il se réveille quand la porte s'ouvre et que la broche passe à HIGH. Si, avant de dormir, tu règles le niveau de réveil sur l'inverse de l'état actuel de la broche, la carte se réveille à l'ouverture comme à la fermeture. Tiens compte aussi du courant qui traverse la pull-up : porte fermée, l'ILS est fermé et une résistance de 10 kΩ laisse passer en permanence 3,3 V / 10 kΩ = 330 µA ; avec 100 kΩ, le courant tombe à 33 µA. En sommeil profond, une résistance externe est plus sûre que la pull-up interne. Tu peux estimer l'autonomie avec le calculateur d'autonomie de batterie.
ILS avec Raspberry Pi Pico et MicroPython
Lire un ILS sur le Raspberry Pi Pico ne demande que quelques lignes de MicroPython. Branche l'ILS entre GP15 et GND, puis la borne positive du buzzer actif sur GP14 et la négative sur GND. Comme le Pico fonctionne en 3,3 V, alimente toujours un module depuis la broche 3V3(OUT) ; si tu l'alimentes en 5 V, la sortie DO monte à 5 V et peut endommager l'entrée du Pico. La pull-up interne du Pico est d'environ 50–80 kΩ, ce qui suffit pour des câbles courts.
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)Le code reprend la même logique anti-rebond que sur l'Arduino avec time.ticks_ms() et time.ticks_diff() ; ticks_diff donne la bonne différence même quand le compteur déborde. Pour les impulsions à ne pas manquer, comme sur un compteur de vélo, tu peux utiliser une interruption avec reed.irq(trigger=Pin.IRQ_FALLING, handler=...). Avec un Pico W, ajoute à ce code l'exemple Pico W de l'article sur le bot Telegram pour envoyer le même événement sur ton téléphone via le Wi-Fi. Si tu utilises le Pico pour la première fois, commence par le guide qu'est-ce que le Raspberry Pi Pico.
Idées de projets avec un ILS
- Détecteur d'ouverture sans fil : Signale chaque ouverture de porte ou de fenêtre sur ton téléphone avec un ESP32 ou envoie-la à Home Assistant via MQTT.
- Alerte de porte de réfrigérateur : Un bip intermittent quand la porte reste ouverte plus de 30 secondes.
- Compteur de vélo : Affiche la vitesse instantanée, la distance totale et la vitesse moyenne sur un écran.
- Anémomètre et pluviomètre : Dans les stations météo, l'anémomètre à coupelles produit une impulsion ILS par tour et le pluviomètre à auget basculant une impulsion par basculement.
- Interrupteur à flotteur : L'aimant du flotteur ouvre et ferme l'ILS de la tige pour signaler que la cuve est pleine ; détails dans l'article capteur de niveau d'eau.
- Serrure de tiroir secrète : Construis une serrure à solénoïde qui ne s'ouvre que si l'on place un aimant au bon endroit.
- Alerte boîte aux lettres : Un ILS sur le volet réveille l'ESP32 de son sommeil profond quand le courrier arrive.
Erreurs fréquentes et solutions
- La broche lit des valeurs aléatoires : Il manque la pull-up. Configure pinMode en INPUT_PULLUP ou ajoute une résistance de pull-up externe de 10 kΩ.
- La logique est inversée : Avec une pull-up, la broche lit LOW quand l'aimant est présent ; ton code attend peut-être HIGH, ou ton capteur est de type NF. Vérifie au multimètre.
- Plusieurs comptages pour une ouverture : Il n'y a pas d'anti-rebond, ou l'aimant passe par les zones de fermeture latérales. Ajoute un temps de stabilité et aligne l'aimant parallèlement à l'ampoule.
- L'ILS ne se ferme jamais : L'aimant est trop faible, la distance trop grande, l'aimant est perpendiculaire au milieu de l'ampoule ou une porte en acier absorbe le champ. Utilise un aimant néodyme plus puissant et une cale en plastique.
- L'ILS reste toujours fermé : Les contacts se sont peut-être soudés à cause d'un courant excessif ou d'une charge capacitive. Ne commande jamais directement un moteur, une lampe ou une bobine de relais avec un ILS ; commute les charges avec un module relais ou un transistor.
- L'ampoule de verre est fêlée : Les pattes ont été pliées trop près du corps. Tiens la patte avec une pince, plie-la à au moins 2–3 mm du verre et soude rapidement.
- Fausses alarmes avec de longs câbles : La pull-up interne est trop faible. Utilise une pull-up externe de 4,7–10 kΩ, un condensateur de 100 nF sur la broche et du câble à paire torsadée.
L'ILS est un capteur bon marché et extrêmement fiable qui détecte un aimant sans consommer d'énergie ; avec la bonne orientation d'aimant, une résistance de pull-up et quelques lignes d'anti-rebond, il fonctionne sans souci pendant des années. Dans l'application BlueGrays, tu trouveras les projets Lecture d'un ILS et Détecteur de porte à ILS, ainsi que d'autres comme l'alarme de mouvement ESP32 et le système d'alarme avec notifications Telegram, avec schémas et code pas à pas.
Questions fréquentes
Comment fonctionne un ILS (interrupteur reed) ?
Un ILS se compose de deux lames en fer-nickel enfermées dans une ampoule de verre. Quand un aimant approche, les lames s'aimantent, s'attirent et le contact se ferme ; quand l'aimant s'éloigne, leur élasticité les sépare. Il ne consomme aucune énergie et se lit sur Arduino comme un bouton-poussoir.
Un ILS est-il normalement ouvert ou fermé ?
Les ILS les plus courants sont NO (normalement ouverts, forme A) : ouverts sans aimant, fermés avec l'aimant. Il existe aussi des modèles NF (forme B) et des inverseurs à trois pattes (forme C). Sur les contacts de porte pour alarme, l'étiquette « NC » signifie en revanche que le circuit est fermé porte fermée, aimant à côté ; le plus sûr est donc de vérifier au multimètre.
À quelle distance un ILS détecte-t-il un aimant ?
Cela dépend de la force de l'aimant et de la sensibilité de l'ILS. Un petit aimant néodyme déclenche généralement un ILS courant à 1–2 cm, et les détecteurs de porte du commerce fonctionnent à 15–25 mm ; avec un aimant en ferrite, la distance est à peu près divisée par deux. Placer l'aimant parallèlement à l'ampoule et l'éloigner des surfaces en acier augmente la distance.
Faut-il une résistance avec un ILS ?
L'entrée de l'Arduino a besoin d'une résistance de pull-up ou de pull-down ; sinon, contact ouvert, la broche flotte et lit des valeurs aléatoires. Comme l'Arduino, l'ESP32 et le Pico ont des pull-up internes activables avec INPUT_PULLUP ou Pin.PULL_UP, une résistance externe est rarement nécessaire. Sur de longs câbles, une résistance externe de 4,7–10 kΩ donne des résultats plus stables.
Quelle différence entre un ILS et un capteur à effet Hall ?
L'ILS est un contact mécanique : il ne demande aucune alimentation et peut commuter directement de petites charges, mais il rebondit et son ampoule de verre est fragile. Le capteur Hall est un semi-conducteur : il doit être alimenté, ne rebondit pas et est bien plus rapide. On préfère l'ILS pour un détecteur de porte sur piles et le capteur Hall pour compter des tours rapides.
Un ILS peut-il commander une lampe 230 V ?
Les petits ILS en verre supportent en général au maximum 10 W de pouvoir de coupure ; commuter directement une lampe ou un moteur en 230 V soude les contacts et est dangereux. Branche l'ILS sur l'Arduino uniquement comme signal, commande la charge secteur avec un module relais et respecte toujours les règles de sécurité quand tu travailles avec le 230 V.
Projets à réaliser après cet article
Voir tous les projets
Lecture d'un interrupteur reed
Tu t'es déjà demandé comment marche l'interrupteur magnétique des alarmes de portes et de fenêtres ? Quand un aimant approche du module à relais reed, le minuscule interrupteur à l'intérieur se ferme

Capteur de porte avec interrupteur reed
Sache si ta porte est ouverte ou fermée rien qu'en regardant une lumière. Tu fixes un petit aimant sur la porte et sur le cadre un interrupteur qui sent les aimants ; porte fermée, ils sont côte à côt

Allumer une LED avec un bouton-poussoir (Push)
Comme une sonnette : la lumière reste allumée tant que tu appuies et s'éteint quand tu relâches. L'Arduino surveille le bouton en permanence ; tant qu'il est enfoncé la LED est allumée, et dès que tu

ESP32 Contrôle de LED avec bouton poussoir (Push)
La LED s'allume lorsque le bouton est enfoncé et s'éteint lorsqu'il est relâché. Montre comment la broche d'entrée numérique de l'ESP32 et la résistance pull-up interne sont utilisées. Grâce au mode INPUT_PULLUP, aucune résistance externe n'est nécessaire.

Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)
Un système d'alarme de sécurité intelligent qui active le buzzer et la LED lorsque le capteur PIR détecte un mouvement, tout en envoyant une notification instantanée au propriétaire via Telegram. Il intègre un délai d'attente de 30 secondes pour limiter la fréquence des alarmes répétées ; ce mécanisme ne vérifie pas la validité des détections du capteur PIR et n'élimine pas les faux déclenchements. Idéal pour la sécurité domestique, la surveillance de garage, d'entrepôts ou de bureaux. Avec l'ES

Raspberry Pi Pico Bouton Debounce : IRQ vs Software Polling
Une pression, le code compte 3-4 ? C'est le contact bounce ! Compare 2 méthodes de comptage dans Serial : RAW polling (attrape bounce, compte faux) vs IRQ + software debounce (précis). Apprends physique du bounce, software debounce, Pin.irq() interrupt, IRQ_FALLING trigger, ISR handlers, sécurité des variables globales ISR.

Système de sécurité laser
Comme dans les scènes de cambriolage au laser des films : un rayon laser éclaire un capteur de lumière, et dès que quelqu'un passe et coupe le rayon, la LED rouge s'allume et le buzzer se met à sonner
Autres articles
Application BlueGrays
Réalise ce montage pas à pas sur ton téléphone
Schéma, code et liste des composants sur un seul écran. Plus de 200 projets Arduino, ESP32 et Pico à réaliser.
Scanne avec ton téléphone
Pointe l’appareil photo vers le code : la boutique d’applications de ton téléphone s’ouvre.
ou ouvre la boutique

