Get a phone alert when a door opens with Arduino Cloud triggers

A reed switch and a magnet notice when a door opens. Arduino Cloud shows the door's state and counts the openings, and a trigger sends an alert to your phone. A free ntfy alert is built in too.
  • Level:Intermediate
  • Duration: 1 h
  • Ages 11+
  • Platform: ESP32

Tools for this lesson

Helpful for this build. Open a tool to see tips and more projects that use it.

Get a phone alert when a door opens with Arduino Cloud triggers – EEMENTOR STEM™ lesson

Want to know when someone opens your bedroom door, the garden gate or the cookie cupboard? A reed switch on the frame and a magnet on the door notice every opening. The ESP32 sends the door's state to Arduino Cloud, where a Contact sensor widget shows open or closed and a counter shows how many times it was opened. An Arduino Cloud trigger turns the change into an alert on your phone. Because triggers may need a paid plan, the sketch also sends a free alert through ntfy.

What you'll learn

  • How a reed switch and a magnet work as a door sensor
  • How to use the Contact sensor variable type
  • How to set up an Arduino Cloud trigger
  • How to send a backup alert through ntfy

What you need

  • ESP32 board, expansion board and USB cable (ESP32 IoT Starter Kit)
  • Reed switch module (45-in-1 Sensor Kit)
  • 1 small magnet, about 10 mm across (a craft or fridge magnet)
  • Passive buzzer (ESP32 IoT Starter Kit)
  • An Arduino Cloud account, and the ntfy app on your phone
  • A 2.4 GHz Wi-Fi network
  • The printed parts from the 3D printing box below (door sensor case and magnet holder), or the cardboard version described there
  • Breadboard and jumper wires (ESP32 IoT Starter Kit)

Wiring

Breadboard wiring diagram: Get a phone alert when a door opens with Arduino Cloud triggers
Breadboard view. Check each connection against the wiring table below.
From To
Reed switch module S ESP32 GPIO 33
Reed switch module + and − 3V3 and GND
Passive buzzer + ESP32 GPIO 26
Passive buzzer − GND

Sensor modules from different makers can label and order their pins differently. Always follow the labels printed on your module.

Set up Arduino Cloud

In Arduino Cloud, open Things, create a new Thing called Door Alert, link it to your ESP32 device and fill in its network settings. Then add these variables. Lesson 1 of this path shows each step with pictures in words.

Variable Type Permission Update
door Contact sensor Read only On change
openings Integer number Read only On change
chime Boolean Read & Write On change

Open Dashboards, create a dashboard and add a Status widget (door), a Value widget (openings) and a Switch (chime), each linked to its variable. The same dashboard appears in the free Arduino IoT Remote app on your phone.

Add the trigger

  1. Open Triggers and click + Trigger.
  2. Choose the door variable of the Door Alert Thing and the condition "changes to open" (true).
  3. Add an action: Send push notification (to the Arduino IoT Remote app) or Send email, and write a message such as "The door was opened".

Triggers are part of Arduino Cloud's paid plans at the time of writing. If you are on the free plan, skip this step: the sketch below also sends an alert through ntfy, which is free. Install the ntfy app and subscribe to a long, random topic name, as in the motion alert lesson. Topics are public, so never use a name that is easy to guess.

The sketch

Arduino Cloud writes the sketch's first version for you, with a thingProperties.h tab that lists your variables and a Secret tab with your Wi-Fi details and device key. In the Thing, open the Sketch tab, click Open full editor, replace the main sketch with the code below and upload. Leave the other tabs as they are.

Start the sketch with the door closed: it uses that reading as "closed". Put your ntfy topic into NTFY_TOPIC, or leave it empty to skip ntfy.

#include "thingProperties.h"
#include <WiFiClientSecure.h>

const char* NTFY_TOPIC = "YOUR_SECRET_TOPIC";   // "" to switch ntfy off
const int REED_PIN = 33, BUZZER_PIN = 26;
int closedReading;
bool wasOpen = false;
unsigned long changedAt = 0;

// Send a message to ntfy with a plain HTTPS request
void sendNtfy(const String& text) {
  if (strlen(NTFY_TOPIC) == 0 || WiFi.status() != WL_CONNECTED) return;
  WiFiClientSecure client;
  client.setInsecure();
  if (!client.connect("ntfy.sh", 443)) {
    Serial.println("ntfy: no connection");
    return;
  }
  client.print(String("POST /") + NTFY_TOPIC + " HTTP/1.1\r\n" +
               "Host: ntfy.sh\r\n" +
               "Title: Door alert\r\n" +
               "Tags: door\r\n" +
               "Content-Type: text/plain\r\n" +
               "Content-Length: " + text.length() + "\r\n" +
               "Connection: close\r\n\r\n" + text);
  String status = client.readStringUntil('\n');   // for example "HTTP/1.1 200 OK"
  client.stop();
  Serial.println("ntfy: " + status);
}

void setup() {
  Serial.begin(115200);
  delay(1500);
  pinMode(REED_PIN, INPUT);
  closedReading = digitalRead(REED_PIN);

  initProperties();
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  setDebugMessageLevel(2);          // connection messages in the Serial Monitor
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  bool open = digitalRead(REED_PIN) != closedReading;
  if (open != wasOpen && millis() - changedAt > 300) {   // ignore the bounce of the switch
    changedAt = millis();
    wasOpen = open;
    door = open;                                        // Contact sensor: true = open
    if (open) {
      openings = openings + 1;
      Serial.println("Door opened");
      if (chime) tone(BUZZER_PIN, 1800, 150);
      sendNtfy("The door was opened.");
    } else {
      Serial.println("Door closed");
    }
  }
}

void onChimeChange() {
  if (chime) tone(BUZZER_PIN, 2400, 80);              // a little beep to confirm
}

For reference, this is the thingProperties.h that Arduino Cloud creates from the variables above. Yours has your own device ID, and may use an older but equally valid style such as addProperty(led, READWRITE, ON_CHANGE, onLedChange).

// Code generated by Arduino Cloud (yours has your own device ID)
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

const char DEVICE_LOGIN_NAME[] = "YOUR_DEVICE_ID";
const char SSID[] = SECRET_SSID;              // from the Secret tab
const char PASS[] = SECRET_OPTIONAL_PASS;
const char DEVICE_KEY[] = SECRET_DEVICE_KEY;

void onChimeChange();

CloudContactSensor door;
int openings;
bool chime;

void initProperties() {
  ArduinoCloud.setBoardId(DEVICE_LOGIN_NAME);
  ArduinoCloud.setSecretDeviceKey(DEVICE_KEY);
  ArduinoCloud.addProperty(door, Permission::Read).publishOnChange(0);
  ArduinoCloud.addProperty(openings, Permission::Read).publishOnChange(0);
  ArduinoCloud.addProperty(chime, Permission::ReadWrite).onUpdate(onChimeChange);
}

WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);

client.setInsecure() keeps the connection encrypted but skips checking the server's certificate. That keeps the sketch short and is fine for a learning project. For a device you leave running for years, load the server's root certificate with client.setCACert() instead.

How it works

A reed switch is two thin metal strips in a glass tube. A magnet nearby pulls them together. Some modules give HIGH with the magnet and some LOW, so the sketch reads the switch at start-up, with the door shut, and calls anything different "open".

Every time the door changes, the sketch updates door; when it opens, it also adds one to openings. Arduino Cloud sees the change and sends it on to the dashboard and to any trigger watching the variable. The trigger runs on Arduino's servers, so it keeps working even when your phone is off.

The 300 ms pause after a change ignores the tiny bounces of the switch contacts, so one opening counts once.

Try this next

  • Send an alert only between 22:00 and 07:00, using internet time.
  • Count how long the door was open in total today.
  • Add a second reed switch for a window.

Troubleshooting

  • The device stays "Offline": open the Serial Monitor at 115200 baud. Check the Wi-Fi name and password in the Secret tab (2.4 GHz only) and that the secret device key is the one you saved when you added the device.
  • Compile error about a variable: the variable names in the sketch must match the ones in your Thing exactly, including capital letters. Rename the Thing's variable or the sketch's to match.
  • It says "open" with the door shut: the magnet is too far away. Bring it within 1 cm and restart the ESP32 with the door shut.
  • No ntfy alert: check the topic letter by letter in the sketch and the app.
  • 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.

Build it yourself

Everything used in this lesson comes in one kit, with parts tested by our engineers.

ESP32 IoT Starter Kit | Arduino IDE Compatible | Free Tutorials $57.00

Shop the kit