#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "esp_camera.h"
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
const int rele= 48; ///pin do rele
const int pir =21; //pin do detector de movimento
bool detecta_mov = true; ////detecta movimento por defeito
bool a_rele = true; ///aciona rle quando movimento detectado por defeito
const char* ssid = "Mxxxxxxxxx"; ///senha do wifi
const char* password = "aoaf6722";
// Initialize Telegram BOT
String BOTtoken = "7707971477:HezxxxxxxwstUrBKHctUcS0I";
String CHAT_ID = "8284444"; // your Bot Token (Get from Botfather)
bool sendPhoto = false;
WiFiClientSecure clientTCP;
UniversalTelegramBot bot(BOTtoken, clientTCP);
//Checks for new messages every 1 second.
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5
#define Y9_GPIO_NUM 16
#define Y8_GPIO_NUM 17
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 12
#define Y5_GPIO_NUM 10
#define Y4_GPIO_NUM 8
#define Y3_GPIO_NUM 9
#define Y2_GPIO_NUM 11
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_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.grab_mode = CAMERA_GRAB_LATEST;
//init with high specs to pre-allocate larger buffers
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10; //0-63 lower number means higher quality
//config.fb_count = 1;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12; //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();
}
}
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 == "/start") {
String welcome = "Welcome , " + from_name + "\n";
welcome += "Use the following commands to interact with the ESP32-CAM \n";
welcome += "/photo : takes a new photo\n";
welcome += "/flash : toggles flash LED \n";
bot.sendMessage(CHAT_ID, welcome, "");
}
if (text == "/ron") {
digitalWrite(rele, HIGH);
}
if (text == "/roff") {
digitalWrite(rele, LOW);
}
if (text == "/alarmeon") {
bool detecta_mov = true; ////detecta movimento
}
if (text == "/alarmeoff") {
bool detecta_mov = false; ////nao detecta movimento
}
if (text == "/releon") {
bool a_rele = true; ///aciona rele quando movimento detectado
}
if (text == "/releoff") {
bool a_rele = false; ///nao aciona rle quando movimento detectado
}
if (text == "/photo") {
sendPhoto = true;
Serial.println("New photo request");
}
}
}
String sendPhotoTelegram() {
const char* myDomain = "api.telegram.org";
String getAll = "";
String getBody = "";
//Dispose first picture because of bad quality
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose the buffered image
// Take a new photo
fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
delay(1000);
ESP.restart();
return "Camera capture failed";
}
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";
size_t imageLen = fb->len;
size_t extraLen = head.length() + tail.length();
size_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(){
Serial.begin(115200);
pinMode(rele,OUTPUT);
pinMode(pir,INPUT);
// Config and init the camera
configInitCamera();
// roda 180 graus para algumas cameras é necessario
sensor_t * s = esp_camera_sensor_get();
s->set_vflip(s, 1); // espelha verticalmente
s->set_hmirror(s, 1); // espelha horizontalmente
//------ fim da rotacao --------
// Connect to Wi-Fi
WiFi.mode(WIFI_STA);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
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());
}
void loop() {
const int IP=digitalRead(pir); //le o valor do sensor de movimento
delay(100);
if(IP==1){ ///se detectou movimento
if(a_rele){
digitalWrite(rele,HIGH); ///liga o rele
delay(500);
}
if(detecta_mov){
sendPhotoTelegram();
delay(180000); // evita spam, 3 minutos
}
}
if (sendPhoto) { ///ver photo
sendPhotoTelegram();
sendPhoto = 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();
}
delay(100);
}