Last active
May 19, 2024 13:44
-
-
Save H3wastooshort/f49ee59c266f7ee8eb050086e65511c5 to your computer and use it in GitHub Desktop.
esp32 telegram security cam
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const String CHAT_ID = "-000000"; | |
const String BOTtoken = "xxx:xxxxxxx"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Rui Santos | |
Complete project details at https://RandomNerdTutorials.com/telegram-esp32-cam-photo-arduino/ | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files. | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
*/ | |
/* | |
Modified by H3 | |
*/ | |
#include <Arduino.h> | |
#include <WiFi.h> | |
#include <WiFiClientSecure.h> | |
#include "soc/soc.h" | |
#include "soc/rtc_cntl_reg.h" | |
#include "esp_camera.h" | |
#include <UniversalTelegramBot.h> | |
#include <ArduinoJson.h> | |
#include <WiFiManager.h> | |
#include "secret.h" | |
#define RED_LED 14 | |
#define GREEN_LED 2 | |
#define PIR_PIN 12 | |
#define BUZ_PIN 13 | |
bool manualPhoto = false; | |
bool armed = true; | |
bool use_flash = true; | |
bool use_buz = false; | |
WiFiClientSecure clientTCP; | |
UniversalTelegramBot bot(BOTtoken, clientTCP); | |
#define FLASH_LED_PIN 4 | |
//Checks for new messages every 1 second. | |
int botRequestDelay = 1000; | |
unsigned long lastTimeBotRan; | |
//CAMERA_MODEL_AI_THINKER | |
#define PWDN_GPIO_NUM 32 | |
#define RESET_GPIO_NUM -1 | |
#define XCLK_GPIO_NUM 0 | |
#define SIOD_GPIO_NUM 26 | |
#define SIOC_GPIO_NUM 27 | |
#define Y9_GPIO_NUM 35 | |
#define Y8_GPIO_NUM 34 | |
#define Y7_GPIO_NUM 39 | |
#define Y6_GPIO_NUM 36 | |
#define Y5_GPIO_NUM 21 | |
#define Y4_GPIO_NUM 19 | |
#define Y3_GPIO_NUM 18 | |
#define Y2_GPIO_NUM 5 | |
#define VSYNC_GPIO_NUM 25 | |
#define HREF_GPIO_NUM 23 | |
#define PCLK_GPIO_NUM 22 | |
void configInitCamera() { | |
camera_config_t config; | |
config.ledc_channel = LEDC_CHANNEL_0; | |
config.ledc_timer = LEDC_TIMER_0; | |
config.pin_d0 = Y2_GPIO_NUM; | |
config.pin_d1 = Y3_GPIO_NUM; | |
config.pin_d2 = Y4_GPIO_NUM; | |
config.pin_d3 = Y5_GPIO_NUM; | |
config.pin_d4 = Y6_GPIO_NUM; | |
config.pin_d5 = Y7_GPIO_NUM; | |
config.pin_d6 = Y8_GPIO_NUM; | |
config.pin_d7 = Y9_GPIO_NUM; | |
config.pin_xclk = XCLK_GPIO_NUM; | |
config.pin_pclk = PCLK_GPIO_NUM; | |
config.pin_vsync = VSYNC_GPIO_NUM; | |
config.pin_href = HREF_GPIO_NUM; | |
config.pin_sscb_sda = SIOD_GPIO_NUM; | |
config.pin_sscb_scl = SIOC_GPIO_NUM; | |
config.pin_pwdn = PWDN_GPIO_NUM; | |
config.pin_reset = RESET_GPIO_NUM; | |
config.xclk_freq_hz = 20000000; | |
config.pixel_format = PIXFORMAT_JPEG; | |
config.frame_size = FRAMESIZE_UXGA; | |
config.jpeg_quality = 10; //0-63 lower number means higher quality | |
config.fb_count = 1; | |
// camera init | |
esp_err_t err = esp_camera_init(&config); | |
if (err != ESP_OK) { | |
Serial.printf("Camera init failed with error 0x%x", err); | |
delay(1000); | |
ESP.restart(); | |
} | |
sensor_t* s = esp_camera_sensor_get(); | |
s->set_framesize(s, FRAMESIZE_SVGA); // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA | |
} | |
void handleNewMessages(int numNewMessages) { | |
Serial.print("Handle New Messages: "); | |
Serial.println(numNewMessages); | |
for (int i = 0; i < numNewMessages; i++) { | |
String chat_id = String(bot.messages[i].chat_id); | |
if (chat_id != CHAT_ID) { | |
bot.sendMessage(chat_id, "Unauthorized user", ""); | |
continue; | |
} | |
// Print the received message | |
String text = bot.messages[i].text; | |
Serial.println(text); | |
String from_name = bot.messages[i].from_name; | |
if (text.startsWith("/start")) { | |
String welcome = "Welcome , " + from_name + "\n"; | |
welcome += "/photo\n"; | |
welcome += "/arm | /disarm\n"; | |
welcome += "/flash_on | /flash_off\n"; | |
welcome += "/buz_on | /buz_off\n"; | |
welcome += "/status \n"; | |
bot.sendMessage(CHAT_ID, welcome, ""); | |
} else if (text.startsWith("/status")) { | |
String status = "WiFi RSSI: "; | |
status += WiFi.RSSI(); | |
status += "dBm\n"; | |
status += armed ? "ARMED" : "DISARMED"; | |
status += "\nBuzzer "; | |
status += use_buz ? "enabled" : "disabled"; | |
status += "\nFlash "; | |
status += use_flash ? "enabled" : "disabled"; | |
bot.sendMessage(CHAT_ID, status, ""); | |
} else if (text.startsWith("/arm")) { | |
armed = true; | |
bot.sendMessage(CHAT_ID, "ARMED", ""); | |
Serial.println("armed"); | |
} else if (text.startsWith("/disarm")) { | |
armed = false; | |
bot.sendMessage(CHAT_ID, "DISARMED", ""); | |
Serial.println("disarmed"); | |
} else if (text.startsWith("/flash_on")) { | |
use_flash = true; | |
bot.sendMessage(CHAT_ID, "Flash is on", ""); | |
Serial.println("flash on"); | |
} else if (text.startsWith("/flash_off")) { | |
use_flash = false; | |
bot.sendMessage(CHAT_ID, "Flash is off", ""); | |
Serial.println("flash off"); | |
} else if (text.startsWith("/buz_on")) { | |
use_buz = true; | |
bot.sendMessage(CHAT_ID, "Buzzer is on", ""); | |
Serial.println("buz on"); | |
} else if (text.startsWith("/buz_off")) { | |
use_buz = false; | |
bot.sendMessage(CHAT_ID, "Buzzer is off", ""); | |
Serial.println("buz off"); | |
} else if (text.startsWith("/photo")) { | |
manualPhoto = true; | |
bot.sendMessage(CHAT_ID, "sending manual photo...", ""); | |
Serial.println("New photo request"); | |
} | |
} | |
} | |
String sendPhotoTelegram() { | |
const char* myDomain = "api.telegram.org"; | |
String getAll = ""; | |
String getBody = ""; | |
digitalWrite(FLASH_LED_PIN, HIGH); | |
delay(10); | |
camera_fb_t* fb = esp_camera_fb_get(); | |
if (!fb) { | |
Serial.println("Camera capture failed"); | |
bot.sendMessage(CHAT_ID, "CAMERA ERROR!", ""); | |
delay(1000); | |
ESP.restart(); | |
return "Camera capture failed"; | |
} | |
delay(10); | |
digitalWrite(FLASH_LED_PIN, LOW); | |
Serial.println("Connect to " + String(myDomain)); | |
if (clientTCP.connect(myDomain, 443)) { | |
Serial.println("Connection successful"); | |
String head = "--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"chat_id\"; \r\n\r\n" + CHAT_ID + "\r\n--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"esp32-cam.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n"; | |
String tail = "\r\n--RandomNerdTutorials--\r\n"; | |
uint16_t imageLen = fb->len; | |
uint16_t extraLen = head.length() + tail.length(); | |
uint16_t totalLen = imageLen + extraLen; | |
clientTCP.println("POST /bot" + BOTtoken + "/sendPhoto HTTP/1.1"); | |
clientTCP.println("Host: " + String(myDomain)); | |
clientTCP.println("Content-Length: " + String(totalLen)); | |
clientTCP.println("Content-Type: multipart/form-data; boundary=RandomNerdTutorials"); | |
clientTCP.println(); | |
clientTCP.print(head); | |
uint8_t* fbBuf = fb->buf; | |
size_t fbLen = fb->len; | |
for (size_t n = 0; n < fbLen; n = n + 1024) { | |
if (n + 1024 < fbLen) { | |
clientTCP.write(fbBuf, 1024); | |
fbBuf += 1024; | |
} else if (fbLen % 1024 > 0) { | |
size_t remainder = fbLen % 1024; | |
clientTCP.write(fbBuf, remainder); | |
} | |
} | |
clientTCP.print(tail); | |
esp_camera_fb_return(fb); | |
int waitTime = 10000; // timeout 10 seconds | |
long startTimer = millis(); | |
boolean state = false; | |
while ((startTimer + waitTime) > millis()) { | |
Serial.print("."); | |
delay(100); | |
while (clientTCP.available()) { | |
char c = clientTCP.read(); | |
if (state == true) getBody += String(c); | |
if (c == '\n') { | |
if (getAll.length() == 0) state = true; | |
getAll = ""; | |
} else if (c != '\r') | |
getAll += String(c); | |
startTimer = millis(); | |
} | |
if (getBody.length() > 0) break; | |
} | |
clientTCP.stop(); | |
Serial.println(getBody); | |
} else { | |
getBody = "Connected to api.telegram.org failed."; | |
Serial.println("Connected to api.telegram.org failed."); | |
} | |
return getBody; | |
} | |
void setup() { | |
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); | |
pinMode(RED_LED, OUTPUT); | |
pinMode(GREEN_LED, OUTPUT); | |
digitalWrite(RED_LED, HIGH); | |
digitalWrite(GREEN_LED, HIGH); | |
pinMode(BUZ_PIN, OUTPUT); | |
ledcSetup(3, 0, 14); | |
ledcAttachPin(BUZ_PIN, 3); | |
pinMode(PIR_PIN, INPUT); | |
// Init Serial Monitor | |
Serial.begin(115200); | |
// Set LED Flash as output | |
pinMode(FLASH_LED_PIN, OUTPUT); | |
digitalWrite(FLASH_LED_PIN, LOW); | |
// Config and init the camera | |
configInitCamera(); | |
// Connect to Wi-Fi | |
Serial.print("Connecting"); | |
WiFiManager wm; | |
wm.setConfigPortalTimeout(60); | |
if (!wm.autoConnect()) { | |
Serial.println("Failed to connect"); | |
ESP.restart(); | |
} | |
clientTCP.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.print("."); | |
delay(500); | |
} | |
Serial.println(); | |
Serial.print("ESP32-CAM IP Address: "); | |
Serial.println(WiFi.localIP()); | |
bot.sendMessage(CHAT_ID, "r e a d y", ""); | |
tone(BUZ_PIN, 500); | |
delay(100); | |
tone(BUZ_PIN, 1000); | |
delay(100); | |
noTone(BUZ_PIN); | |
digitalWrite(RED_LED, LOW); | |
digitalWrite(GREEN_LED, LOW); | |
} | |
uint64_t lastPhotoTime = 0; | |
void loop() { | |
digitalWrite(RED_LED, armed); | |
digitalWrite(GREEN_LED, !armed); | |
if (digitalRead(PIR_PIN) && armed) { | |
if (millis() - lastPhotoTime > 1000) { | |
bot.sendMessage(CHAT_ID, "INTRUDER ALERT!", ""); | |
sendPhotoTelegram(); | |
} | |
if (use_buz) tone(BUZ_PIN, (millis() * 2) % 1000); | |
} else { | |
noTone(BUZ_PIN); | |
} | |
if (manualPhoto) { | |
Serial.println("Manual photo"); | |
sendPhotoTelegram(); | |
sendPhotoTelegram(); | |
sendPhotoTelegram(); | |
manualPhoto = false; | |
} | |
if (millis() > lastTimeBotRan + botRequestDelay) { | |
int numNewMessages = bot.getUpdates(bot.last_message_received + 1); | |
while (numNewMessages) { | |
Serial.println("got response"); | |
handleNewMessages(numNewMessages); | |
numNewMessages = bot.getUpdates(bot.last_message_received + 1); | |
} | |
lastTimeBotRan = millis(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment