Burglar alarms, fridges and laptops all use the same trick to know when something is open: a reed switch. It is two thin metal strips in a small glass tube, and a magnet pulls them together. Put the magnet on a door and the switch on the frame, and the Arduino knows when the door opens. In this lesson you count openings, light an LED while the door is open, and beep if it stays open for more than 30 seconds.
What you'll learn
- How a reed switch reacts to a magnet
- How to detect the moment something changes (an edge)
- How to time how long a door stays open
- How to make a sketch work with modules that idle HIGH or LOW
What you need
- UNO R3 board and USB cable (UNO R3 Starter Kit)
- Reed switch module (45-in-1 Sensor Kit)
- Active buzzer module (45-in-1 Sensor Kit)
- Red LED and 1 resistor, 220 Ω (UNO R3 Starter Kit)
- A small fridge magnet
- The printed parts from the 3D printing box below (sensor and magnet holders), or the cardboard version described there
- Breadboard and jumper wires (UNO R3 Starter Kit)
Wiring

| From | To |
|---|---|
| Reed switch module S | UNO pin 2 |
| Reed switch module + and − | 5V and GND |
| UNO pin 13 | 220 Ω resistor, then the red LED's long leg |
| Red LED short leg | GND |
| Active buzzer module S | UNO pin 8 |
| Active buzzer module + and − | 5V and GND |
Sensor modules from different makers can label and order their pins differently. Always follow the labels printed on your module.
The sketch
Start the sketch with the door closed (or the magnet next to the switch): it uses that as the "closed" reading.
const int REED_PIN = 2;
const int LED_PIN = 13;
const int BUZZER_PIN = 8;
const unsigned long OPEN_TOO_LONG = 30000; // beep after 30 s
int closedReading; // what the pin reads while the magnet is near
bool wasOpen = false;
unsigned long openedAt = 0;
unsigned long openings = 0;
void setup() {
Serial.begin(9600);
pinMode(REED_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
delay(200);
closedReading = digitalRead(REED_PIN);
Serial.println("Door closed. Counting...");
}
void loop() {
bool open = digitalRead(REED_PIN) != closedReading;
if (open && !wasOpen) { // it just opened
openings++;
openedAt = millis();
Serial.print("Opened! Total: ");
Serial.println(openings);
}
if (!open && wasOpen) { // it just closed
Serial.print("Closed after ");
Serial.print((millis() - openedAt) / 1000);
Serial.println(" s");
digitalWrite(BUZZER_PIN, LOW);
}
wasOpen = open;
digitalWrite(LED_PIN, open);
if (open && millis() - openedAt > OPEN_TOO_LONG) {
digitalWrite(BUZZER_PIN, (millis() / 500) % 2); // beep on and off
}
delay(20); // short pause also ignores contact bounce
}
How it works
The magnet's field pulls the two strips in the reed switch together, closing the circuit. Move the magnet away and they spring apart. The module turns that into a HIGH or LOW signal, but makers wire it in different ways, so the sketch reads the pin once at the start, with the door closed, and treats any other reading as "open".
The interesting moments are the changes: open && !wasOpen is true only once, in the loop where the door has just opened. Remembering the previous state in wasOpen is called edge detection. Saving millis() at that moment lets the sketch work out later how long the door was open.
Try this next
- Count openings per hour and print a small table every hour.
- Use it on a fridge or a cupboard with snacks. Who opens it most?
- Move it to the ESP32 and send an ntfy alert, like the motion alert lesson.
Troubleshooting
- It counts openings while the door is shut: the magnet is too weak or too far away. Bring it closer, or turn it round.
-
It counts two openings at once: make the
delay(20)longer. - Everything is the wrong way round: you started the sketch with the door open. Close it and press the UNO's reset button.
- A printed part is too tight or too loose: printers differ by a few tenths of a millimetre. Sand or file a tight hole, and fix a loose part with a drop of hot glue or a strip of tape.