Smart Vacuum Cleaner Project,communication between esp32 cam and ardunio uno

My project will be a smart vacuum cleaner project. In the project, a vacuum motor, a relay for the control of this motor, 4 dc motors, a l298n motor driver, an arduino uno, an esp32 glass, a distance sensor, batteries and a servo will be installed with the circuit. Servo motor, IN1,2,3,4,enA,enB pins, distance sensor and vacuum motor outputs (relay) will be connected to arduino uno. My smart robot will have two modes. Automatic mode will be the mode in which the robot can draw its own path with the help of the distance sensor and servo motor and go that way. I should also be able to activate and deactivate the manual mode from the same web interface.manual mode is the mode that we control the robot, that is, the mode that we control with the right, left, front, back keys.In addition, we should see camera data LIVE in our web interface, which includes the modes we have created and so on.I am having trouble communicating between esp32 cam and arduino uno.I tried I2C and UART protocols, but I did not get positive results.Please help me.I can share the codes.

ESP32 CAM code:

#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "xxx";
const char* password = "xxx";

#define CAMERA_MODEL_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

WebServer server(80);

void startCameraServer();
void handleRoot();
void handleStream();
void handleControl();

void setup() {
  Serial.begin(115200);
  
  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_QVGA;
  config.jpeg_quality = 10;
  config.fb_count = 2;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  startCameraServer();
}

void loop() {
  server.handleClient();
  
  if (Serial.available()) {
    String command = Serial.readStringUntil('\n');
    command.trim();
    
    // Forward valid commands
    if (command == "MODE_AUTO" || command == "MODE_MANUAL" ||
        command == "FORWARD" || command == "BACKWARD" ||
        command == "LEFT" || command == "RIGHT" || 
        command == "STOP" || command == "VACUUM_ON" || 
        command == "VACUUM_OFF") {
      Serial.println(command);
    }
  }
}

void startCameraServer() {
  server.on("/", handleRoot);
  server.on("/stream", handleStream);
  server.on("/control", handleControl);
  server.begin();
  Serial.println("HTTP server started");
}

void handleRoot() {
  String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Akıllı Süpürge Kontrol Paneli</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            text-align: center;
            background-color: #f5f5f5;
        }
        h1 {
            color: #2c3e50;
            margin-bottom: 30px;
        }
        img {
            max-width: 100%;
            height: auto;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-bottom: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .mode-buttons {
            margin-bottom: 20px;
        }
        .control-group {
            margin: 15px 0;
            padding: 15px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        button {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 12px 20px;
            margin: 5px;
            border-radius: 4px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s;
            min-width: 120px;
        }
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }
        .movement-btn {
            background-color: #2ecc71;
        }
        .movement-btn:hover {
            background-color: #27ae60;
        }
        .vacuum-btn {
            background-color: #e74c3c;
        }
        .vacuum-btn:hover {
            background-color: #c0392b;
        }
        .stop-btn {
            background-color: #f39c12;
        }
        .stop-btn:hover {
            background-color: #d35400;
        }
        .mode-btn {
            background-color: #9b59b6;
        }
        .mode-btn:hover {
            background-color: #8e44ad;
        }
        @media (max-width: 600px) {
            button {
                padding: 10px 15px;
                font-size: 14px;
                min-width: 100px;
            }
        }
    </style>
</head>
<body>
    <h1>Robot Süpürge Kontrol Paneli</h1>
    <img src="/stream" width="640" height="480" alt="Robot Kamera Görüntüsü">
    
    <div class="mode-buttons control-group">
        <button class="mode-btn" onclick="sendCommand('MODE_AUTO')">Otonom Mod</button>
        <button class="mode-btn" onclick="sendCommand('MODE_MANUAL')">Manuel Mod</button>
    </div>
    
    <div class="control-group">
        <button class="movement-btn" onmousedown="sendCommand('FORWARD')" onmouseup="sendCommand('STOP')">İleri</button>
        <button class="movement-btn" onmousedown="sendCommand('BACKWARD')" onmouseup="sendCommand('STOP')">Geri</button>
        <button class="movement-btn" onmousedown="sendCommand('LEFT')" onmouseup="sendCommand('STOP')">Sol</button>
        <button class="movement-btn" onmousedown="sendCommand('RIGHT')" onmouseup="sendCommand('STOP')">Sağ</button>
        <button class="stop-btn" onclick="sendCommand('STOP')">DUR</button>
    </div>
    
    <div class="control-group">
        <button class="vacuum-btn" onclick="sendCommand('VACUUM_ON')">Süpürge Aç</button>
        <button class="vacuum-btn" onclick="sendCommand('VACUUM_OFF')">Süpürge Kapat</button>
    </div>

    <script>
        function sendCommand(cmd) {
            fetch('/control?cmd=' + cmd)
                .then(response => {
                    if (!response.ok) {
                        console.error('Server error:', response.status);
                    }
                })
                .catch(err => console.error('Network error:', err));
        }
    </script>
</body>
</html>
)rawliteral";
  server.send(200, "text/html", html);
}

void handleStream() {
  WiFiClient client = server.client();
  
  // Send MJPEG stream header
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: multipart/x-mixed-replace; boundary=frame");
  client.println("Access-Control-Allow-Origin: *");
  client.println();
  
  while (client.connected()) {
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Camera capture failed");
      break;
    }

    client.println("--frame");
    client.println("Content-Type: image/jpeg");
    client.println("Content-Length: " + String(fb->len));
    client.println();
    client.write(fb->buf, fb->len);
    client.println();
    
    esp_camera_fb_return(fb);
    
    delay(10);
  }
}

void handleControl() {
  if (server.hasArg("cmd")) {
    String cmd = server.arg("cmd");
    Serial.println(cmd);
    server.send(200, "text/plain", "Command received: " + cmd);
  } else {
    server.send(400, "text/plain", "Missing cmd parameter");
  }
}

Arduino uno code(UART):

#include <SoftwareSerial.h>


SoftwareSerial toESP(0, 1);

// Motor kontrol pinleri
const int MOTOR_A1 = 4;
const int MOTOR_A2 = 5;
const int MOTOR_B1 = 6;
const int MOTOR_B2 = 7;

const int SERVO1_PIN = 9;
const int SERVO2_PIN = 10;

const int TRIG_PIN = 11;
const int ECHO_PIN = 12;

enum Mode {
  MANUAL,
  AUTOMATIC
};

Mode currentMode = MANUAL;
bool isVacuumOn = false;

void setup() {
  pinMode(MOTOR_A1, OUTPUT);
  pinMode(MOTOR_A2, OUTPUT);
  pinMode(MOTOR_B1, OUTPUT);
  pinMode(MOTOR_B2, OUTPUT);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  Serial.begin(115200);
  esp32Serial.begin(115200);
}

void loop() {
  if (esp32Serial.available()) {
    String command = esp32Serial.readStringUntil('\n');
    processCommand(command);
  }

  if (currentMode == AUTOMATIC) {
    autonomousMove();
  }
}

void processCommand(String command) {
  if (command == "MODE_AUTO") {
    currentMode = AUTOMATIC;
  } else if (command == "MODE_MANUAL") {
    currentMode = MANUAL;
  } else if (currentMode == MANUAL) {
    // Manuel mod komutları
    if (command == "FORWARD") moveForward();
    else if (command == "BACKWARD") moveBackward();
    else if (command == "LEFT") turnLeft();
    else if (command == "RIGHT") turnRight();
    else if (command == "STOP") stopMoving();
    else if (command == "VACUUM_ON") turnOnVacuum();
    else if (command == "VACUUM_OFF") turnOffVacuum();
  }
}

void autonomousMove() {
  long distance = measureDistance();
  
  if (distance > 20) {  
    moveForward();
  } else {
    turnRight();
  }
}

long measureDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void moveForward() {
  digitalWrite(MOTOR_A1, HIGH);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, HIGH);
  digitalWrite(MOTOR_B2, LOW);
}

void moveBackward() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, HIGH);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, HIGH);
}

void turnLeft() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, HIGH);
  digitalWrite(MOTOR_B1, HIGH);
  digitalWrite(MOTOR_B2, LOW);
}

void turnRight() {
  digitalWrite(MOTOR_A1, HIGH);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, HIGH);
}

void stopMoving() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, LOW);
}

void turnOnVacuum() {
  isVacuumOn = true;
}

void turnOffVacuum() {
  isVacuumOn = false;
}#include <SoftwareSerial.h>


SoftwareSerial toESP(0, 1);

// Motor kontrol pinleri
const int MOTOR_A1 = 4;
const int MOTOR_A2 = 5;
const int MOTOR_B1 = 6;
const int MOTOR_B2 = 7;

const int SERVO1_PIN = 9;
const int SERVO2_PIN = 10;

const int TRIG_PIN = 11;
const int ECHO_PIN = 12;

enum Mode {
  MANUAL,
  AUTOMATIC
};

Mode currentMode = MANUAL;
bool isVacuumOn = false;

void setup() {
  pinMode(MOTOR_A1, OUTPUT);
  pinMode(MOTOR_A2, OUTPUT);
  pinMode(MOTOR_B1, OUTPUT);
  pinMode(MOTOR_B2, OUTPUT);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  Serial.begin(115200);
  esp32Serial.begin(115200);
}

void loop() {
  if (esp32Serial.available()) {
    String command = esp32Serial.readStringUntil('\n');
    processCommand(command);
  }

  if (currentMode == AUTOMATIC) {
    autonomousMove();
  }
}

void processCommand(String command) {
  if (command == "MODE_AUTO") {
    currentMode = AUTOMATIC;
  } else if (command == "MODE_MANUAL") {
    currentMode = MANUAL;
  } else if (currentMode == MANUAL) {
    // Manuel mod komutları
    if (command == "FORWARD") moveForward();
    else if (command == "BACKWARD") moveBackward();
    else if (command == "LEFT") turnLeft();
    else if (command == "RIGHT") turnRight();
    else if (command == "STOP") stopMoving();
    else if (command == "VACUUM_ON") turnOnVacuum();
    else if (command == "VACUUM_OFF") turnOffVacuum();
  }
}

void autonomousMove() {
  long distance = measureDistance();
  
  if (distance > 20) {  
    moveForward();
  } else {
    turnRight();
  }
}

long measureDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void moveForward() {
  digitalWrite(MOTOR_A1, HIGH);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, HIGH);
  digitalWrite(MOTOR_B2, LOW);
}

void moveBackward() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, HIGH);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, HIGH);
}

void turnLeft() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, HIGH);
  digitalWrite(MOTOR_B1, HIGH);
  digitalWrite(MOTOR_B2, LOW);
}

void turnRight() {
  digitalWrite(MOTOR_A1, HIGH);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, HIGH);
}

void stopMoving() {
  digitalWrite(MOTOR_A1, LOW);
  digitalWrite(MOTOR_A2, LOW);
  digitalWrite(MOTOR_B1, LOW);
  digitalWrite(MOTOR_B2, LOW);
}

void turnOnVacuum() {
  isVacuumOn = true;
}

void turnOffVacuum() {
  isVacuumOn = false;
}

115200 is too high for sw serial, try with 38400

Is your maid going to drag this vacuum around so it can clean? What is your weigh estimate?

tried but didn't work

my robot will vacuum around and it will be clean.

Your SoftwareSerial is named toESP, not esp32Serial

Also, don't use softwareserial on hardware serial pins (0, 1), use normal pins like 3 and 4.

Are you going to pull it around while it cleans?

look at this one, pls esp32 cam code:

#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>
#include <HardwareSerial.h>

// WiFi Ayarları
const char* ssid = "Badirinphone";
const char* password = "Badir8186";

// Kamera Konfigürasyonu
#define CAMERA_MODEL_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

// Seri Haberleşme
#define RXD2 16
#define TXD2 17

WebServer server(80);
String currentMode = "MANUAL";

void 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;
  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_QVGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Kamera başlatma hatası 0x%x", err);
    ESP.restart();
  }
}

void connectWiFi() {
  WiFi.begin(ssid, password);
  Serial.print("WiFi'ye bağlanıyor...");
  
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    delay(500);
    Serial.print(".");
    attempts++;
  }
  
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWiFi bağlandı");
    Serial.print("IP Adresi: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("\nWiFi bağlantı hatası! Yeniden başlatılıyor...");
    delay(3000);
    ESP.restart();
  }
}

void handleRoot() {
  String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Akıllı Süpürge Kontrol</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f0f2f5;
            color: #333;
        }
        .header {
            text-align: center;
            margin-bottom: 25px;
            padding: 15px;
            background: linear-gradient(135deg, #6e8efb, #a777e3);
            color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        .video-container {
            background: #000;
            border-radius: 8px;
            overflow: hidden;
            margin-bottom: 20px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }
        .control-panel {
            background: white;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .mode-buttons {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-bottom: 20px;
        }
        .movement-buttons {
            display: grid;
            grid-template-columns: 1fr 1fr 1fr;
            gap: 10px;
            margin-bottom: 20px;
        }
        button {
            border: none;
            padding: 12px 0;
            border-radius: 6px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s;
        }
        button:active {
            transform: scale(0.95);
        }
        .btn-auto {
            background: #4CAF50;
            color: white;
        }
        .btn-manual {
            background: #2196F3;
            color: white;
        }
        .btn-forward {
            background: #FF9800;
            color: white;
            grid-column: 2;
        }
        .btn-left {
            background: #9C27B0;
            color: white;
        }
        .btn-right {
            background: #3F51B5;
            color: white;
        }
        .btn-back {
            background: #F44336;
            color: white;
            grid-column: 2;
        }
        .btn-stop {
            background: #607D8B;
            color: white;
            grid-column: 2;
        }
        .btn-vacuum {
            background: #E91E63;
            color: white;
        }
        .status {
            text-align: center;
            padding: 10px;
            margin-top: 10px;
            border-radius: 4px;
            background: #e3f2fd;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>Robot Süpürge Kontrol Paneli</h1>
        <div class="status">Mevcut Mod: %MODE%</div>
    </div>
    
    <div class="video-container">
        <img src="/video" width="640" height="480" alt="Canlı Kamera">
    </div>
    
    <div class="control-panel">
        <div class="mode-buttons">
            <button class="btn-auto" onclick="sendCommand('MODE_AUTO')">Otonom Mod</button>
            <button class="btn-manual" onclick="sendCommand('MODE_MANUAL')">Manuel Mod</button>
        </div>
        
        <div class="movement-buttons">
            <button class="btn-forward" 
                    onmousedown="sendCommand('FORWARD')" 
                    onmouseup="sendCommand('STOP')">İLERİ</button>
            <button class="btn-left" 
                    onmousedown="sendCommand('LEFT')" 
                    onmouseup="sendCommand('STOP')">SOL</button>
            <button class="btn-stop" onclick="sendCommand('STOP')">DUR</button>
            <button class="btn-right" 
                    onmousedown="sendCommand('RIGHT')" 
                    onmouseup="sendCommand('STOP')">SAĞ</button>
            <button class="btn-back" 
                    onmousedown="sendCommand('BACKWARD')" 
                    onmouseup="sendCommand('STOP')">GERİ</button>
        </div>
        
        <div style="text-align: center;">
            <button class="btn-vacuum" onclick="sendCommand('VACUUM_ON')">SÜPÜRGE AÇ</button>
            <button class="btn-vacuum" onclick="sendCommand('VACUUM_OFF')">SÜPÜRGE KAPAT</button>
        </div>
    </div>

    <script>
        function sendCommand(cmd) {
            fetch('/control?cmd=' + cmd)
                .then(response => {
                    if (response.ok) {
                        if (cmd.includes('MODE')) {
                            setTimeout(() => location.reload(), 500);
                        }
                    }
                });
        }
    </script>
</body>
</html>
)rawliteral";

  html.replace("%MODE%", currentMode);
  server.send(200, "text/html", html);
}

void handleVideo() {
  WiFiClient client = server.client();
  
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: multipart/x-mixed-replace; boundary=frame");
  client.println("Access-Control-Allow-Origin: *");
  client.println();
  
  while (client.connected()) {
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Kamera yakalama hatası");
      delay(100);
      continue;
    }

    client.println("--frame");
    client.println("Content-Type: image/jpeg");
    client.println("Content-Length: " + String(fb->len));
    client.println();
    client.write(fb->buf, fb->len);
    client.println();
    
    esp_camera_fb_return(fb);
    delay(10);
  }
}

void handleControl() {
  if (server.hasArg("cmd")) {
    String cmd = server.arg("cmd");
    Serial2.println(cmd);
    
    if (cmd == "MODE_AUTO") {
      currentMode = "AUTO";
    } else if (cmd == "MODE_MANUAL") {
      currentMode = "MANUAL";
    }
    
    server.send(200, "text/plain", "OK: " + cmd);
  } else {
    server.send(400, "text/plain", "Hatalı istek");
  }
}

void checkSerial() {
  if (Serial2.available()) {
    String incoming = Serial2.readStringUntil('\n');
    incoming.trim();
    
    if (incoming.startsWith("STATUS:")) {
      if (incoming.indexOf("AUTO") != -1) {
        currentMode = "AUTO";
      } else {
        currentMode = "MANUAL";
      }
    }
  }
}

void setup() {
  Serial.begin(115200);
  Serial2.begin(38400, SERIAL_8N1, RXD2, TXD2);
  
  setupCamera();
  connectWiFi();

  server.on("/", HTTP_GET, handleRoot);
  server.on("/control", HTTP_GET, handleControl);
  server.on("/video", HTTP_GET, handleVideo);
  server.onNotFound([](){
    server.send(404, "text/plain", "Sayfa bulunamadı");
  });
  
  server.begin();
  Serial.println("HTTP sunucusu başlatıldı");
}

void loop() {
  server.handleClient();
  checkSerial();
}

arduino uno code:

#include <Servo.h>

// Pin Tanımlamaları
const int trigPin = 12;
const int echoPin = 11;
const int vacuumRelay = 8;
const int enA = 2;   // Sol motorlar PWM
const int in1 = 4;   // Sol motorlar yön
const int in2 = 5;   
const int enB = 3;   // Sağ motorlar PWM
const int in3 = 6;   // Sağ motorlar yön
const int in4 = 7;   

Servo sensorServo;   // Mesafe sensörü servo motoru
int servoPos = 90;   // Servo başlangıç pozisyonu
int scanDirection = 1; // Tarama yönü

// Motor ve Çalışma Ayarları
int motorSpeed = 120; // Yavaş hareket için 0-255 arası
bool isAutoMode = false;
bool isVacuumOn = false;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(vacuumRelay, OUTPUT);
  
  // Motor sürücü pinleri
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
  sensorServo.attach(9);
  sensorServo.write(servoPos);
  
  // Başlangıçta vakum motoru kapalı
  digitalWrite(vacuumRelay, LOW);
  
  Serial.begin(38400);
}

void loop() {
  // Seri haberleşmeden gelen komutları işle
  if (Serial.available()) {
    String command = Serial.readStringUntil('\n');
    command.trim();
    
    // Mod ve Kontrol Komutları
    if (command == "MODE_AUTO") {
      isAutoMode = true;
      Serial.println("Otonom mod aktif");
    } else if (command == "MODE_MANUAL") {
      isAutoMode = false;
      stopMotors();
      Serial.println("Manuel mod aktif");
    } else if (!isAutoMode) {
      // Manuel mod komutları
      if (command == "FORWARD") moveForward();
      else if (command == "BACKWARD") moveBackward();
      else if (command == "LEFT") turnLeft();
      else if (command == "RIGHT") turnRight();
      else if (command == "STOP") stopMotors();
      else if (command == "VACUUM_ON") turnOnVacuum();
      else if (command == "VACUUM_OFF") turnOffVacuum();
    }
  }
  
  // Otonom mod çalışması
  if (isAutoMode) {
    autonomousNavigate();
  }
}

void autonomousNavigate() {
  // Servo ile ortamı tarama
  scanEnvironment();
  
  // Mesafe ölçümü
  float distance = getDistance();
  
  if (distance < 30) { // 30cm'den yakın engel varsa
    avoidObstacle();
  } else {
    moveForward();
  }
  
  delay(100);
}

float getDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  float distance = duration * 0.034 / 2;
  
  return distance;
}

void scanEnvironment() {
  servoPos += (10 * scanDirection);
  sensorServo.write(servoPos);
  
  // Servo hareket sınırları
  if (servoPos >= 150 || servoPos <= 30) {
    scanDirection *= -1;
  }
}

void moveForward() {
  turnOnVacuum();
  
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  
  analogWrite(enA, motorSpeed);
  analogWrite(enB, motorSpeed);
}

void moveBackward() {
  turnOffVacuum();
  
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  
  analogWrite(enA, motorSpeed);
  analogWrite(enB, motorSpeed);
}

void turnLeft() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  
  analogWrite(enA, motorSpeed);
  analogWrite(enB, motorSpeed);
}

void turnRight() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  
  analogWrite(enA, motorSpeed);
  analogWrite(enB, motorSpeed);
}

void avoidObstacle() {
  turnOffVacuum();
  
  // Geri git
  moveBackward();
  delay(500);
  
  // Rasgele yöne dön
  if (random(2) == 0) {
    turnLeft();
  } else {
    turnRight();
  }
  delay(300);
}

void stopMotors() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  turnOffVacuum();
}

void turnOnVacuum() {
  digitalWrite(vacuumRelay, HIGH);
  isVacuumOn = true;
}

void turnOffVacuum() {
  digitalWrite(vacuumRelay, LOW);
  isVacuumOn = false;
}

here is my project:The project will be a smart vacuum cleaner project. In the project, there is a vacuum motor, a relay to control this motor, 4 dc motors, an l298n motor driver, an arduino uno, an esp32 cam, a distance sensor, and a servo. My smart vacuum cleaner robot, which includes everything, will have two modes. Automatic mode will be the mode where the robot can draw its own path with the help of the distance sensor and servo motor and follow that path. I should be able to activate and close this mode from the web interface. I should also be able to activate and close the manual mode from the same web interface. Manual mode is the mode where we control the robot, that is, we control it with the right, left, front and back buttons. We can add the esp32 cam servo feature to this mode. In addition, we should see LIVE camera data in our web interface where the modes we created are located. In addition, the website interface should be stylish.Also i can use esp32 instead of arduino uno

do you actually have that pin?

Can you explain what I should do with it?

I don't understand your question.
You use it on your esp32 code for serial communication.
And afaik esp32-cam doesn't have gpio17 exposed. That's why I'm asking....

Is that code some ChatGPT generated...?

it is from deepseek.Can you explain what I should do with it?

Delete it and write code that you yourself understand. You're wasting your time trying to get an AI to do something you don't know how to do yourself. You can't tell that it's just making nonsense up.

you are right, but what will happen if I don't write something that needs to be in the code?

Have you picked a fan that will produce enough vacuum to pick up dirt?

Which protocol i should use and how i can use it?