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
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 offNo 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 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.
The same alarm in MicroPython: note when the door opens, and light the TK01 on a second pin once it has stood open for ALARM_AFTER_MS.
"""
Hall Effect Sensor - a door alarm, MicroPython TK18 / /p/tk18
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 3V3 (never 5V: with no magnet, SIGNAL sits at VCC)
NC -> nothing (unconnected on the board)
SIGNAL -> 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 -> GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3, GP14 on a Pico
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine and time are built in.
"""
from machine import Pin
import time
# The GPIO number the Hall sensor's SIGNAL is wired to.
# ESP32: 25. ESP32-S3: 4. Pico: 15.
HALL_PIN = 4
# The GPIO number the TK01's SIGNAL is wired to.
# ESP32: 4. ESP32-S3: 5. Pico: 14.
LED_PIN = 5
ALARM_AFTER_MS = 10000
hall = Pin(HALL_PIN, Pin.IN) # the chip drives SIGNAL both ways
led = Pin(LED_PIN, Pin.OUT, value=0)
def door_shut():
return hall.value() == 0 # magnet near: 0
was_shut = door_shut()
opened_at = time.ticks_ms()
alarm_on = False
while True:
shut = door_shut()
now = time.ticks_ms()
if not shut and was_shut: # it has just opened
opened_at = now
print("opened")
if shut and not was_shut:
print("shut")
was_shut = shut
alarm = (not shut
and time.ticks_diff(now, opened_at) >= ALARM_AFTER_MS)
if alarm != alarm_on:
alarm_on = alarm
led.value(alarm)
print("left open: alarm" if alarm else "alarm off")time.ticks_ms() wraps round, so the sketch compares times with ticks_diff() rather than subtracting. Stop it with Ctrl-C in Thonny's shell; the TK01 stays in whatever state it was in.
When it does not work
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.
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.
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.
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().
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
Questions about this product
See what other owners have asked, and read their solutions.
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.