commit ce5a26629039dc14809ba7933451c88dbb6380b9 Author: teguhsetyob Date: Mon Aug 18 23:13:32 2025 +0700 Upload files to "/" diff --git a/Smartpaket.ino b/Smartpaket.ino new file mode 100644 index 0000000..3dd6156 --- /dev/null +++ b/Smartpaket.ino @@ -0,0 +1,251 @@ +#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()); + } + +} \ No newline at end of file