Автоматизація
Середній
Telegram-бот на ESP32: керування реле та сповіщення про рух
Керуємо світлом командами /on та /off з будь-якої точки світу й отримуємо повідомлення в Telegram, коли PIR-датчик помітив рух. Без білого IP та прокидання портів.
Чому Telegram
Щоб керувати пристроєм з інтернету, зазвичай потрібні білий IP, прокидання портів чи хмарний сервіс. З Telegram усе простіше: ESP32 сам звертається до серверів Telegram і опитує нові повідомлення. Вхідних підключень немає — отже, працює за будь-яким роутером і навіть через мобільний інтернет.
Що вміє бот:
/on,/off— вмикає й вимикає реле;/status— стан реле, рівень сигналу Wi-Fi та час роботи;- сам надсилає повідомлення, коли PIR-датчик фіксує рух (не частіше разу на хвилину).
Компоненти
- ESP32 DevKit
- Модуль реле (або світлодіод для тестів) — GPIO 26
- PIR-датчик руху HC-SR501 або AM312 — GPIO 27
| Модуль | ESP32 |
|---|---|
| Реле IN / VCC / GND | GPIO 26 / 5V / GND |
| PIR OUT / VCC / GND | GPIO 27 / 5V (HC-SR501) або 3V3 (AM312) / GND |
Вихід HC-SR501 — 3.3 В навіть при живленні 5 В, тож його можна під'єднувати напряму.
Бібліотеки
- UniversalTelegramBot (Brian Lough)
- ArduinoJson (Benoît Blanchon) — залежність
Створюємо бота
- У Telegram напишіть @BotFather →
/newbot→ задайте назву. Отримаєте токен вигляду123456789:AA.... - Напишіть @userinfobot — він повідомить ваш chat ID (число).
- Відкрийте свого нового бота й натисніть Start, інакше він не зможе вам писати.
Код
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
const char* WIFI_SSID = "YOUR_SSID";
const char* WIFI_PASS = "YOUR_PASSWORD";
#define BOT_TOKEN "123456789:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const String OWNER_CHAT_ID = "123456789"; // ваш chat ID
const int RELAY_PIN = 26;
const int PIR_PIN = 27;
const unsigned long MOTION_COOLDOWN = 60000; // 1 хв між сповіщеннями
WiFiClientSecure client;
UniversalTelegramBot bot(BOT_TOKEN, client);
unsigned long lastPoll = 0;
unsigned long lastMotionAlert = 0;
void handleMessages(int count) {
for (int i = 0; i < count; i++) {
const String chatId = bot.messages[i].chat_id;
const String text = bot.messages[i].text;
// Відповідаємо лише власнику — бота може знайти будь-хто
if (chatId != OWNER_CHAT_ID) {
bot.sendMessage(chatId, "Access denied", "");
continue;
}
if (text == "/on") {
digitalWrite(RELAY_PIN, HIGH);
bot.sendMessage(chatId, "💡 Увімкнено", "");
} else if (text == "/off") {
digitalWrite(RELAY_PIN, LOW);
bot.sendMessage(chatId, "🌑 Вимкнено", "");
} else if (text == "/status") {
String s = "Реле: " + String(digitalRead(RELAY_PIN) ? "ON" : "OFF");
s += "\nWi-Fi: " + String(WiFi.RSSI()) + " dBm";
s += "\nПрацює: " + String(millis() / 60000) + " хв";
bot.sendMessage(chatId, s, "");
} else {
bot.sendMessage(chatId, "Команди: /on /off /status", "");
}
}
}
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
pinMode(PIR_PIN, INPUT);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println(WiFi.localIP());
client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // перевіряємо сертифікат api.telegram.org
bot.sendMessage(OWNER_CHAT_ID, "🤖 ESP32 онлайн", "");
}
void loop() {
// Опитуємо Telegram раз на секунду
if (millis() - lastPoll > 1000) {
lastPoll = millis();
int n = bot.getUpdates(bot.last_message_received + 1);
while (n) {
handleMessages(n);
n = bot.getUpdates(bot.last_message_received + 1);
}
}
// Рух + пауза між сповіщеннями
if (digitalRead(PIR_PIN) == HIGH && millis() - lastMotionAlert > MOTION_COOLDOWN) {
lastMotionAlert = millis();
bot.sendMessage(OWNER_CHAT_ID, "🚶 Виявлено рух!", "");
}
}
Перевірка
- Після старту бот надішле вам «🤖 ESP32 онлайн».
- Напишіть
/status, потім/on— реле клацне. - Помахайте рукою перед PIR-датчиком — прийде сповіщення.
Корисно знати
- Налаштуйте HC-SR501: лівий потенціометр — чутливість, правий — тривалість сигналу; перемичку поставте в режим H (повторне спрацювання).
- Після ввімкнення PIR-датчику потрібно ~30–60 с на калібрування — у цей час можливі хибні спрацювання.
- Додайте меню-кнопки через BotFather →
/setcommands, щоб не набирати команди вручну. - Токен — це пароль. Не публікуйте скетч з ним на GitHub. Якщо токен витік —
/revokeу BotFather.
Ідеї
- Надсилати фото з ESP32-CAM при русі (
bot.sendPhotoByBinary). - Щоденний звіт з температурою з проєкту «Міні-метеостанція».
- Кілька користувачів — масив дозволених chat ID.