#include "esp_camera.h" #include #include #include #include #include const char* ssid = "Maratus soleha"; const char* password = "12345678"; // ================= Cloudinary ===================== const char* cloud_name = "duecjbzre"; const char* upload_preset = "esp32upload"; // ================= Firebase ===================== #define FIREBASE_AUTH "AIzaSyAHdV9uhz6NgtMN5x-NGJ5-XtdxOUpQW4g" #define FIREBASE_HOST "https://paket-b7ef8-default-rtdb.asia-southeast1.firebasedatabase.app/" FirebaseData firebaseData; FirebaseAuth firebaseAuth; FirebaseConfig firebaseConfig; Servo myServo; // ================= Ultrasonik ===================== #define TRIG_PIN 12 #define ECHO_PIN 13 bool objekTerdeteksi = false; #define SERVO_PIN 14 // ================= Kamera 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 // ================= SETUP ===================== void setup() { Serial.begin(115200); delay(1000); pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); WiFi.begin(ssid, password); Serial.print("Menghubungkan WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nāœ… WiFi terhubung!"); firebaseConfig.database_url = FIREBASE_HOST; firebaseConfig.signer.tokens.legacy_token = FIREBASE_AUTH; Firebase.begin(&firebaseConfig, &firebaseAuth); Firebase.reconnectWiFi(true); myServo.attach(SERVO_PIN); myServo.write(0); 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; config.frame_size = FRAMESIZE_VGA; config.jpeg_quality = 10; config.fb_count = 1; if (esp_camera_init(&config) != ESP_OK) { Serial.println("āŒ Kamera gagal diinisialisasi"); while (1); } } // ================= LOOP ===================== void loop() { float jarak = ukurJarak(); Serial.print("šŸ“ Jarak: "); Serial.print(jarak); Serial.println(" cm"); // Cek jika objek baru terdeteksi (transisi: tidak ada → ada) if (jarak > 0 && jarak <= 15.0 && !objekTerdeteksi) { objekTerdeteksi = true; Serial.println("šŸ“· Objek terdeteksi! Mengambil gambar..."); ambilUploadDanSimpan(); } // Reset flag jika objek menjauh if (jarak > 20.0) { objekTerdeteksi = false; } BukaTutupServo(); delay(500); } // ================= Ultrasonik ===================== float ukurJarak() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); long durasi = pulseIn(ECHO_PIN, HIGH, 30000); if (durasi == 0) return -1; return durasi * 0.034 / 2; } void BukaTutupServo() { if (Firebase.getBool(firebaseData, "servo")) { bool perintah = firebaseData.boolData(); Serial.print("šŸ”§ Perintah servo: "); Serial.println(perintah); if (perintah == true) { myServo.write(0); // servo membuka } else if (perintah == false) { myServo.write(180); // servo menutup } else { Serial.println("ā— Perintah tidak dikenal"); } } else { Serial.print("āŒ Gagal membaca data servo: "); Serial.println(firebaseData.errorReason()); } } // ================= Upload ke Cloudinary & Simpan Firebase ===================== void ambilUploadDanSimpan() { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("āŒ Gagal mengambil gambar"); return; } WiFiClientSecure client; client.setInsecure(); // Abaikan sertifikat SSL if (!client.connect("api.cloudinary.com", 443)) { Serial.println("āŒ Gagal terhubung ke Cloudinary"); return; } String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"; String startRequest = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"esp32.jpg\"\r\n" + "Content-Type: image/jpeg\r\n\r\n"; String endRequest = "\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"upload_preset\"\r\n\r\n" + String(upload_preset) + "\r\n--" + boundary + "--\r\n"; int contentLength = startRequest.length() + fb->len + endRequest.length(); client.println("POST /v1_1/" + String(cloud_name) + "/image/upload HTTP/1.1"); client.println("Host: api.cloudinary.com"); client.println("Content-Type: multipart/form-data; boundary=" + boundary); client.println("Content-Length: " + String(contentLength)); client.println("Connection: close"); client.println(); client.print(startRequest); client.write(fb->buf, fb->len); client.print(endRequest); // Lewati header dulu while (client.connected()) { String line = client.readStringUntil('\n'); if (line.length() <= 1) break; // "\r" atau "" } // Sekarang baca JSON body dengan cara aman String response; while (client.available()) { char c = client.read(); response += c; } // Potong hanya bagian JSON int jsonStart = response.indexOf('{'); if (jsonStart == -1) { Serial.println("āŒ Tidak ditemukan awalan JSON"); Serial.println(response); // Untuk debug return; } response = response.substring(jsonStart); // Buang header, ambil JSON murni Serial.println("šŸ“¦ JSON Akhir:"); Serial.println(response); // Parse JSON DynamicJsonDocument doc(4096); DeserializationError error = deserializeJson(doc, response); if (error) { Serial.print("āŒ Gagal parsing JSON: "); Serial.println(error.c_str()); esp_camera_fb_return(fb); return; } String secure_url = doc["secure_url"]; Serial.print("āœ… URL Gambar: "); Serial.println(secure_url); esp_camera_fb_return(fb); FirebaseJson json; json.set("url", secure_url); json.set("timestamp", millis()); json.set("status", true); if (Firebase.setJSON(firebaseData, "/Gambar", json)) { Serial.println("āœ… Data berhasil dikirim ke Firebase"); } else { Serial.print("āŒ Gagal kirim ke Firebase: "); Serial.println(firebaseData.errorReason()); } }