#include "esp_camera.h" #include #include #include #include "addons/TokenHelper.h" #include "addons/RTDBHelper.h" // ======= Konfigurasi WiFi ======= const char* ssid = "iPhone pasa"; const char* password = "caca2004"; // ======= Konfigurasi Firebase ======= #define API_KEY "AIzaSyAkcK-nMUY8AcQRpOyrb0xACIgq9Er31Fk" #define DATABASE_URL "https://petfeeder-e9908-default-rtdb.asia-southeast1.firebasedatabase.app" #define USER_EMAIL "tkk@gmail.com" #define USER_PASSWORD "123456" // Firebase instances FirebaseData fbdo; FirebaseAuth auth; FirebaseConfig config; // ======= Konfigurasi pin untuk AI Thinker ESP32-CAM ======= #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 WebServer server(80); // HTTP server di port 80 // ======= Setup ======= void setup() { Serial.begin(115200); Serial.setDebugOutput(false); Serial.println("\n\n[BOOT] Memulai ESP32-CAM..."); // Konfigurasi kamera camera_config_t configCam; configCam.ledc_channel = LEDC_CHANNEL_0; configCam.ledc_timer = LEDC_TIMER_0; configCam.pin_d0 = Y2_GPIO_NUM; configCam.pin_d1 = Y3_GPIO_NUM; configCam.pin_d2 = Y4_GPIO_NUM; configCam.pin_d3 = Y5_GPIO_NUM; configCam.pin_d4 = Y6_GPIO_NUM; configCam.pin_d5 = Y7_GPIO_NUM; configCam.pin_d6 = Y8_GPIO_NUM; configCam.pin_d7 = Y9_GPIO_NUM; configCam.pin_xclk = XCLK_GPIO_NUM; configCam.pin_pclk = PCLK_GPIO_NUM; configCam.pin_vsync = VSYNC_GPIO_NUM; configCam.pin_href = HREF_GPIO_NUM; configCam.pin_sscb_sda = SIOD_GPIO_NUM; configCam.pin_sscb_scl = SIOC_GPIO_NUM; configCam.pin_pwdn = PWDN_GPIO_NUM; configCam.pin_reset = RESET_GPIO_NUM; configCam.xclk_freq_hz = 20000000; configCam.pixel_format = PIXFORMAT_JPEG; configCam.frame_size = FRAMESIZE_QVGA; configCam.jpeg_quality = 10; configCam.fb_count = 2; // Inisialisasi kamera if (esp_camera_init(&configCam) != ESP_OK) { Serial.println("[ERROR] Inisialisasi kamera gagal."); return; } // Koneksi WiFi Serial.print("[INFO] Menghubungkan ke WiFi"); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\n[SUKSES] WiFi tersambung"); Serial.println("[INFO] IP Lokal: " + WiFi.localIP().toString()); // Inisialisasi Firebase config.api_key = API_KEY; config.database_url = DATABASE_URL; auth.user.email = USER_EMAIL; auth.user.password = USER_PASSWORD; fbdo.setResponseSize(4096); // Opsional: perbesar buffer Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); Serial.print("[INFO] Menunggu autentikasi Firebase"); while (auth.token.uid == "") { Serial.print("."); delay(1000); } Serial.println("\n[SUKSES] Autentikasi berhasil"); // Kirim IP lokal ke Firebase Realtime Database if (Firebase.ready() && Firebase.RTDB.setString(&fbdo, "/esp32cam/ip", WiFi.localIP().toString())) { Serial.println("[SUKSES] IP dikirim ke Firebase: " + WiFi.localIP().toString()); } else { Serial.println("[GAGAL] Kirim IP: " + fbdo.errorReason()); } // Setup routing server server.on("/", HTTP_GET, []() { server.send(200, "text/html", "

ESP32-CAM Stream

"); }); server.on("/stream", HTTP_GET, handleJPGStream); server.on("/capture", HTTP_GET, handleCapture); server.begin(); Serial.println("[READY] Server aktif."); Serial.println("[STREAM] http://" + WiFi.localIP().toString() + "/stream"); Serial.println("[CAPTURE] http://" + WiFi.localIP().toString() + "/capture"); } void loop() { server.handleClient(); } // ======= Streaming MJPEG ======= void handleJPGStream() { WiFiClient client = server.client(); String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n"; server.sendContent(response); while (client.connected()) { camera_fb_t * fb = esp_camera_fb_get(); if (!fb) { Serial.println("[ERROR] Frame capture gagal"); break; } response = "--frame\r\nContent-Type: image/jpeg\r\n\r\n"; server.sendContent(response); client.write(fb->buf, fb->len); server.sendContent("\r\n"); esp_camera_fb_return(fb); delay(100); } } // ======= Capture JPG ======= void handleCapture() { camera_fb_t * fb = esp_camera_fb_get(); if (!fb) { server.send(500, "text/plain", "Capture gagal"); return; } server.sendHeader("Content-Type", "image/jpeg"); server.send_P(200, "image/jpeg", (char *)fb->buf, fb->len); esp_camera_fb_return(fb); }