import sys with open('esp32_serial_backend/esp32_serial_backend.ino', 'r', encoding='utf8') as f: content = f.read() # Update postFrame signature content = content.replace( 'String postFrame(const String &url, camera_fb_t *fb, uint32_t timeoutMs)', 'String postFrame(const String &url, uint8_t *buf, size_t len, uint32_t timeoutMs)' ) content = content.replace( 'if (!fb)\n return "ERROR no_frame";', 'if (!buf)\n return "ERROR no_buf";' ) content = content.replace( 'int code = http.POST(fb->buf, fb->len);', 'int code = http.POST(buf, len);' ) # Update postFrameWithRetry signature content = content.replace( 'String postFrameWithRetry(const String &url, camera_fb_t *fb, uint32_t timeoutMs, int retries = 1)', 'String postFrameWithRetry(const String &url, uint8_t *buf, size_t len, uint32_t timeoutMs, int retries = 1)' ) content = content.replace( 'String resp = postFrame(url, fb, timeoutMs);', 'String resp = postFrame(url, buf, len, timeoutMs);' ) # In handleCommand, remove reinitCamera and add frame2jpg old_capture_code = """ gBusy = true; if (!reinitCamera(PIXFORMAT_JPEG)) { showStatus("GAGAL JEPRET", TFT_RED, "JPEG Init error"); gBusy = false; return false; } delay(80); camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("ERROR no_frame"); showStatus("KAMERA ERROR", TFT_RED, "Camera fb null"); gBusy = false; return false; } // Debug: verify we're actually sending a JPEG. if (fb->len >= 3) { Serial.printf("CAP fmt=%d len=%u magic=%02X %02X %02X\\n", (int)fb->format, (unsigned)fb->len, fb->buf[0], fb->buf[1], fb->buf[2]); } else { Serial.printf("CAP fmt=%d len=%u\\n", (int)fb->format, (unsigned)fb->len); } // If the frame isn't JPEG or doesn't have JPEG SOI marker, don't upload. if (fb->format != PIXFORMAT_JPEG || fb->len < 3 || !(fb->buf[0] == 0xFF && fb->buf[1] == 0xD8 && fb->buf[2] == 0xFF)) { showStatus("BUKAN JPEG", TFT_RED, "Format salah"); esp_camera_fb_return(fb); reinitCamera(PIXFORMAT_RGB565); gBusy = false; return false; }""" new_capture_code = """ gBusy = true; // Tidak perlu reinitCamera ke JPEG lagi! // Kita ambil frame saat ini (RGB565) lalu convert ke JPEG di memori agar jauh lebih cepat. camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("ERROR no_frame"); showStatus("KAMERA ERROR", TFT_RED, "Camera fb null"); gBusy = false; return false; } uint8_t *jpg_buf = NULL; size_t jpg_len = 0; if (!frame2jpg(fb, 80, &jpg_buf, &jpg_len)) { Serial.println("ERROR frame2jpg"); showStatus("GAGAL KONVERSI", TFT_RED, "JPEG failed"); esp_camera_fb_return(fb); gBusy = false; return false; }""" content = content.replace(old_capture_code, new_capture_code) # Replace fb with jpg_buf in ENROLL content = content.replace( 'String resp = postFrameWithRetry(url, fb, 60000);', 'String resp = postFrameWithRetry(url, jpg_buf, jpg_len, 60000);' ) # And in RECOG, it's the exact same line, so the replace above covers both. # But wait, we need to free jpg_buf! # At the end of handleCommand: old_end = """ esp_camera_fb_return(fb); // Back to TFT preview mode reinitCamera(PIXFORMAT_RGB565); gBusy = false; return true;""" new_end = """ if (jpg_buf) free(jpg_buf); esp_camera_fb_return(fb); gBusy = false; return true;""" content = content.replace(old_end, new_end) # Also fix the early return in ENROLL if name is empty old_early = """ if (name.length() == 0) { showStatus("NAMA KOSONG", TFT_RED, "Silakan isi nama"); esp_camera_fb_return(fb); reinitCamera(PIXFORMAT_RGB565); gBusy = false; return false; }""" new_early = """ if (name.length() == 0) { showStatus("NAMA KOSONG", TFT_RED, "Silakan isi nama"); if (jpg_buf) free(jpg_buf); esp_camera_fb_return(fb); gBusy = false; return false; }""" content = content.replace(old_early, new_early) # And fix the early return in RECOG if HTTP error old_recog_err = """ if (resp.startsWith("HTTP ERR") || resp.startsWith("HTTP 4") || resp.startsWith("HTTP 5") || resp.startsWith("WIFI")) { Serial.println("[RECOG] upload FAILED"); showStatus("SERVER DISABLE/RTO", TFT_RED, ""); esp_camera_fb_return(fb); reinitCamera(PIXFORMAT_RGB565); gBusy = false; return false; }""" new_recog_err = """ if (resp.startsWith("HTTP ERR") || resp.startsWith("HTTP 4") || resp.startsWith("HTTP 5") || resp.startsWith("WIFI")) { Serial.println("[RECOG] upload FAILED"); showStatus("SERVER DISABLE/RTO", TFT_RED, ""); if (jpg_buf) free(jpg_buf); esp_camera_fb_return(fb); gBusy = false; return false; }""" content = content.replace(old_recog_err, new_recog_err) with open('esp32_serial_backend/esp32_serial_backend.ino', 'w', encoding='utf8') as f: f.write(content) print("Done")