Chave reed com Arduino: sensor de porta, alarme e velocímetro
Como funciona uma chave reed e como ligá-la ao Arduino: tipos NA/NF, distância do ímã, pull-up e debounce, alarme de porta, velocímetro de bicicleta e códigos para ESP32 e Pico.
Uma chave reed (chave magnética) é um sensor simples que fecha um circuito quando um ímã faz duas lâminas finas de metal dentro de um tubo de vidro se tocarem, e ela mesma não consome energia nenhuma. No Arduino, ela é lida exatamente como um botão: os contatos se fecham quando há um ímã por perto e se abrem de novo quando ele se afasta. Esse pequeno tubo de vidro fica escondido dentro de alarmes de portas e janelas, ciclocomputadores, chaves de nível tipo boia e medidores de vento.
Neste guia você vai aprender passo a passo o que há dentro de uma chave reed, os tipos NA e NF, a que distância e em que posição o ímã funciona melhor e como ligá-la ao Arduino com um resistor de pull-up. Depois você vai eliminar o repique dos contatos por software, montar um alarme de porta aberta e um velocímetro de bicicleta, enviar uma notificação de “porta aberta” para o celular com um ESP32 e rodar o mesmo circuito em um Raspberry Pi Pico com MicroPython. As últimas seções comparam a chave reed com um sensor Hall e reúnem os erros mais comuns.

O que é uma chave reed e como ela funciona?
O coração de uma chave reed é um pequeno tubo de vidro cheio de um gás inerte, como o nitrogênio, ou com vácuo. Duas lâminas flexíveis de ferro-níquel entram pelas duas pontas e se sobrepõem no meio, com uma folga muito pequena; a palavra inglesa “reed” (palheta) se refere a essas lâminas. As pontas são revestidas com metais duros, como ródio ou rutênio, o que mantém baixa a resistência de contato e reduz o desgaste. Quando um ímã se aproxima, as duas lâminas se magnetizam, polos opostos se formam nas pontas sobrepostas e as lâminas se atraem até se tocarem. Quando o ímã se afasta, a força de mola das lâminas separa os contatos de novo. Como o vidro protege os contatos contra poeira, umidade e oxidação, as chaves reed podem operar centenas de milhões de vezes com corrente baixa.
Muitos vendedores chamam essa peça de “relé reed”, mas, tecnicamente, o tubo de vidro sozinho é uma chave reed. Um relé reed de verdade é o mesmo tubo de vidro com uma bobina enrolada em volta; nele, quem fecha os contatos é a corrente na bobina, e não um ímã. Este artigo trata da chave acionada por ímã e dos módulos sensores construídos em torno dela. Sua maior vantagem é que ela não consome energia: só passa por ela a corrente do seu próprio circuito, o que a torna ideal para dispositivos que funcionam meses com baterias.
Especificações da chave reed
| Característica | Valor típico (reed de vidro pequena) |
|---|---|
| Tipo de contato | Form A (NA, normalmente aberto) é o mais comum |
| Corpo de vidro | Cerca de 2 mm de diâmetro e 10–15 mm de comprimento |
| Potência de chaveamento | Até 10 W |
| Tensão de chaveamento | Até 100–200 V CC |
| Corrente de chaveamento | Cerca de 0,5 A |
| Resistência de contato | Abaixo de 0,1 Ω |
| Tempo de operação | Menos de 1 ms (incluindo o repique) |
| Sensibilidade | 10–40 AT (ampère-espiras) |
| Vida útil | De 100 milhões a 1 bilhão de operações com corrente baixa |
| Consumo próprio | Nenhum (componente passivo) |
A sensibilidade é dada em AT (ampère-espiras): a corrente multiplicada pelo número de espiras necessário para fechar a reed em uma bobina de teste padrão. Quanto menor o valor, mais fraco pode ser o ímã que a aciona, então ela funciona a uma distância maior. Também existe histerese: o campo necessário para fechar os contatos (pull-in, acionamento) é mais forte que o campo necessário para mantê-los fechados. Por exemplo, uma reed que um ímã fecha a 15 mm pode só abrir de novo por volta de 20 mm. Essa diferença reduz a trepidação em pequenas vibrações, mas o seu projeto precisa garantir que o ímã também se afaste além da distância de liberação (drop-out).
Tipos de reed NA, NF e reversível (Form A, B, C)
As chaves reed vêm em três arranjos de contato. As siglas NA (normalmente aberto; em inglês, NO) e NF (normalmente fechado; em inglês, NC) sempre descrevem o estado do contato sem nenhum ímã por perto.
| Tipo | Sem ímã | Com ímã perto | Terminais | Onde é usado? |
|---|---|---|---|---|
| Form A (NA) | Aberto | Fechado | 2 | Sensores de porta, contadores de velocidade, a maioria dos módulos |
| Form B (NF) | Fechado | Aberto | 2 | Aplicações que precisam fechar o circuito quando o ímã se afasta |
| Form C (reversível) | COM–NF fechado | COM–NA fechado | 3 | Circuitos que precisam de uma saída aberta e de uma fechada |
Acionamento com ímã: distância, posição e sensibilidade
A melhor forma de acionar uma chave reed é com um pequeno ímã de neodímio. Um disco de neodímio de 10×3 mm normalmente aciona uma reed comum a 10–20 mm; um ímã de ferrite preto do mesmo tamanho reduz essa distância mais ou menos à metade. Os sensores de porta prontos costumam funcionar a 15–25 mm. A distância não depende só da força do ímã, mas também da sua posição: quando o eixo norte-sul do ímã fica paralelo ao tubo de vidro e é aproximado do meio dele, você obtém um único fechamento limpo. Se o ímã ficar perpendicular ao tubo, ele pode não acionar exatamente no meio e, em vez disso, acionar em dois pontos perto das pontas. Um ímã paralelo deslizado ao longo do tubo também cria pequenas zonas de fechamento extras dos dois lados da principal. Assim, quando o ímã passa pela reed, os contatos podem fechar e abrir duas ou três vezes; esse é o motivo mais comum para projetos de contagem registrarem uma volta como duas ou três.

- A polaridade não importa: a reed reage da mesma forma ao polo norte e ao polo sul; virar o ímã não muda o resultado.
- Alinhe o ímã com o meio do tubo: nos sensores de porta, o ímã e o corpo da reed devem ficar lado a lado e paralelos, com a menor folga possível.
- Portas de aço encurtam a distância: o ferro puxa para si o campo do ímã. Eleve o sensor e o ímã com um espaçador plástico de 5–10 mm ou use um ímã mais forte.
- Meça a distância primeiro: com o Monitor Serial aberto, aproxime e afaste o ímã da reed devagar. Com a porta fechada, o ímã deve ficar com folga dentro da distância de acionamento; assim que a porta abre um pouco, ele deve passar da distância de liberação.
- Mantenha longe de campos fortes: alto-falantes, motores e outros ímãs podem fechar a reed sem querer; não monte a reed bem ao lado deles.
Ligação da chave reed no Arduino: por que o resistor de pull-up é indispensável?
Como a chave reed se comporta como um botão, ela não gera tensão sozinha; só liga ou desliga seus dois terminais. Enquanto os contatos estão abertos, o pino não está ligado a nada (fica flutuando) e você lê valores HIGH e LOW aleatórios causados por ruído. A solução é um resistor de pull-up: o pino é puxado para 5 V (ou 3,3 V) através de um resistor, e a reed fica entre o pino e o GND. Sem ímã, o pino lê HIGH; quando o ímã fecha os contatos, o pino fica ligado direto ao GND e lê LOW. O Arduino Uno tem um resistor de pull-up interno de 20–50 kΩ, então basta escrever pinMode(pin, INPUT_PULLUP) e nenhum resistor externo é necessário. Para os detalhes dessa lógica, veja o guia como ligar um botão no Arduino.
| Ligação | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Terminal 1 da reed (reed avulsa) | D2 | GPIO 27 | GP15 (pino físico 20) |
| Terminal 2 da reed (reed avulsa) | GND | GND | GND |
| Pull-up | Interno (INPUT_PULLUP) | Interno (INPUT_PULLUP) | Interno (Pin.PULL_UP) |
| VCC do módulo | 5V | 3V3 | 3V3(OUT) (pino físico 36) |
| GND do módulo | GND | GND | GND |
| DO do módulo | D2 | GPIO 27 | GP15 |
| LED de status | D13 (LED integrado) | GPIO 2 (LED integrado) | LED integrado |
| Buzzer ativo (+) | D8 | Não usado | GP14 |
Primeiro circuito passo a passo: detectando um ímã
- Ligue um terminal da chave reed no pino D2 do Arduino e o outro no GND. Uma reed avulsa não tem polaridade, então o sentido dos terminais não importa.
- Se usar um módulo, ligue o VCC no 5V, o GND no GND e a saída DO no D2.
- Carregue o código abaixo e abra o Monitor Serial a 9600 baud.
- Aproxime o ímã devagar, mantendo-o paralelo ao tubo de vidro; o LED integrado deve acender e “magnet detected” (ímã detectado) deve aparecer na tela.
- Ao afastar o ímã, meça com uma régua a que distância o LED apaga; essa é a sua distância de liberação.
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}O único ponto de atenção no código é a lógica invertida: como você usa INPUT_PULLUP, lê LOW quando o ímã está presente e HIGH quando não está. Nos módulos LM393 de 3 pinos, a saída também costuma ir para LOW quando o ímã se aproxima, e o LED DO da placa acende; como isso pode variar de um modelo para outro, confira primeiro o seu módulo no Monitor Serial. O potenciômetro do módulo define o limiar do comparador; como a reed já funciona como liga/desliga, ele tem pouco efeito na distância de detecção, e deixá-lo no meio normalmente basta. Minimódulos como o KY-021 não têm comparador; a placa só leva a reed e um resistor de 10 kΩ.
Debounce: repique dos contatos e vibração
Como qualquer contato mecânico, uma chave reed pode repicar algumas vezes ao fechar. Na reed, esse repique é muito curto, normalmente menos de 1 ms, mas esse não é o problema de verdade. Se o ímã se move devagar na borda da distância de acionamento, ou se a porta balança com o vento, os contatos podem abrir e fechar muitas vezes em um segundo. É por isso que um sistema que envia notificação de porta aberta pode disparar cinco mensagens para uma única abertura. A solução é esperar até o estado ficar inalterado por um certo tempo, em vez de aceitar cada mudança na hora. Para um sensor de porta, 50–100 ms bastam; para um contador de velocidade, funciona bem usar como tempo de bloqueio o menor intervalo fisicamente possível entre dois pulsos.
Se quiser uma solução de hardware, coloque um capacitor de 100 nF entre o pino e o GND. Junto com um pull-up de 10 kΩ, isso dá uma constante de tempo de τ = R × C = 10 kΩ × 100 nF = 1 ms, que suaviza os repiques muito curtos. Você pode testar outros pares de resistor e capacitor com a ferramenta Constante de tempo RC. Com o pull-up interno, a resistência é de 20–50 kΩ, então o tempo cresce para 2–5 ms. Em sensores de porta com vários metros de cabo, um pull-up externo de 4,7–10 kΩ mais esse capacitor também protege contra ruído.
Projeto de sensor de porta e janela aberta com alarme
O projeto de reed mais comum é o sensor de porta. Monte o ímã na folha móvel da porta e a reed no batente; com a porta fechada, eles ficam lado a lado, os contatos ficam fechados e o pino lê LOW. Quando a porta abre, o ímã se afasta e o pino vai para HIGH. Esse arranjo tem um bom efeito colateral: se alguém cortar o cabo do sensor, o pino também vai para HIGH e o sistema entende como “porta aberta”. É por isso que os sistemas de alarme usam fiação em laço fechado. O código abaixo conta cada abertura, mede quanto tempo a porta fica aberta e faz o buzzer apitar de forma intermitente se a porta ficar aberta por mais de 30 segundos; é perfeito para a porta da geladeira ou do freezer.
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}Como o código não usa delay(), o laço verifica o pino o tempo todo e nunca perde uma abertura; explicamos essa técnica em detalhes no artigo millis em vez de delay. Cada vez que a leitura bruta muda, o tempo lastChange é zerado, e o estado doorOpen só muda se o valor ficar igual por 50 ms. A parte do buzzer divide millis() por 250 para ligar e desligar a cada quarto de segundo. Para transformar isso em um alarme de verdade, você pode armá-lo e desarmá-lo com um teclado matricial com senha e acrescentar um sensor de movimento PIR dentro do cômodo. Para uma montagem mais completa, dê uma olhada no artigo sistema de alarme com Arduino.
Velocímetro de bicicleta: contando voltas com uma chave reed
A maioria dos ciclocomputadores é formada por uma chave reed e um pequeno ímã preso em um raio. A cada volta da roda, o ímã passa uma vez pela reed no garfo e gera um pulso. Meça o tempo entre dois pulsos e você tem a velocidade; conte os pulsos e você tem a distância: velocidade (km/h) = circunferência (mm) / tempo (ms) × 3,6. Aqui, mm/ms é exatamente m/s, e multiplicar por 3,6 converte para km/h. Por exemplo, em uma roda 700x25C com circunferência de 2105 mm, 253 ms entre dois pulsos significam 2105 / 253 × 3,6 ≈ 30 km/h. A forma mais precisa de encontrar a circunferência é rolar a roda exatamente uma volta, com a válvula embaixo, e medir a distância entre as duas marcas no chão.
| Medida do pneu | Circunferência aproximada | Tempo por volta a 30 km/h |
|---|---|---|
| 20x1.75 (BMX, bicicleta infantil) | 1515 mm | 182 ms |
| 26x2.1 (mountain bike) | 2068 mm | 248 ms |
| 29x2.1 (mountain bike) | 2288 mm | 275 ms |
| 700x25C (bicicleta de estrada) | 2105 mm | 253 ms |
| 700x28C (urbana, 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}Como o pulso é capturado com attachInterrupt, nenhuma volta se perde, por mais ocupado que esteja o loop(); no Arduino Uno, só os pinos D2 e D3 oferecem esse tipo de interrupção. O valor LOCKOUT_MS é muito importante: 80 ms correspondem a uma velocidade máxima de cerca de 95 km/h em uma roda de 2105 mm (2105 / 80 × 3,6). Pulsos que chegam mais próximos que isso são fisicamente impossíveis, então são ignorados como repique, zonas laterais de fechamento do ímã ou o contato repicando ao abrir. Se nenhum pulso chegar por 3 segundos, a velocidade é considerada zero. Com a mesma estrutura, você pode medir a velocidade de um motor ou de uma roda em rotações por minuto: RPM = 60000 / tempo (ms). Para saber mais sobre interrupções, veja o guia interrupções no Arduino; para mostrar a velocidade em um display no guidão, combine o código com um display OLED.
Chave reed ou sensor Hall?
A segunda forma de detectar um ímã é um sensor Hall. O sensor Hall transforma o campo magnético em um sinal elétrico dentro de um chip semicondutor; ele não tem partes móveis, mas precisa de alimentação para funcionar. A regra curta: para um sensor de porta ou janela que funciona muito tempo com bateria e aciona raramente, escolha uma reed; para contagem rápida e contínua, como a de um motor, de uma ventoinha ou de um sensor de fluxo de água girando dezenas de vezes por segundo, o sensor Hall é a melhor escolha.
| Característica | Chave reed | Sensor Hall (A3144, US1881, 49E) |
|---|---|---|
| Como funciona | Contato mecânico, fechado por um ímã | Semicondutor, transforma o campo em sinal elétrico |
| Alimentação | Não precisa, não consome energia | Necessária (alguns mA) |
| Velocidade de chaveamento | Centenas de vezes por segundo | Até dezenas de milhares de Hz |
| Repique dos contatos | Sim (menos de 1 ms) | Nenhum |
| Vida útil | Desgaste mecânico, 100 milhões – 1 bilhão de operações | Sem partes móveis, sem desgaste |
| Detecção do polo | Não, reage aos dois polos | Conforme o modelo: unipolar, bipolar ou com trava (latching) |
| Medição analógica | Não, só aberto ou fechado | Modelos lineares (49E) medem a intensidade do campo |
| Chaveamento de carga | Pode chavear diretamente pequenas cargas CA/CC | Só saída de sinal |
| Robustez | O tubo de vidro é sensível a impactos e dobras | Encapsulamento plástico, resistente a choques |
Notificação de porta aberta com ESP32 (Telegram)
Graças ao Wi-Fi do ESP32, o sensor de porta pode enviar uma mensagem para o seu celular no momento em que a porta abre. Para isso, você precisa criar um bot com o BotFather no Telegram, obter o token dele e o seu próprio chat ID e instalar as bibliotecas UniversalTelegramBot e ArduinoJson na Arduino IDE; explicamos esses passos em detalhes no artigo bot do Telegram com ESP32. Ligue um terminal da reed no GPIO 27 e o outro no GND. O código envia uma mensagem quando a porta abre e quando fecha, avisa você se a porta ficar aberta por mais de 5 minutos e, se o Wi-Fi estiver fora do ar naquele momento, tenta enviar a mensagem de novo 10 segundos depois.
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}Enviar uma mensagem para o Telegram pode levar 1–2 segundos, e o laço espera durante esse tempo; mas, como a máquina de estados lê o pino de novo depois do envio, o último estado da porta nunca se perde. Se quiser fazer o sensor funcionar com baterias, coloque o ESP32 em deep sleep e use esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, 1) para que ele acorde quando a porta abrir e o pino for para HIGH. Se, antes de dormir, você definir o nível de despertar como o oposto do estado atual do pino, a placa acorda tanto na abertura quanto no fechamento. Nesse caso, considere também a corrente que passa pelo resistor de pull-up: enquanto a porta está fechada, a reed está fechada, então 3,3 V / 10 kΩ = 330 µA circulam sem parar por um resistor de 10 kΩ; com 100 kΩ, a corrente cai para 33 µA. Em deep sleep, um resistor externo é a escolha mais segura, em vez do pull-up interno. Você pode estimar a duração da bateria com a ferramenta Autonomia da bateria.
Chave reed com Raspberry Pi Pico e MicroPython
Ler uma chave reed no Raspberry Pi Pico exige só algumas linhas de MicroPython. Ligue a reed entre o GP15 e o GND e, depois, o terminal positivo do buzzer ativo no GP14 e o negativo no GND. Como o Pico funciona com 3,3 V, alimente sempre um módulo pelo pino 3V3(OUT); se você alimentar o módulo com 5 V, a saída DO sobe para 5 V e pode danificar a entrada do Pico. O pull-up interno do Pico fica em torno de 50–80 kΩ, o que basta para cabos curtos.
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)O código monta a mesma lógica de debounce do Arduino usando time.ticks_ms() e time.ticks_diff(); ticks_diff devolve a diferença correta mesmo quando o contador dá a volta. Para pulsos que não podem se perder, como os de um contador de velocidade, você pode usar uma interrupção com reed.irq(trigger=Pin.IRQ_FALLING, handler=...). Se você tem um Pico W, pode juntar a este código o exemplo para Pico W do artigo sobre bot do Telegram e enviar o mesmo evento para o celular por Wi-Fi. Se é a primeira vez que você usa o Pico, comece pelo guia o que é o Raspberry Pi Pico.
Ideias de projetos com chave reed
- Sensor de porta e janela sem fio: informe cada abertura da sua casa no celular com um ESP32 ou envie para o Home Assistant via MQTT.
- Lembrete da porta da geladeira: apite de forma intermitente quando a porta ficar aberta por mais de 30 segundos.
- Ciclocomputador: mostre em um display a velocidade atual, a distância total e a velocidade média.
- Medidor de vento e chuva: nas estações meteorológicas, o anemômetro de conchas gera um pulso da reed por volta, e o pluviômetro de báscula, um pulso por basculada.
- Chave de nível tipo boia: o ímã dentro da boia abre e fecha a reed na haste para avisar que o reservatório está cheio; detalhes no artigo sensor de nível de água.
- Trava secreta de gaveta: monte uma fechadura solenoide que só abre quando um ímã é colocado no ponto certo.
- Aviso de correspondência: uma reed na portinhola da caixa de correio acorda o ESP32 do deep sleep quando chega uma carta.
Erros comuns e como resolver
- O pino lê valores aleatórios: falta o pull-up. Configure o pinMode como INPUT_PULLUP ou coloque um resistor de pull-up externo de 10 kΩ.
- A lógica está invertida: com pull-up, o pino lê LOW quando o ímã está presente; seu código pode estar esperando HIGH, ou o seu sensor é do tipo NF. Confira com o multímetro.
- Várias contagens para uma abertura: falta o debounce, ou o ímã passa pelas zonas laterais de fechamento. Acrescente um tempo de estabilidade e alinhe o ímã paralelo ao tubo.
- A reed nunca fecha: o ímã é fraco, a distância é grande demais, o ímã está perpendicular ao meio do tubo ou uma porta de aço absorve o campo. Use um ímã de neodímio mais forte e um espaçador plástico.
- A reed fica fechada o tempo todo: os contatos podem ter se soldado por excesso de corrente ou por uma carga capacitiva. Nunca acione um motor, uma lâmpada ou a bobina de um relé direto com uma reed; chaveie cargas com um módulo relé ou um transistor.
- O tubo de vidro trincou: os terminais foram dobrados perto demais do corpo. Segure o terminal com um alicate, dobre a pelo menos 2–3 mm do vidro e termine a solda rapidamente.
- Alarmes falsos em cabos longos: o pull-up interno é fraco demais. Use um pull-up externo de 4,7–10 kΩ, um capacitor de 100 nF no pino e cabo de par trançado.
A chave reed é um sensor barato e extremamente confiável que detecta um ímã sem consumir energia; com a posição certa do ímã, um resistor de pull-up e algumas linhas de código de debounce, ela funciona sem problemas por anos. No app BlueGrays você encontra os projetos Leitura de uma chave reed e Sensor de porta com chave reed, além de projetos como o Alarme de movimento com ESP32 e o sistema de alarme com notificações pelo Telegram, com esquemas do circuito e códigos passo a passo.
Perguntas frequentes
Como funciona uma chave reed?
Uma chave reed é formada por duas lâminas de ferro-níquel dentro de um tubo de vidro. Quando um ímã se aproxima, as lâminas se magnetizam, se atraem e os contatos se fecham; quando o ímã se afasta, a força de mola delas as separa. Ela mesma não consome energia e é lida no Arduino exatamente como um botão.
A chave reed é normalmente aberta ou normalmente fechada?
As chaves reed mais comuns são NA (normalmente aberta, Form A): abertas sem ímã e fechadas quando um ímã se aproxima. Também existem versões NF (Form B) e reversíveis de três terminais (Form C). Nos contatos de porta para alarme, porém, a etiqueta “NC” significa que o circuito está fechado enquanto a porta está fechada e o ímã está ao lado, por isso testar com o multímetro é o caminho mais seguro.
A que distância um ímã consegue acionar uma chave reed?
Depende da força do ímã e da sensibilidade da reed. Um pequeno ímã de neodímio normalmente aciona as reeds comuns a 1–2 cm, e os sensores de porta prontos funcionam a 15–25 mm; com ímãs de ferrite, a distância cai mais ou menos à metade. Manter o ímã paralelo ao tubo e longe de superfícies de aço aumenta a distância.
A chave reed precisa de resistor?
A entrada do Arduino precisa de um resistor de pull-up ou pull-down; sem ele, o pino fica flutuando e lê valores aleatórios enquanto os contatos estão abertos. Como o Arduino, o ESP32 e o Pico têm pull-ups internos que você ativa com INPUT_PULLUP ou Pin.PULL_UP, normalmente não é preciso um resistor externo. Em cabos longos, um resistor externo de 4,7–10 kΩ dá resultados mais estáveis.
Qual é a diferença entre uma chave reed e um sensor de efeito Hall?
A chave reed é um contato mecânico; não precisa de alimentação e pode chavear pequenas cargas diretamente, mas tem repique e o tubo de vidro é frágil. O sensor Hall é um semicondutor; precisa de alimentação, não tem repique e é muito mais rápido. A reed é a preferida para sensores de porta a bateria, e o sensor Hall, para contagem rápida de rotações.
Uma chave reed pode ligar uma lâmpada da rede elétrica?
As chaves reed de vidro pequenas normalmente aguentam no máximo 10 W de potência de chaveamento, então chavear direto uma lâmpada ou um motor da rede elétrica solda os contatos e é perigoso. Ligue a reed ao Arduino só como sinal, controle a carga da rede com um módulo relé e sempre siga as regras de segurança ao trabalhar com a tensão da rede.
Projetos para montar depois desta leitura
Ver todos os projetos
Leitura de uma chave reed
Você já teve curiosidade sobre a chave magnética dos alarmes de portas e janelas? Quando um ímã se aproxima do módulo de relé reed, a pequena chave interna fecha; o Arduino faz a leitura uma vez por s

Sensor de porta com chave reed
Saiba se a porta está aberta ou fechada só de olhar uma luz. Você fixa um pequeno ímã na porta e uma chave sensível ao ímã no batente; quando a porta está fechada, os dois ficam lado a lado e o LED ve

Controle de LED com botão (momentâneo)
É como uma campainha: a luz fica acesa enquanto você pressiona o botão e apaga quando você solta. O Arduino monitora o botão continuamente; enquanto ele está pressionado, o LED fica aceso e apaga assi

Controle de LED com botão no ESP32 (momentâneo)
O LED acende enquanto o botão está pressionado e apaga ao soltá-lo. Mostra como usar o pino de entrada digital e o resistor pull-up interno do ESP32. O modo INPUT_PULLUP dispensa um resistor externo.

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.

Raspberry Pi Pico: debounce de botão com IRQ ou consulta por software
Você pressiona o botão uma vez e o código conta 3-4? Isso é oscilação dos contatos — os contatos metálicos oscilam por microssegundos! Compare 2 métodos de contagem lado a lado no Monitor Serial: consulta sem filtro (detecta as oscilações e conta a mais) e IRQ + debounce por software (contagem correta). Aprenda a física da oscilação dos contatos, debounce por software (ticks_diff() > 50ms), registro de interrupção com Pin.irq(), disparo IRQ_FALLING, rotinas ISR, global e…

Sistema de segurança com laser
Como nas cenas de roubo com lasers dos filmes: um feixe de laser atinge um sensor de luz e, assim que alguém passa e interrompe o feixe, o LED vermelho acende e o buzzer começa a soar. O alarme não pa
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

