Hall effect sensor/Using it/09. A door alarm
Using it · 09 of 10

A door alarm

A magnet on the door, the block on the frame. Shut, SIGNAL is LOW; open, it goes HIGH. The sketch does not sound the alarm when the door opens: it times how long SIGNAL has been HIGH, and lights a TK01 once the door has stood open for ten seconds.

Magnet on the door, block on the frame

Fix the block to the frame and a small magnet to the door, so that when the door shuts, the magnet's flat face sits over the small chip at the top left of the block. Shut, the magnet is in range and SIGNAL is LOW. Open, it moves away and SIGNAL goes HIGH.

The block's own red LED is the mounting guide. It should be lit with the door shut and go out when the door is open a finger's width. If it flickers or stays dark when shut, the magnet is too far away or off to one side. How far a magnet reaches gives a starting gap; leave a few millimetres to spare.

The door and the frame can be wood or plastic, and the magnet can sit behind a thin panel. A steel door is another matter: steel draws the field into itself, and the magnet may need to stand off from it.

Time, not the level

A door left open
Door
shut
SIGNAL
LOW
Alarm
off
The door is shut, the magnet on it is beside the block, and SIGNAL is LOW. Run the thirty seconds.

An alarm that goes off whenever SIGNAL is HIGH goes off every time somebody walks through. The sketch does something else: when the door opens, it notes the time; while it stays open, it compares the time since then with ALARM_AFTER_MS; and when the door shuts, the alarm stops. Ten seconds is the figure's choice and the sketch's; change the number to suit the door.

The three seconds at the start of the figure is someone walking through. The door opened, SIGNAL went HIGH, the door shut again, and nothing happened. The second opening is the one that was left.

The wiring

The block is wired as in the first read. The alarm is a TK01 XL LED on a second pin: D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3, GP14 on a Pico. Its first blink shows the two wires. Without one, watch the serial monitor:

opened
shut
opened
left open: alarm
shut
alarm off

No debouncing, and none needed: the chip has no contacts, and its hysteresis keeps a door that rattles at the edge of range from reading as a string of openings.

The code

Watches a door with a magnet on it. It prints each opening and closing, and once the door has been open for ALARM_AFTER_MS it lights a TK01 XL LED on a second pin. No library, no delay().

hall_door_alarm.ino
/*
  Hall Effect Sensor - a door alarm                      TK18 / /p/tk18

  Wiring. Count from the square pad on the TinkerBlock board, parts
  up, header at the bottom:

    GND    -> GND
    VCC    -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
              (with no magnet, SIGNAL sits at whatever VCC is)
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> D2 on an Uno, GPIO 25 on an ESP32, GPIO 4 on an
              ESP32-S3, GP15 on a Raspberry Pi Pico

  The block on the frame, a magnet on the door facing the small
  chip at the top left of the block.

  A TK01 XL LED on a second pin is the alarm (optional):
    GND    -> GND
    SIGNAL -> D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an
              ESP32-S3, GP14 on a Raspberry Pi Pico

  Arduino IDE
    Tools > Board                 your board, e.g. ESP32S3 Dev Module
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    No library needed.
*/

// The GPIO number the Hall sensor's SIGNAL is wired to.
// Uno: 2. ESP32: 25. ESP32-S3: 4. Pico: 15.
const int HALL_PIN = 4;
// The GPIO number the TK01's SIGNAL is wired to.
// Uno: 9. ESP32: 4. ESP32-S3: 5. Pico: 14.
const int LED_PIN = 5;
const unsigned long ALARM_AFTER_MS = 10000;

bool wasShut;
bool alarmOn = false;
unsigned long openedAt;

bool doorShut() {
  return digitalRead(HALL_PIN) == LOW;   // magnet near: LOW
}

void setup() {
  Serial.begin(115200);
  pinMode(HALL_PIN, INPUT);     // the chip drives SIGNAL both ways
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  wasShut = doorShut();
  openedAt = millis();
}

void loop() {
  bool shut = doorShut();
  unsigned long now = millis();

  if (!shut && wasShut) {       // it has just opened: start the clock
    openedAt = now;
    Serial.println("opened");
  }
  if (shut && !wasShut) {
    Serial.println("shut");
  }
  wasShut = shut;

  bool alarm = !shut && now - openedAt >= ALARM_AFTER_MS;
  if (alarm != alarmOn) {
    alarmOn = alarm;
    digitalWrite(LED_PIN, alarm ? HIGH : LOW);
    Serial.println(alarm ? "left open: alarm" : "alarm off");
  }
}

The alarm depends on time, not on the level: opening the door starts a clock, shutting it stops the alarm and forgets the clock. setup() reads the door once, so a door that is already open at power-up is timed from then rather than counted as a fresh opening.

When it does not work

It says the door is open when it is shut.

The magnet is too far from the chip when the door closes, or it lines up with the wrong part of the block. The red LED on the block should be lit with the door shut: move the magnet or the block until it is, with a few millimetres to spare. Remember the chip is at the top left, not under the printed magnet.

The alarm goes off the moment I open the door.

ALARM_AFTER_MS is too small, or the sketch is testing the level rather than the time. The alarm should depend on how long the door has been open: now minus openedAt, compared with ALARM_AFTER_MS, as in the sketch.

It is on a battery and the battery goes flat quickly.

With the door shut the magnet is there, SIGNAL is LOW, and the block's red LED is lit: about 3.5 mA from 5 V, all the time the door is shut. The chip itself averages about 5 µA. For a battery sensor, that LED is the cost to plan for, not the chip.

Can I use a buzzer instead of the TK01?

Yes. The sketch drives LED_PIN HIGH for the alarm, so anything that switches on with a HIGH works on that pin unchanged; the active buzzer block is one. A passive buzzer needs tone() instead of digitalWrite().

Where this goes next

The short list of reasons, split in two by the red LED.

When a magnet does nothing

Edit this page — content/books/hall-effect-sensor/a-door-alarm.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Hall Effect Sensor

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum