Componentes · 17 min de leitura

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.

Módulo sensor com chave reed e chave reed de vidro
Módulo de chave reed: o tubo de vidro à esquerda guarda duas lâminas de metal; o comparador LM393 e o potenciômetro da placa transformam o sinal em uma saída digital limpa no pino DO.

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ísticaValor típico (reed de vidro pequena)
Tipo de contatoForm A (NA, normalmente aberto) é o mais comum
Corpo de vidroCerca de 2 mm de diâmetro e 10–15 mm de comprimento
Potência de chaveamentoAté 10 W
Tensão de chaveamentoAté 100–200 V CC
Corrente de chaveamentoCerca de 0,5 A
Resistência de contatoAbaixo de 0,1 Ω
Tempo de operaçãoMenos de 1 ms (incluindo o repique)
Sensibilidade10–40 AT (ampère-espiras)
Vida útilDe 100 milhões a 1 bilhão de operações com corrente baixa
Consumo próprioNenhum (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.

TipoSem ímãCom ímã pertoTerminaisOnde é usado?
Form A (NA)AbertoFechado2Sensores de porta, contadores de velocidade, a maioria dos módulos
Form B (NF)FechadoAberto2Aplicações que precisam fechar o circuito quando o ímã se afasta
Form C (reversível)COM–NF fechadoCOM–NA fechado3Circuitos que precisam de uma saída aberta e de uma fechada
Os contatos de porta vendidos para sistemas de alarme (como o modelo comum MC-38) costumam vir marcados como “NC”. Aqui, NC significa que o circuito está fechado enquanto a porta está fechada, ou seja, com o ímã ao lado; por dentro há, na verdade, uma reed Form A (NA). Por isso, teste primeiro o seu sensor no modo de continuidade (bipe) do multímetro, com e sem o ímã; se você escrever o código só com base na etiqueta, pode acabar com a lógica invertida.

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.

Tipos de ímãs de neodímio: disco, cubo, bloco e escareado
Os ímãs de neodímio são ideais para acionar uma chave reed; os escareados são fáceis de parafusar em uma porta ou em um batente.
  • 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çãoArduino UnoESP32Raspberry Pi Pico
Terminal 1 da reed (reed avulsa)D2GPIO 27GP15 (pino físico 20)
Terminal 2 da reed (reed avulsa)GNDGNDGND
Pull-upInterno (INPUT_PULLUP)Interno (INPUT_PULLUP)Interno (Pin.PULL_UP)
VCC do módulo5V3V33V3(OUT) (pino físico 36)
GND do móduloGNDGNDGND
DO do móduloD2GPIO 27GP15
LED de statusD13 (LED integrado)GPIO 2 (LED integrado)LED integrado
Buzzer ativo (+)D8Não usadoGP14
Nunca ligue uma chave reed direto entre o 5V e o GND nem em um pino configurado como OUTPUT: no momento em que um ímã se aproxima, você cria um curto-circuito, os contatos finos podem se soldar e o regulador da placa pode ser danificado. No ESP32, os GPIO 34–39 são só de entrada e não têm resistores de pull-up internos; se usar esses pinos para uma reed, coloque um resistor de pull-up externo de 10 kΩ.

Primeiro circuito passo a passo: detectando um ímã

  1. 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.
  2. Se usar um módulo, ligue o VCC no 5V, o GND no GND e a saída DO no D2.
  3. Carregue o código abaixo e abra o Monitor Serial a 9600 baud.
  4. 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.
  5. 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.
C++ (Arduino IDE)
1const byte REED_PIN = 2;             // reed: D2 ile GND arasında / reed between D2 and GND
2const byte LED_PIN = 13;             // karttaki LED / onboard LED
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(REED_PIN, INPUT_PULLUP);   // dahili pull-up: mıknatıs yokken HIGH / internal pull-up: HIGH without a magnet
7  pinMode(LED_PIN, OUTPUT);
8}
9
10void loop() {
11  if (digitalRead(REED_PIN) == LOW) {       // kontak kapalı: mıknatıs yakında / contacts closed: magnet nearby
12    digitalWrite(LED_PIN, HIGH);
13    Serial.println(F("Miknatis var / magnet detected"));
14  } else {                                  // kontak açık: mıknatıs uzakta / contacts open: magnet away
15    digitalWrite(LED_PIN, LOW);
16    Serial.println(F("Miknatis yok / no magnet"));
17  }
18  delay(200);
19}

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.

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

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

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ísticaChave reedSensor Hall (A3144, US1881, 49E)
Como funcionaContato mecânico, fechado por um ímãSemicondutor, transforma o campo em sinal elétrico
AlimentaçãoNão precisa, não consome energiaNecessária (alguns mA)
Velocidade de chaveamentoCentenas de vezes por segundoAté dezenas de milhares de Hz
Repique dos contatosSim (menos de 1 ms)Nenhum
Vida útilDesgaste mecânico, 100 milhões – 1 bilhão de operaçõesSem partes móveis, sem desgaste
Detecção do poloNão, reage aos dois polosConforme o modelo: unipolar, bipolar ou com trava (latching)
Medição analógicaNão, só aberto ou fechadoModelos lineares (49E) medem a intensidade do campo
Chaveamento de cargaPode chavear diretamente pequenas cargas CA/CCSó saída de sinal
RobustezO tubo de vidro é sensível a impactos e dobrasEncapsulamento 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.

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

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.

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

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.
Teste a chave reed no modo de continuidade (bipe) do multímetro antes de colocá-la no circuito: com as pontas de prova nos dois terminais, ele deve apitar quando o ímã se aproxima e parar quando ele se afasta. Esse teste de dez segundos mostra com certeza tanto se a reed funciona quanto se ela é NA ou NF; também é a forma mais fácil de medir com uma régua a distância de acionamento do ímã.

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.

Ver todos os projetos
Leitura de uma chave reed
#37Iniciante

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

4.4(21)
27
Sensor de porta com chave reed
#38Iniciante
Premium

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

4.7(34)
44
Controle de LED com botão (momentâneo)
#9Iniciante

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

4.8(113)
229
Controle de LED com botão no ESP32 (momentâneo)
#104Iniciante

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.

4.6(36)
55
Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
#145Avançado
Premium

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.

0.0(0)
9
Raspberry Pi Pico: debounce de botão com IRQ ou consulta por software
#159Intermediário
Premium

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…

0.0(0)
12
Sistema de segurança com laser
#23Avançado
Premium

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

4.8(60)
77