آموزش آردوینو اینترنت اشیا IOT برد Esp32 برد ESP8266 ماژول دوربین

عکاسی با دوربین ESP-Cam و ارسال تصاویر به تلگرام با برد ESP32

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM
نوشته شده توسط CiferTech

برد ESP-Cam کاربردهای مختلفی دارد. با توجه به تراشه قدرتمند و قابلیت نصب دوربین به ابن برد، امکانات دیگری از جمله ثبت تصاویر و یا ارسال آن‌ها را دارد. در این آموزش با استفاده از برد ESP32-CAM تصاویر ثبت شده به ربات تلگرامی خود ارسال میکنیم. کافیست از طریق ربات تلگرامی که در ادامه این آموزش روش ساخت آن توضیح داده می‌شود، دستور تصویربرداری و ارسال آن را به برد می‌دهیم. همچنین تمام فرآیند را توسط ربات تلگرامی کنترل می‌کنیم. تنها با استفاده از چند دستور از قبل تایین شده؛ برای مثال با فرمان /Photo ربات درخواست ثبت تصویر را به سمت برد ESP32-CAM ارسال میکند. در ادامه این آموزش با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.

 


تراشه ESP32


ESP32 نسل پیشرفته ESP8266 است. یکی از تفاوت‌های آن بلوتوث داخلی‌اش می‌باشد. همچنین دارای هسته وایفای ۲,۴ گیگا هرتزی و بلوتوث داخلی تولید شده با تکنولوژی ۴۰ نانومتری شرکت TSMC می‌باشد. این ماژول دارای بهترین پرفورمنس در مصرف انرژی می‌باشد یعنی با کمترین مصرف انرژی بهترین نتیجه را برای ما به همراه دارد. اگر بخواهیم دقیق‌تر به این برد نگاه کنیم باید بگوییم که این یک chip است که پلتفرم NodeMCU در اون پیاده سازی شده که به این نوع چیپ ها System on a chip microcontrollers هم گفته می‌شود.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM

از دیگر امکانات ماژول esp32-cam می‌توان به دوربین OV2640 با قابلیت ثبت تصویر با فرمت JPEG, BMP, grayscale اشاره کرد. همچنین با LED flash مونتاژ شده بر روی این ماژول قادر به تصویر برداری در مکان‌های تاریک نیز خواهید بود. یکی از ویژگی‌های کاربردی این ماژول ورودی micro SD با قابلیت ارتقا تا ۴GB است که به کاربر اجازه ذخیره تصاویر را هم می‌دهد.

 


ماژول FTDI programmer


برای پروگرام کردن ESP32-cam بدلیل اینکه پروگرامر داخلی برای قرار داده نشده، از این ماژول استفاده می کنیم در واقع این ماژول مبدل USB به TTL می باشد که از Rx و Tx با برد ESP-CAM و از طریق ارتباط USB با سیستم مورد استفاده ما ارتباط برقرار میکند. در این ماژول دو سطحی ولتاژ ۳٫۳ و ۵ ولت وجود دارد که در پروژه های مختلف می تواند مفید باشد.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM


تلگرام Telegram


تلگرام یک پیام رسان فوری مبتنی بر Cloud و خدمات صوتی از طریق IP است. که به راحتی می توانید آن را در تلفن هوشمند (Android و iPhone) یا رایانه (PC ، Mac و Linux) نصب کنید. تلگرام به ما امکان می دهد ربات هایی ایجاد کنیم و همچنین بتوانیم با آنها تعامل کنیم. ربات ها اپلیکیشن های Third-Party هستند که داخل تلگرام اجرا می شوند و ما با کامند و دستوراتی آن هارا  کنترل میکنیم که در واقع این کامند ها درخواست های از نوع HTTPS هستن که برای API تلگرام ارسال می شود.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM


ساخت ربات تلگرام برای ESP32-cam


بعد از نصب تلگرام مانند تصویر زیر در قسمت جستجو تلگرام، کلمه “BotFather” را سرچ کنید؛ دقت کنید ربات تایید شده از طرف تلگرام را انتخاب کنید.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM

سپس بر روی “START” کلیک کنید و یا از دستور /start برای شروع استفاده کنید.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM

در این بخش با استفاده از دستور /newbot اقدام به ساخت یک ربات تلگرامی میکنیم.

تنظیمات ربات تلگرام برای ثبت و ارسال تصاویر به تلگرام با ESP32-CAM

در این مرحله یک اسم دلخواه برای ربات خود بگذارید.

تنظیمات ربات تلگرام برای ثبت و ارسال تصاویر به تلگرام با ESP32-CAM

در مرحله بعد یک ID  برای ربات خود انتخاب کنید؛ دقت داشته باشید که انتهای ID باید با کلمه Bot یا _bot تمام شود.

ثبت و ارسال تصاویر به تلگرام با ESP32-CAM - تنظیمات تلگرام

تبریک! ربات ساخته شد؛ الان ما یک توکن در اختیار داریم که از طریق این توکن می توانیم به HTTP API دسترسی داشته باشیم.

ثبت و ارسال تصاویر به ربات تلگرام با برد ESP32-CAM - دیجی اسپارک

 


دریافت UserID از تلگرام


دریافت userID به امنیت ربات ما کمک می کند برای مثال الان شما ID ربات من را در اختیار داری پس می توانید براحتی کنترل دوربین من را بدست بگیرید. اما با یوزر ایدی می توانیم تنها دسترسی ربات را به یک یا چند کاربر خاص اختصاص دهیم. طبق تصویر زیر ابتدا اسم ربات یعنی myidbot را سرچ کنید، دقت کنید که از ربا ای متفرقه استفاده نکنید؛ سپس بر روی START کلیک کنید و یا از دستور /start استفاده کنید.

تنظیمات ربات تلگرام و دریافت ChatID - دیجی اسپارک

در این مرحله از فرمان /getid برای دریافت ID استفاده کنید.

دستور getid برای دریافت ID در تلگرام - دیجی اسپارک

خب اینم از ID شما، در ادامه از این id استفاده خواهیم کرد.

مشاهده ID تلگرام با دستور getid - دیجی اسپارک

 


نصب کتابخانه‌های مورد نیاز


ابتدا طبق مراحل زیر پیش بروید و برای برد esp32-cam کتابخانه مرجع برای ربات های تلگرامی را نصب کنید.

  1. از این لینک کتابخانه را دانلود کنید.
  2. این مسیر را دنبال کنید Sketch Include Library > Add.ZIP Library
  3. فایل .zip که قبل تر دانلود کردید را انتخاب کنید.

روش نصب کتابخانه در نرم افزار آردوینو با ESP32-CAM - دیجی اسپارک

 

حالا با دنبال کردن مراحل زیر کتابخانه Arduinojson را نصب کنید.

  1. این مسیر را دنبال کنید Sketch Include Library > Manage Libraries
  2. کلمه Arduinojson را جستجو کنید.
  3. کتابخانه را نصب کنید.

نصب کتابخانه های مورد نیاز به تلگرام با ESP32-CAM - دیجی اسپارک انتخاب کتابخانه برد ESP32-CAM - دیجی اسپارک

 


کد ارسال تصویر به تلگرام با ESP32-CAM


در کد زیر باید مواردی را نسبت به اطلاعات خود ویرایش کنید، از جمله اطلاعات اینترنت خود “ssid و پسوورد”، توکن ربات تلگرامی که ساخته اید و همچنین userid که چند مرحله قبل بدست آوردید.

#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>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Initialize Telegram BOT
String BOTtoken = "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";  // your Bot Token (Get from Botfather)

// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
String CHAT_ID = "XXXXXXXXXX";

bool sendPhoto = false;

WiFiClientSecure clientTCP;
UniversalTelegramBot bot(BOTtoken, clientTCP);

#define FLASH_LED_PIN 4
bool flashState = LOW;

//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;

  //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 = 2;
  } 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();
  }

  // Drop down frame size for higher initial frame rate
  sensor_t * s = esp_camera_sensor_get();
  s->set_framesize(s, FRAMESIZE_CIF);  // 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 == "/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 == "/flash") {
      flashState = !flashState;
      digitalWrite(FLASH_LED_PIN, flashState);
      Serial.println("Change flash LED state");
    }
    if (text == "/photo") {
      sendPhoto = true;
      Serial.println("New photo request");
    }
  }
}

String sendPhotoTelegram() {
  const char* myDomain = "api.telegram.org";
  String getAll = "";
  String getBody = "";

  camera_fb_t * 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";

    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 (c == '\n') 
          {
            if (getAll.length()==0) state=true; 
            getAll = "";
          } 
          else if (c != '\r')
            getAll += String(c);
          if (state==true) getBody += 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); 
  // Init Serial Monitor
  Serial.begin(115200);

  // Set LED Flash as output
  pinMode(FLASH_LED_PIN, OUTPUT);
  digitalWrite(FLASH_LED_PIN, flashState);

  // Config and init the camera
  configInitCamera();

  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("ESP32-CAM IP Address: ");
  Serial.println(WiFi.localIP()); 
}

void loop() {
  if (sendPhoto) {
    Serial.println("Preparing 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();
  }
}

 

 


توضیحات تکمیلی برای کد


در این قسمت اطلاعات وای فای خود را وارد کنید:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

 

در این بخش userid که از طریق بات IDBOT بدست آوردید را وارد کنید:

String CHAT_ID = "XXXXXXXXXX";

 

و در نهایت در این قسمت توکن ربات تلگرامی خود را وارد کنید:

String BOTtoken = "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

 


نتیجه پروژه


در نهایت زمانی که در ربات تلگرامی خود فرمان /start را وارد کنید، فعالیت ربات شروع می شود، با فرمان /photo ربات ببرد ESP-CAM فرمان ثبت تصویر را ارسال می کند و تصویر به شما نمایش داده می شود؛ همچنین با فرمان /flash می توانید led موجود بر روی برد را را فعال و غیر فعال کنید.

 

 


وسایل مورد نیاز


برد ESP32-CAM

ماژول FTDI programer

کابل فلت برای اتصالات

برد برد برای اتصالات

 

چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریع‌ترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند می‌توانید از همین طریق اطلاع رسانی کنید.

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی , از وبسایت دیجی اسپارک حمایت کنید.

 

درباره نویسنده

CiferTech

تبادل نظر و رفع عیب با ثبت دیدگاه

۴۲ دیدگاه