Translate

ESP32 Cam Kirim Foto ke Telegram

ESP32 Cam Kirim Foto ke Telegram
 

        Pada kesempatan kali ini saya akan menjelaskan bagaimana cara membuat sebuah alat dengan ESP32 cam untuk mengirim gambar ke telegram, fungsi dari alat ini yaitu untuk fitur pemantauan, jadi misal lagi di tempat kerja lalu ingin melihat kondisi real yang ada disana bisa dipantau via telegram dan gambarnya bisa di share ke group atau status media sosial. untuk lebih jelasnya berkut adalah koding dan haslnya.
 
 
1. Hasilnya
 

 
2. Program ESP32 Cam
 
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "esp_camera.h"

// =====================================================
// WIFI
// =====================================================


const char* WIFI_SSID = "hotspotkuwifi";
const char* WIFI_PASSWORD = "123456789";

// ================================
// TELEGRAM
// ================================

// Gunakan token baru
String BOT_TOKEN = "8599566365:AAHWGXsuTQp5IROs0d9HIV9gFd9DyG8xx1x";


// Chat ID tujuan
const char* CHAT_ID = "7796726911";

// =====================================================
// PIN ESP32-CAM 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

// =====================================================
// TELEGRAM UPDATE
// =====================================================

long lastUpdateID = 0;

unsigned long lastCheck = 0;

const unsigned long CHECK_INTERVAL = 1000;


// =====================================================
// INISIALISASI CAMERA
// =====================================================

bool setupCamera() {

  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;

  // Kompatibilitas beberapa versi ESP32 Core

#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 2

  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;

#else

  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;

#endif

  config.pin_pwdn  = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;

  config.xclk_freq_hz = 20000000;

  // Langsung menghasilkan JPG
  config.pixel_format = PIXFORMAT_JPEG;

  // Mulai VGA supaya stabil
  config.frame_size = FRAMESIZE_VGA;

  config.jpeg_quality = 12;

  config.fb_count = 1;


  Serial.println("Memulai kamera...");


  esp_err_t err =
    esp_camera_init(&config);


  if (err != ESP_OK) {

    Serial.printf(
      "Camera gagal. Error: 0x%x\n",
      err
    );

    return false;
  }


  sensor_t* sensor =
    esp_camera_sensor_get();


  sensor->set_framesize(
    sensor,
    FRAMESIZE_VGA
  );


  sensor->set_quality(
    sensor,
    12
  );


  Serial.println(
    "Camera berhasil."
  );


  return true;
}


// =====================================================
// CONNECT WIFI
// =====================================================

void connectWiFi() {

  WiFi.mode(WIFI_STA);

  WiFi.begin(
    WIFI_SSID,
    WIFI_PASSWORD
  );


  Serial.print(
    "Menghubungkan WiFi"
  );


  while (
    WiFi.status() != WL_CONNECTED
  ) {

    delay(500);

    Serial.print(".");
  }


  Serial.println();

  Serial.println(
    "WiFi terhubung"
  );


  Serial.print(
    "IP: "
  );

  Serial.println(
    WiFi.localIP()
  );


  Serial.print(
    "Signal: "
  );

  Serial.print(
    WiFi.RSSI()
  );

  Serial.println(
    " dBm"
  );
}


// =====================================================
// HAPUS WEBHOOK
// Supaya getUpdates bisa digunakan
// =====================================================

void deleteWebhook() {

  WiFiClientSecure client;

  client.setInsecure();


  HTTPClient https;


  String url =
    "https://api.telegram.org/bot"
    + BOT_TOKEN
    + "/deleteWebhook?drop_pending_updates=true";


  Serial.println(
    "Menyiapkan Telegram..."
  );


  if (
    https.begin(
      client,
      url
    )
  ) {

    int httpCode =
      https.GET();


    Serial.print(
      "deleteWebhook HTTP: "
    );

    Serial.println(
      httpCode
    );


    https.end();
  }
}


// =====================================================
// KIRIM FOTO JPG KE TELEGRAM
// =====================================================

bool sendPhotoTelegram(
  String chatID
) {

  Serial.println();
  Serial.println(
    "=============================="
  );

  Serial.println(
    "MENGAMBIL FOTO"
  );

  Serial.println(
    "=============================="
  );


  // ===================================================
  // BUANG FRAME PERTAMA
  // ===================================================

  camera_fb_t* fb =
    esp_camera_fb_get();


  if (fb) {

    esp_camera_fb_return(fb);

    fb = NULL;
  }


  delay(200);


  // ===================================================
  // AMBIL FOTO BARU
  // ===================================================

  fb =
    esp_camera_fb_get();


  if (!fb) {

    Serial.println(
      "Gagal mengambil gambar!"
    );

    return false;
  }


  Serial.print(
    "Resolusi: "
  );

  Serial.print(
    fb->width
  );

  Serial.print(
    " x "
  );

  Serial.println(
    fb->height
  );


  Serial.print(
    "Ukuran JPG: "
  );

  Serial.print(
    fb->len
  );

  Serial.println(
    " bytes"
  );


  // ===================================================
  // CONNECT TELEGRAM
  // ===================================================

  WiFiClientSecure client;

  client.setInsecure();

  client.setTimeout(15000);


  Serial.println(
    "Menghubungkan Telegram..."
  );


  if (
    !client.connect(
      "api.telegram.org",
      443
    )
  ) {

    Serial.println(
      "Koneksi Telegram gagal!"
    );


    esp_camera_fb_return(fb);

    return false;
  }


  Serial.println(
    "Telegram connected"
  );


  // ===================================================
  // MULTIPART FORM DATA
  // ===================================================

  String boundary =
    "ESP32CAMBoundary";


  String head =

    "--" + boundary + "\r\n"

    "Content-Disposition: form-data; "
    "name=\"chat_id\"\r\n\r\n"

    + chatID +

    "\r\n"

    "--" + boundary + "\r\n"

    "Content-Disposition: form-data; "
    "name=\"photo\"; "
    "filename=\"esp32cam.jpg\"\r\n"

    "Content-Type: image/jpeg\r\n\r\n";


  String tail =

    "\r\n--"
    + boundary
    + "--\r\n";


  size_t contentLength =
    head.length()
    +
    fb->len
    +
    tail.length();


  // ===================================================
  // HTTP POST
  // ===================================================

  client.print(
    "POST /bot"
  );

  client.print(
    BOT_TOKEN
  );

  client.println(
    "/sendPhoto HTTP/1.1"
  );


  client.println(
    "Host: api.telegram.org"
  );


  client.println(
    "Connection: close"
  );


  client.print(
    "Content-Type: multipart/form-data; boundary="
  );

  client.println(
    boundary
  );


  client.print(
    "Content-Length: "
  );

  client.println(
    contentLength
  );


  client.println();


  // ===================================================
  // KIRIM HEADER
  // ===================================================

  client.print(
    head
  );


  // ===================================================
  // KIRIM DATA JPG
  // ===================================================

  size_t sent = 0;

  unsigned long sendTimeout =
    millis();


  while (
    sent < fb->len
  ) {

    size_t remaining =
      fb->len - sent;


    size_t chunkSize =
      remaining > 1024
      ? 1024
      : remaining;


    size_t written =
      client.write(
        fb->buf + sent,
        chunkSize
      );


    if (written > 0) {

      sent += written;

      sendTimeout =
        millis();

    } else {

      if (
        millis() - sendTimeout >
        10000
      ) {

        Serial.println(
          "Timeout mengirim JPG"
        );

        break;
      }

      delay(10);
    }


    delay(1);
  }


  client.print(
    tail
  );


  Serial.print(
    "JPG terkirim: "
  );

  Serial.print(
    sent
  );

  Serial.print(
    "/"
  );

  Serial.println(
    fb->len
  );


  // Frame sudah selesai
  esp_camera_fb_return(fb);

  fb = NULL;


  // ===================================================
  // BACA RESPONSE TELEGRAM
  // ===================================================

  bool telegramOK =
    false;


  unsigned long timeout =
    millis();


  Serial.println(
    "Menunggu response Telegram..."
  );


  while (
    millis() - timeout <
    15000
  ) {

    while (
      client.available()
    ) {

      String line =
        client.readStringUntil('\n');


      Serial.println(
        line
      );


      if (
        line.indexOf(
          "\"ok\":true"
        ) >= 0
      ) {

        telegramOK =
          true;
      }


      timeout =
        millis();
    }


    if (
      !client.connected()
    ) {

      break;
    }


    delay(10);
  }


  client.stop();


  if (telegramOK) {

    Serial.println();
    Serial.println(
      "FOTO BERHASIL DIKIRIM!"
    );

  } else {

    Serial.println();
    Serial.println(
      "FOTO GAGAL DIKIRIM!"
    );
  }


  return telegramOK;
}


// =====================================================
// CEK PESAN TELEGRAM
// =====================================================

void checkTelegram() {

  WiFiClientSecure client;

  client.setInsecure();


  HTTPClient https;


  String url =
    "https://api.telegram.org/bot"
    + BOT_TOKEN
    + "/getUpdates?offset="
    + String(lastUpdateID + 1)
    + "&limit=5&timeout=0";


  if (
    !https.begin(
      client,
      url
    )
  ) {

    Serial.println(
      "HTTP Telegram gagal"
    );

    return;
  }


  int httpCode =
    https.GET();


  if (
    httpCode != 200
  ) {

    Serial.print(
      "getUpdates HTTP Error: "
    );

    Serial.println(
      httpCode
    );


    https.end();

    return;
  }


  String payload =
    https.getString();


  https.end();


  // ===================================================
  // PARSE JSON
  // ===================================================

  DynamicJsonDocument doc(
    16384
  );


  DeserializationError error =
    deserializeJson(
      doc,
      payload
    );


  if (error) {

    Serial.print(
      "JSON error: "
    );

    Serial.println(
      error.c_str()
    );

    return;
  }


  JsonArray results =
    doc["result"].as<JsonArray>();


  for (
    JsonObject update : results
  ) {

    long updateID =
      update["update_id"] | 0;


    if (
      updateID >
      lastUpdateID
    ) {

      lastUpdateID =
        updateID;
    }


    // Pastikan update berisi message

    if (
      update["message"].isNull()
    ) {

      continue;
    }


    const char* textRaw =
      update["message"]["text"] | "";


    String text =
      String(textRaw);


    // Telegram chat ID sekarang bisa besar.
    // Ambil sebagai 64-bit.

    int64_t chatIDNumber =
      update["message"]["chat"]["id"]
      .as<int64_t>();


    char chatBuffer[32];


    snprintf(
      chatBuffer,
      sizeof(chatBuffer),
      "%lld",
      (long long)chatIDNumber
    );


    String chatID =
      String(chatBuffer);


    Serial.println();
    Serial.println(
      "------------------------------"
    );

    Serial.print(
      "Chat ID : "
    );

    Serial.println(
      chatID
    );


    Serial.print(
      "Pesan   : "
    );

    Serial.println(
      text
    );


    // =================================================
    // PERINTAH /foto
    // =================================================

    if (
      text == "/foto"
      ||
      text.startsWith(
        "/foto@"
      )
    ) {

      Serial.println(
        "Perintah /foto diterima"
      );


      sendPhotoTelegram(
        chatID
      );
    }
  }
}


// =====================================================
// SETUP
// =====================================================

void setup() {

  Serial.begin(
    115200
  );


  delay(1000);


  Serial.println();
  Serial.println(
    "================================"
  );

  Serial.println(
    "ESP32-CAM TELEGRAM /FOTO"
  );

  Serial.println(
    "================================"
  );


  // CAMERA

  if (
    !setupCamera()
  ) {

    Serial.println(
      "Camera gagal."
    );

    return;
  }


  // WIFI

  connectWiFi();


  // getUpdates tidak bisa digunakan
  // jika bot masih memakai webhook.

  deleteWebhook();


  Serial.println();
  Serial.println(
    "================================"
  );

  Serial.println(
    "SISTEM SIAP"
  );

  Serial.println(
    "Kirim /foto ke Telegram"
  );

  Serial.println(
    "================================"
  );
}


// =====================================================
// LOOP
// =====================================================

void loop() {

  // Reconnect WiFi

  if (
    WiFi.status() !=
    WL_CONNECTED
  ) {

    connectWiFi();
  }


  // Cek Telegram setiap 1 detik

  if (
    millis() - lastCheck >=
    CHECK_INTERVAL
  ) {

    lastCheck =
      millis();


    checkTelegram();
  }
}
 
 
 
3. VIDEO HASILNYA
 


No comments:

Post a Comment