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();
}
}
#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

.jpeg)







