Build a low-cost, practical door presence alert using an ultrasonic distance sensor, an ESP32, and Telegram. When someone stands near your door for a few seconds, you get an instant notification on your phone — no subscriptions, just hardware + logic.
Quick Summary
An HC-SR04 ultrasonic sensor continuously measures distance at your front door. An ESP32 checks whether someone is within a defined range for a set amount of time. If that condition is met, the ESP32 sends a Telegram message directly to your phone with a built-in cooldown to prevent spam.
Table of Contents
Parts List
From ShillehTek
- Breadboard — Shop Breadboard
- Jumper Wires — Shop Jumper Wires
External
- ESP32 Dev Board (WROOM-based)
- HC-SR04 Ultrasonic Distance Sensor
- USB Battery Pack (5V, 2A+ recommended)
- Mounting tape (for door install)
- 100µF capacitors (optional but recommended for stable Wi-Fi/TLS)
Note: This project is intentionally simple and local. The only “external” dependency is Telegram for notifications.
Step 1: Wiring
This wiring powers the sensor from the ESP32’s 3.3V rail and uses GPIO18/19 for trigger/echo.
HC-SR04 → ESP32
- VCC → ESP32 3V3
- GND → ESP32 GND
- TRIG → ESP32 GPIO18
- ECHO → ESP32 GPIO19
Stability tip: Place multiple 100µF capacitors in parallel from 3V3 → GND as close to the ESP32 as possible. This helps prevent resets when Telegram (HTTPS) sends.
Step 2: Create a Telegram Bot + Get Chat ID
We’re using a Telegram bot so the ESP32 can send you messages.
A) Create your bot token
- In Telegram, search for @BotFather.
- Send:
/newbot - Follow prompts (name + username). BotFather will give you a bot token.
B) Get your Chat ID (fast)
- Open Telegram and message your new bot (send any text like “hi”).
- In a browser, visit this URL (replace
<TOKEN>):
https://api.telegram.org/bot<TOKEN>/getUpdates
Look in the response for "chat":{"id": ... }. That number is your TELEGRAM_CHAT_ID.
Tip: If you want alerts to go to a group chat, add the bot to the group, send a message in the group, then run getUpdates again to find the group chat ID.
Step 3: Detection Logic
The system uses three rules:
-
Distance threshold: Trigger when someone is within ~1 meter (
THRESH_CM). -
Hold time: Must stay below the threshold for 3 seconds (
HOLD_MS). -
Cooldown: Wait 30 seconds after an alert (
COOLDOWN_MS).
This avoids false triggers and prevents spam.
Step 4: ESP32 + Telegram Code
Important: Replace the empty strings below with your Wi-Fi + Telegram info.
#include <WiFi.h>
#include <WiFiClientSecure.h>
// --- Put your secrets here (keep these private) ---
// Replace the empty strings with your own Wi-Fi + Telegram credentials.
const char* WIFI_SSID = "";
const char* WIFI_PASSWORD = "";
const char* TELEGRAM_BOT_TOKEN = "";
const char* TELEGRAM_CHAT_ID = "";
// --- Pins ---
const int ECHO_PIN = 19;
const int TRIG_PIN = 18;
// --- Behavior ---
const int THRESH_CM = 100; // 1 meter
const unsigned long HOLD_MS = 3000; // 3 seconds
const unsigned long COOLDOWN_MS = 30000; // 30 seconds
unsigned long closeStartMs = 0;
unsigned long lastAlertMs = 0;
String urlEncode(const String& s) {
String out;
const char *hex = "0123456789ABCDEF";
for (size_t i = 0; i < s.length(); i++) {
char c = s[i];
if (isalnum((unsigned char)c) || c == '-' || c == '_' || c == '.' || c == '~') out += c;
else if (c == ' ') out += "%20";
else {
out += '%';
out += hex[(c >> 4) & 0xF];
out += hex[c & 0xF];
}
}
return out;
}
bool sendTelegram(const String& msg) {
WiFiClientSecure client;
client.setInsecure(); // demo: skip cert validation
String url = "/bot" + String(TELEGRAM_BOT_TOKEN)
+ "/sendMessage?chat_id=" + String(TELEGRAM_CHAT_ID)
+ "&text=" + urlEncode(msg);
if (!client.connect("api.telegram.org", 443)) {
Serial.println("Telegram connect failed");
return false;
}
client.print(String("GET ") + url + " HTTP/1.1\r\n"
+ "Host: api.telegram.org\r\n"
+ "Connection: close\r\n\r\n");
while (client.connected() || client.available()) {
String line = client.readStringUntil('\n');
if (line.indexOf("\"ok\":true") >= 0) return true;
}
return false;
}
float readDistanceCm() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) return -1;
return (duration * 0.0343f) / 2.0f;
}
float readDistanceCmFiltered() {
float a = readDistanceCm();
delay(30);
float b = readDistanceCm();
delay(30);
float c = readDistanceCm();
if (a > b) { float t=a; a=b; b=t; }
if (b > c) { float t=b; b=c; c=t; }
if (a > b) { float t=a; a=b; b=t; }
return b;
}
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
btStop();
WiFi.setTxPower(WIFI_POWER_11dBm);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("WiFi connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println("\nWiFi connected");
sendTelegram("✅ Your device is online");
}
void loop() {
unsigned long now = millis();
float cm = readDistanceCmFiltered();
if (cm > 0) {
bool isClose = (cm <= THRESH_CM);
if (isClose) {
if (closeStartMs == 0) closeStartMs = now;
bool heldLongEnough = (now - closeStartMs) >= HOLD_MS;
bool cooldownOver = (now - lastAlertMs) >= COOLDOWN_MS;
if (heldLongEnough && cooldownOver) {
String msg = "🚪 Someone is near the door: " + String(cm, 1) + " cm";
bool ok = sendTelegram(msg);
Serial.println(ok ? "Alert sent" : "Alert failed");
lastAlertMs = now;
closeStartMs = 0;
}
} else {
closeStartMs = 0;
}
} else {
closeStartMs = 0;
}
delay(120);
}
Tuning: Adjust THRESH_CM (range), HOLD_MS (how long they must stand there), and COOLDOWN_MS (spam control).
Step 5: Mounting at the Door
Mount the sensor at waist/chest height aimed at where a person naturally stands. Start with:
- THRESH_CM = 80–100 cm
- HOLD_MS = 3000 ms
- COOLDOWN_MS = 30000 ms
If your entry is narrow, drop the threshold. If you want fewer false positives, increase the hold time.
Conclusion + Next Ideas
This build is a clean example of “cheap parts + simple logic = real utility.” No cameras. No subscriptions. Just an alert when someone is actually standing at your door.
Ideas to extend it
- Different messages for different distances
- Quiet hours (only alert at night)
- Multiple sensors for wider coverage
- Battery optimization (deep sleep + wake strategies)
Want help productionizing a project like this? ShillehTek consulting covers hardware, firmware, and deployment.