Smart vacuum cleaner project esp32 cam code error

when i upload the code(claude) to esp32 cam.This seems repeatedly in serial monitor:

ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8

the code:

#include "esp_camera.h"
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <iostream>
#include <sstream>
#include <ESP32Servo.h>

// Define hardware pins
#define VACUUM_PIN 1      // Pin for vacuum motor relay
#define SERVO_PIN 16       // Pin for servo motor
#define ULTRASONIC_TRIG 2 // Pin for ultrasonic sensor trigger
#define ULTRASONIC_ECHO 4 // Pin for ultrasonic sensor echo

// Motor pins structure
struct MOTOR_PINS
{
  int pinIN1;
  int pinIN2;    
};

// L298N motor driver connections
// Note: We're not using ENA/ENB pins due to ESP32-CAM pin limitations
std::vector<MOTOR_PINS> motorPins = 
{
  {12, 13},  // RIGHT_MOTOR Pins (IN1, IN2)
  {14, 15},  // LEFT_MOTOR Pins (IN3, IN4)
};

// Direction definitions
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define STOP 0

#define RIGHT_MOTOR 0
#define LEFT_MOTOR 1

#define FORWARD 1
#define BACKWARD -1
#define STOP_MOTOR 0

// Operation mode
bool automaticMode = false;
bool vacuumOn = false;

// Camera pins
#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

// WiFi credentials
const char* ssid     = "VacuumBot";
const char* password = "vacuum1234";

AsyncWebServer server(80);
AsyncWebSocket wsCamera("/Camera");
AsyncWebSocket wsRobotInput("/RobotInput");
uint32_t cameraClientId = 0;

// Create servo and ultrasonic sensor objects
Servo servoMotor;
unsigned long lastDistanceCheck = 0;
int servoAngle = 90; // Center position
int minDistance = 30; // Minimum distance in cm before turning


// HTML for the web interface
const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <style>
      body {
        font-family: Arial, sans-serif;
        background-color: #f0f0f0;
        margin: 0;
        padding: 20px;
        text-align: center;
      }
      
      .container {
        max-width: 800px;
        margin: 0 auto;
        background-color: white;
        border-radius: 10px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        padding: 20px;
      }
      
      h1 {
        color: #2c3e50;
      }
      `
      .camera-container {
        width: 100%;
        margin: 20px 0;
        position: relative;
        overflow: hidden;
        border-radius: 10px;
      }
      
      #cameraImage {
        width: 100%;
        max-width: 640px;
        height: auto;
        border-radius: 10px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }
      
      .controls {
        display: flex;
        flex-direction: column;
        align-items: center;
        margin-top: 20px;
      }
      
      .mode-controls {
        display: flex;
        justify-content: center;
        margin-bottom: 20px;
        gap: 20px;
      }
      
      .mode-button {
        padding: 12px 20px;
        border: none;
        border-radius: 30px;
        background-color: #3498db;
        color: white;
        font-weight: bold;
        cursor: pointer;
        transition: background-color 0.3s;
      }
      `
      .mode-button.active {
        background-color: #2ecc71;
      }
      
      .mode-button:hover {
        background-color: #2980b9;
      }
      
      .manual-controls {
        display: grid;
        grid-template-columns: repeat(3, 70px);
        grid-template-rows: repeat(3, 70px);
        gap: 5px;
      }
      
      .control-button {
        background-color: #34495e;
        color: white;
        border: none;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 24px;
        cursor: pointer;
        transition: transform 0.1s, background-color 0.3s;
      }
      
      .control-button:active {
        transform: scale(0.95);
        background-color: #2c3e50;
      }
      
      .vacuum-control {
        margin-top: 20px;
      }
      
      .vacuum-button {
        padding: 12px 20px;
        border: none;
        border-radius: 30px;
        background-color: #e74c3c;
        color: white;
        font-weight: bold;
        cursor: pointer;
        transition: background-color 0.3s;
        width: 200px;
      }
      
      .vacuum-button.active {
        background-color: #c0392b;
      }
      
      .status {
        margin-top: 20px;
        padding: 10px;
        background-color: #f8f9fa;
        border-radius: 5px;
        font-size: 14px;
      }
      
      /* Arrow symbols */
      .arrow-up::after { content: "↑"; }
      .arrow-down::after { content: "↓"; }
      .arrow-left::after { content: "←"; }
      .arrow-right::after { content: "→"; }
      .arrow-stop::after { content: "■"; }
    </style>
  </head>

  <body>
    <div class="container">
      <h1>Smart Vacuum Cleaner</h1>
      
      <div class="camera-container">
        <img id="cameraImage" src="" alt="Camera Feed">
      </div>
      
      <div class="controls">
        <div class="mode-controls">
          <button id="manualModeBtn" class="mode-button active" onclick="setMode('manual')">Manual Mode</button>
          <button id="autoModeBtn" class="mode-button" onclick="setMode('auto')">Auto Mode</button>
        </div>
        
        <div id="manualControls" class="manual-controls">
          <div></div>
          <button class="control-button arrow-up" ontouchstart='sendCommand("move","1")' ontouchend='sendCommand("move","0")' onmousedown='sendCommand("move","1")' onmouseup='sendCommand("move","0")'></button>
          <div></div>
          
          <button class="control-button arrow-left" ontouchstart='sendCommand("move","3")' ontouchend='sendCommand("move","0")' onmousedown='sendCommand("move","3")' onmouseup='sendCommand("move","0")'></button>
          <button class="control-button arrow-stop" ontouchstart='sendCommand("move","0")' onmousedown='sendCommand("move","0")'></button>
          <button class="control-button arrow-right" ontouchstart='sendCommand("move","4")' ontouchend='sendCommand("move","0")' onmousedown='sendCommand("move","4")' onmouseup='sendCommand("move","0")'></button>
          
          <div></div>
          <button class="control-button arrow-down" ontouchstart='sendCommand("move","2")' ontouchend='sendCommand("move","0")' onmousedown='sendCommand("move","2")' onmouseup='sendCommand("move","0")'></button>
          <div></div>
        </div>
        
        <div class="vacuum-control">
          <button id="vacuumBtn" class="vacuum-button" onclick="toggleVacuum()">Turn Vacuum ON</button>
        </div>
        
        <div class="status" id="statusDisplay">
          Status: Manual Mode | Vacuum: OFF
        </div>
      </div>
    </div>
    
    <script>
      // WebSocket connections
      var cameraWebSocket;
      var inputWebSocket;
      var isManualMode = true;
      var isVacuumOn = false;
      
      function initWebSockets() {
        // Camera WebSocket
        cameraWebSocket = new WebSocket("ws://" + window.location.hostname + "/Camera");
        cameraWebSocket.binaryType = 'blob';
        cameraWebSocket.onopen = function(event) {
          console.log("Camera WebSocket connected");
        };
        cameraWebSocket.onclose = function(event) {
          console.log("Camera WebSocket disconnected, reconnecting...");
          setTimeout(function() { initWebSockets(); }, 2000);
        };
        cameraWebSocket.onmessage = function(event) {
          document.getElementById("cameraImage").src = URL.createObjectURL(event.data);
        };
        
        // Control WebSocket
        inputWebSocket = new WebSocket("ws://" + window.location.hostname + "/RobotInput");
        inputWebSocket.onopen = function(event) {
          console.log("Control WebSocket connected");
          // Send initial mode
          sendCommand("mode", isManualMode ? "manual" : "auto");
          sendCommand("vacuum", isVacuumOn ? "1" : "0");
        };
        inputWebSocket.onclose = function(event) {
          console.log("Control WebSocket disconnected, reconnecting...");
          setTimeout(function() { initWebSockets(); }, 2000);
        };
      }
      
      function sendCommand(command, value) {
        if (inputWebSocket && inputWebSocket.readyState === WebSocket.OPEN) {
          inputWebSocket.send(command + "," + value);
        }
      }
      
      function setMode(mode) {
        isManualMode = (mode === 'manual');
        document.getElementById('manualModeBtn').classList.toggle('active', isManualMode);
        document.getElementById('autoModeBtn').classList.toggle('active', !isManualMode);
        document.getElementById('manualControls').style.opacity = isManualMode ? "1" : "0.5";
        document.getElementById('manualControls').style.pointerEvents = isManualMode ? "auto" : "none";
        
        sendCommand("mode", mode);
        updateStatus();
      }
      
      function toggleVacuum() {
        isVacuumOn = !isVacuumOn;
        document.getElementById('vacuumBtn').textContent = isVacuumOn ? "Turn Vacuum OFF" : "Turn Vacuum ON";
        document.getElementById('vacuumBtn').classList.toggle('active', isVacuumOn);
        
        sendCommand("vacuum", isVacuumOn ? "1" : "0");
        updateStatus();
      }
      
      function updateStatus() {
        const modeText = isManualMode ? "Manual Mode" : "Automatic Mode";
        const vacuumText = isVacuumOn ? "ON" : "OFF";
        document.getElementById('statusDisplay').textContent = `Status: ${modeText} | Vacuum: ${vacuumText}`;
      }
      
      window.onload = function() {
        initWebSockets();
        updateStatus();
      };
    </script>
  </body>
</html>
)HTMLHOMEPAGE";


// Function to measure distance with ultrasonic sensor
int getDistance() {
  // Clear the trigger pin
  digitalWrite(ULTRASONIC_TRIG, LOW);
  delayMicroseconds(2);
  
  // Set the trigger pin HIGH for 10 microseconds
  digitalWrite(ULTRASONIC_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRASONIC_TRIG, LOW);
  
  // Read the echo pin, return the sound wave travel time in microseconds
  long duration = pulseIn(ULTRASONIC_ECHO, HIGH);
  
  // Calculate the distance
  int distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  
  return distance;
}

// Move the servo to look around
void scanSurroundings() {
  // Scan from left to right
  for (int angle = 0; angle <= 180; angle += 45) {
    servoMotor.write(angle);
    delay(300); // Give servo time to move
    int distance = getDistance();
    
    // If the distance is safe, return this angle
    if (distance > minDistance) {
      servoAngle = angle;
      return;
    }
  }
  
  // If no safe direction found, turn around
  servoAngle = 180;
}

// Robot movement control
void rotateMotor(int motorNumber, int motorDirection) {
  if (motorDirection == FORWARD) {
    digitalWrite(motorPins[motorNumber].pinIN1, HIGH);
    digitalWrite(motorPins[motorNumber].pinIN2, LOW);
  }
  else if (motorDirection == BACKWARD) {
    digitalWrite(motorPins[motorNumber].pinIN1, LOW);
    digitalWrite(motorPins[motorNumber].pinIN2, HIGH);
  }
  else {
    digitalWrite(motorPins[motorNumber].pinIN1, LOW);
    digitalWrite(motorPins[motorNumber].pinIN2, LOW);
  }
}

void moveRobot(int direction) {
  Serial.printf("Moving robot: %d\n", direction);
  
  switch(direction) {
    case UP:
      rotateMotor(RIGHT_MOTOR, FORWARD);
      rotateMotor(LEFT_MOTOR, FORWARD);
      break;
    
    case DOWN:
      rotateMotor(RIGHT_MOTOR, BACKWARD);
      rotateMotor(LEFT_MOTOR, BACKWARD);
      break;
    
    case LEFT:
      rotateMotor(RIGHT_MOTOR, FORWARD);
      rotateMotor(LEFT_MOTOR, BACKWARD);
      break;
    
    case RIGHT:
      rotateMotor(RIGHT_MOTOR, BACKWARD);
      rotateMotor(LEFT_MOTOR, FORWARD);
      break;
    
    case STOP:
    default:
      rotateMotor(RIGHT_MOTOR, STOP_MOTOR);
      rotateMotor(LEFT_MOTOR, STOP_MOTOR);
      break;
  }
}

// Control vacuum motor
void setVacuum(bool state) {
  vacuumOn = state;
  digitalWrite(VACUUM_PIN, state ? HIGH : LOW);
  Serial.printf("Vacuum: %s\n", state ? "ON" : "OFF");
}

// Automatic navigation mode
void runAutomaticMode() {
  // Check distance every 500ms
  if (millis() - lastDistanceCheck > 500) {
    lastDistanceCheck = millis();
    
    // Get distance from ultrasonic sensor
    int distance = getDistance();
    Serial.printf("Distance: %d cm\n", distance);
    
    // If obstacle detected, scan surroundings and change direction
    if (distance < minDistance) {
      moveRobot(STOP);
      delay(100);
      
      scanSurroundings();
      
      // Based on servo angle, decide where to go
      if (servoAngle < 45) {
        // Obstacle on the left, turn right
        moveRobot(RIGHT);
        delay(700);
      } 
      else if (servoAngle > 135) {
        // Obstacle on the right, turn left
        moveRobot(LEFT);
        delay(700);
      } 
      else {
        // Obstacle ahead, turn around
        moveRobot(LEFT);
        delay(1400); // Longer turn to do a 180
      }
      
      // Return servo to center
      servoMotor.write(90);
      
      // Move forward
      moveRobot(UP);
    } 
    else {
      // No obstacle, keep moving forward
      moveRobot(UP);
    }
  }
}

// Web server handlers
void handleRoot(AsyncWebServerRequest *request) {
  request->send_P(200, "text/html", htmlHomePage);
}

void handleNotFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "File Not Found");
}

// WebSocket event handlers
void onRobotInputWebSocketEvent(AsyncWebSocket *server, 
                      AsyncWebSocketClient *client, 
                      AwsEventType type,
                      void *arg, 
                      uint8_t *data, 
                      size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      moveRobot(STOP);
      break;
    case WS_EVT_DATA:
      AwsFrameInfo *info;
      info = (AwsFrameInfo*)arg;
      if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
        std::string myData = "";
        myData.assign((char *)data, len);
        std::istringstream ss(myData);
        std::string key, value;
        std::getline(ss, key, ',');
        std::getline(ss, value, ',');
        Serial.printf("Key [%s] Value[%s]\n", key.c_str(), value.c_str());
        
        if (key == "move") {
          int directionValue = atoi(value.c_str());
          moveRobot(directionValue);
        }
        else if (key == "mode") {
          automaticMode = (value == "auto");
          Serial.printf("Mode changed to: %s\n", automaticMode ? "Automatic" : "Manual");
          
          // If switching to manual mode, stop the robot
          if (!automaticMode) {
            moveRobot(STOP);
          }
        }
        else if (key == "vacuum") {
          bool vacuumState = (value == "1");
          setVacuum(vacuumState);
        }
      }
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
    default:
      break;
  }
}

void onCameraWebSocketEvent(AsyncWebSocket *server, 
                      AsyncWebSocketClient *client, 
                      AwsEventType type,
                      void *arg, 
                      uint8_t *data, 
                      size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("Camera WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      cameraClientId = client->id();
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("Camera WebSocket client #%u disconnected\n", client->id());
      cameraClientId = 0;
      break;
    case WS_EVT_DATA:
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
    default:
      break;
  }
}

// Camera setup
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;
  
  // Set lower resolution to improve performance
  config.frame_size = FRAMESIZE_VGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;

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

  // Enable PSRAM if available
  if (psramFound()) {
    heap_caps_malloc_extmem_enable(20000);
    Serial.println("PSRAM initialized");
  }
}

// Send camera frame to WebSocket clients
void sendCameraPicture() {
  if (cameraClientId == 0) {
    return;
  }
  
  // Capture a frame
  camera_fb_t * fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Failed to get camera frame buffer");
    return;
  }

  // Send the image via WebSocket
  wsCamera.binary(cameraClientId, fb->buf, fb->len);
  esp_camera_fb_return(fb);
  
  // Wait for message to be delivered
  while (true) {
    AsyncWebSocketClient * clientPointer = wsCamera.client(cameraClientId);
    if (!clientPointer || !(clientPointer->queueIsFull())) {
      break;
    }
    delay(1);
  }
}
`
`
// Set up the hardware pin modes
void setupPins() {
  // Setup Motor pins
  for (int i = 0; i < motorPins.size(); i++) {
    pinMode(motorPins[i].pinIN1, OUTPUT);
    pinMode(motorPins[i].pinIN2, OUTPUT);
  }
  
  // Setup vacuum control pin
  pinMode(VACUUM_PIN, OUTPUT);
  digitalWrite(VACUUM_PIN, LOW); // Start with vacuum off
  
  // Setup ultrasonic sensor pins
  pinMode(ULTRASONIC_TRIG, OUTPUT);
  pinMode(ULTRASONIC_ECHO, INPUT);
  
  // Initialize servo
  servoMotor.attach(SERVO_PIN);
  servoMotor.write(90); // Center position
  
  // Initialize all motors to stopped position
  moveRobot(STOP);
}

void setup() {
  Serial.begin(115200);
  
  // Setup hardware pins
  setupPins();
  
  // Set up WiFi access point
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  // Configure web server routes
  server.on("/", HTTP_GET, handleRoot);
  server.onNotFound(handleNotFound);
  
  // Add WebSocket handlers
  wsCamera.onEvent(onCameraWebSocketEvent);
  server.addHandler(&wsCamera);

  wsRobotInput.onEvent(onRobotInputWebSocketEvent);
  server.addHandler(&wsRobotInput);

  // Start the server
  server.begin();
  Serial.println("HTTP server started");

  // Initialize camera
  setupCamera();
  
  Serial.println("Smart Vacuum Cleaner Robot ready!");
}

void loop() {
  // Clean up disconnected WebSocket clients
  wsCamera.cleanupClients();
  wsRobotInput.cleanupClients();
  
  // Send camera picture
  sendCameraPicture();
  
  // Run automatic mode if enabled
  if (automaticMode) {
    runAutomaticMode();
  }
  
  // Small delay to prevent CPU overload
  delay(10);
}

Wrap the error you received in a code block, just like the code you posted.

Show a wiring diagram. Perhaps something is connected incorrectly, causing a reboot.