ESP32-CAM merupakan salah satu modul mikrokontroler berbasis ESP32 yang telah dilengkapi dengan kamera OV2640 dan konektivitas Wi-Fi. Berkat fitur tersebut, ESP32-CAM banyak digunakan dalam berbagai proyek Internet of Things (IoT), seperti sistem keamanan, pemantauan jarak jauh, smart home, dan otomasi industri. Pada tutorial ini, ESP32-CAM akan dihubungkan dengan Telegram Bot sehingga pengguna dapat mengambil foto dari jarak jauh hanya dengan mengirimkan perintah melalui aplikasi Telegram. Setelah menerima perintah, ESP32-CAM akan mengambil gambar menggunakan kamera yang terpasang, kemudian mengirimkan hasil foto tersebut kembali ke akun Telegram pengguna melalui internet. Fitur yang akan dibuat pada proyek ini meliputi:
- Menghubungkan ESP32-CAM dengan Telegram Bot.
- Mengambil foto menggunakan perintah Telegram.
- Mengirim hasil foto secara otomatis ke Telegram.
- Mengendalikan LED flash bawaan ESP32-CAM.
- Menampilkan daftar perintah yang tersedia.
- Membatasi akses hanya untuk pengguna yang terdaftar.
Dengan memanfaatkan Telegram Bot API, sistem dapat diakses dari mana saja selama perangkat dan pengguna sama-sama terhubung ke internet.
Mengenal Telegram Bot
Telegram menyediakan fitur Bot yang memungkinkan pengguna berinteraksi dengan sistem otomatis melalui pesan. Bot dapat menerima perintah, memproses data, serta mengirimkan respons sesuai program yang dibuat. Pada proyek ini, Telegram Bot berfungsi sebagai media komunikasi antara pengguna dan ESP32-CAM. Ketika pengguna mengirimkan perintah melalui Telegram, ESP32-CAM akan membaca pesan tersebut menggunakan Telegram Bot API, menjalankan perintah yang sesuai, kemudian mengirimkan hasilnya kembali ke Telegram. Secara umum, alur kerja sistem dapat dijelaskan sebagai berikut:
1. Pengguna mengirimkan perintah ke Telegram Bot.
2. Telegram menyimpan pesan pada server Telegram.
3. ESP32-CAM memeriksa pesan baru melalui Telegram Bot API.
4. Perintah diproses oleh ESP32-CAM.
5. Hasil berupa pesan atau foto dikirim kembali ke Telegram.
Membuat Telegram Bot
Sebelum ESP32-CAM dapat berkomunikasi dengan Telegram, terlebih dahulu perlu dibuat sebuah Telegram Bot.
1. Unduh dan instal aplikasi Telegram pada perangkat yang digunakan.
2. Selanjutnya cari akun BotFather pada kolom pencarian Telegram atau buka tautan berikut https://t.me/botfather
Tekan tombol Start, kemudian kirim perintah berikut /newbot. BotFather akan meminta nama bot dan username bot yang akan digunakan.
Jika proses pembuatan berhasil, BotFather akan memberikan Bot Token yang nantinya digunakan oleh ESP32-CAM untuk mengakses Telegram Bot API.
Simpan token tersebut karena akan digunakan pada program Arduino IDE.
Mendapatkan Telegram User ID
Agar sistem lebih aman, ESP32-CAM dapat dikonfigurasi untuk hanya merespons pesan dari pengguna tertentu. Untuk mendapatkan User ID Telegram, cari bot @myidbot atau buka tautan berikut https://t.me/myidbot
Tekan tombol Start, kemudian kirim perintah /getid. Bot akan mengirimkan User ID akun Telegram Anda.
Simpan nilai tersebut karena akan digunakan pada program untuk memverifikasi pengguna yang diperbolehkan mengakses sistem.
Instalasi Library
Pada proyek ini digunakan dua library tambahan, yaitu:
- Universal Arduino Telegram Bot
- ArduinoJson
Library Universal Arduino Telegram Bot digunakan untuk berkomunikasi dengan Telegram Bot API, sedangkan ArduinoJson digunakan untuk memproses data JSON yang dikirimkan oleh server Telegram.
1. Unduh dan instal library Universal Arduino Telegram Bot melalui file ZIP, kemudian tambahkan ke Arduino IDE melalui menu Sketch > Include Library > Add .ZIP Library.
2. Selanjutnya instal library ArduinoJson melalui Library Manager Arduino IDE.
Program ESP32-CAM Telegram Camera
Salin program berikut ke Arduino IDE.
#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_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 == "/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 = "";
//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(){
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);
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() {
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();
}
}
Catatan: Sebelum melakukan upload program, sesuaikan terlebih dahulu nilai SSID, password Wi-Fi, Bot Token, dan Chat ID sesuai konfigurasi yang digunakan.
Penjelasan Program
1. Import Library
Pada bagian awal program dilakukan pemanggilan beberapa library yang diperlukan untuk mendukung koneksi Wi-Fi, komunikasi HTTPS, pengendalian kamera, Telegram Bot, dan pemrosesan data JSON.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "esp_camera.h"
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
Library tersebut menjadi komponen utama agar ESP32-CAM dapat terhubung ke internet dan berkomunikasi dengan Telegram.
2. Konfigurasi Wi-Fi
ESP32-CAM memerlukan koneksi internet agar dapat mengakses server Telegram. Oleh karena itu, nama jaringan Wi-Fi dan kata sandi harus diisikan terlebih dahulu.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Ketika sistem dijalankan, ESP32-CAM akan mencoba terhubung ke jaringan Wi-Fi yang telah ditentukan.
3. Konfigurasi Telegram Bot
Bot Token dan Chat ID digunakan sebagai identitas sistem saat berkomunikasi dengan Telegram.
String BOTtoken = "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXX";
String CHAT_ID = "XXXXXXXXXX";
Bot Token diperoleh dari BotFather, sedangkan Chat ID diperoleh dari @myidbot. Selain digunakan untuk mengirim pesan, Chat ID juga berfungsi sebagai mekanisme keamanan agar hanya pengguna tertentu yang dapat mengendalikan perangkat.
4. Konfigurasi Kamera ESP32-CAM
Program menggunakan konfigurasi pin untuk modul ESP32-CAM AI Thinker.
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
Konfigurasi tersebut digunakan untuk menghubungkan ESP32 dengan sensor kamera OV2640 sehingga proses pengambilan gambar dapat dilakukan dengan benar. Fungsi configInitCamera() bertugas menginisialisasi kamera, menentukan resolusi gambar, kualitas JPEG, serta mengalokasikan memori yang diperlukan selama proses pengambilan foto.
5. Fungsi handleNewMessages()
Fungsi ini digunakan untuk membaca dan memproses pesan yang diterima dari Telegram.
void handleNewMessages(int numNewMessages)
Program mendukung tiga perintah utama, yaitu:
- /start menampilkan daftar perintah
- /flash mengaktifkan atau menonaktifkan LED flash
- /photo mengambil dan mengirim foto baru
6. Fungsi sendPhotoTelegram()
Fungsi ini bertugas mengambil gambar dari kamera dan mengirimkannya ke Telegram. Sebelum mengambil foto utama, program terlebih dahulu membuang frame pertama karena kualitas gambar awal sering kali kurang baik akibat proses penyesuaian white balance pada sensor kamera. Setelah foto berhasil diambil, ESP32-CAM membuat permintaan HTTPS menggunakan metode POST ke Telegram Bot API untuk mengirimkan file gambar dalam format JPEG.
7. Fungsi setup()
Fungsi setup() dijalankan satu kali saat perangkat pertama kali dinyalakan. Pada fungsi ini dilakukan beberapa proses penting, antara lain:
- Inisialisasi Serial Monitor.
- Konfigurasi LED flash.
- Inisialisasi kamera.
- Koneksi ke jaringan Wi-Fi.
- Persiapan koneksi aman ke server Telegram.
Jika seluruh proses berhasil, ESP32-CAM siap menerima perintah dari Telegram.
8. Fungsi loop()
Fungsi loop() berjalan secara terus-menerus selama perangkat aktif. Program akan memeriksa apakah terdapat permintaan pengambilan foto serta memeriksa pesan baru dari Telegram secara berkala. Ketika perintah /photo diterima, ESP32-CAM akan mengambil foto kemudian mengirimkannya ke akun Telegram pengguna.
Pengujian Sistem
Setelah program berhasil diunggah ke ESP32-CAM, tekan tombol RST untuk menjalankan sistem.
Buka aplikasi Telegram dan kirimkan perintah berikut kepada bot yang telah dibuat:
1. Menampilkan daftar perintah /start. Bot akan mengirimkan pesan berisi daftar perintah yang tersedia.
2. Mengendalikan LED Flash dengan perintah /flash. Perintah ini digunakan untuk menyalakan atau mematikan LED flash pada ESP32-CAM.
3. Mengambil Foto dengan perintah /photo. ESP32-CAM akan mengambil gambar menggunakan kamera OV2640 dan mengirimkannya langsung ke Telegram.
Pada saat yang sama, Serial Monitor Arduino IDE akan menampilkan aktivitas komunikasi antara ESP32-CAM dan server Telegram. Jika terdapat pengguna lain yang mencoba mengakses bot, sistem akan mengirimkan pesan "Unauthorized user".







0 Komentar