Need help for robot w/ esp32 & PS4 controller car

Hello, everyone, I hope you may help me in my robot car project of a security robot car with aligned SDGs. Its function is to detect and roam around surroundings, acting similar to a police car. Basically its specific components are: ultrasonic sensor, servo motor, buzzer, DC motors, lcd module, rgb led, thermistor (heat detection), photoresistor (light detection), level shifter, and ps4 controller. It's main components are: Arduino UNO, Adafruit Motorshield v1, and ESP32 w/ CAM module. To add, there's no cam in the esp32 since the robot's too complex as it is.

I just need help because the problem is the robot is not moving, especially the fact that there is serious trouble in connecting the esp32 with the arduino UNO. Even if I finally managed to connect them both with a long serious effort, the problem persists with the robot not fulfilling its commands as the Arduino's serial monitor does not act; this goes back with the original problem of the connection between arduino and esp32.

Also, I've managed to at least connect successfully the ps4 controller and the esp32, and I have already planned several command buttons for the robot function.

Please help me fix this code. I'm already quite dying before being able to manage fixing this robot. :smiling_face_with_tear: :face_with_head_bandage:

Arduino UNO code

#include <Servo.h>    
#include <LiquidCrystal_I2C.h>  
#include <Wire.h>
#include <AFMotor.h>  
#include <SoftwareSerial.h>

// RX = 8, TX = 9
SoftwareSerial EspSerial(8, 9);  // RX, TX


// Pin Definitions
const int BUZZER_PIN = 7;
const int LED_R_PIN = 3;
const int LED_G_PIN = 5;
const int LED_B_PIN = 6;
const int SERVO_PIN = 10;

// Sensor Pins
const int PHOTORESISTOR_PIN = 2;  
const int THERMISTOR_PIN = 4;     
const int ULTRASONIC_TRIGGER_PIN = A2;
const int ULTRASONIC_ECHO_PIN = A3;

Servo ultrasonicServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);

bool sdgModeActive = false;
bool intruderModeActive = false;
bool obstacleDetected = false; // for off when robot is on

unsigned long lastMoveTime = 0;
int roamingState = 0;

// Motor Speed
int motorSpeed = 128;  
bool ramModeActive = false;

// Thresholds
const int HIGH_TEMP_THRESHOLD = 40;     // Temperature threshold in Celsius
const int dangerDistance = 15;          // Distance in cm, adjust as needed
const int lightThreshold = 200;         // Adjust based on your sensor range

long duration;
int distance;

// Define motors
AF_DCMotor motor1(1);  
AF_DCMotor motor2(2);  
AF_DCMotor motor3(3);  
AF_DCMotor motor4(4);  

void setup() {
  Serial.begin(19200);

  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_R_PIN, OUTPUT);
  pinMode(LED_G_PIN, OUTPUT);
  pinMode(LED_B_PIN, OUTPUT);

  pinMode(PHOTORESISTOR_PIN, INPUT); 
  pinMode(THERMISTOR_PIN, INPUT);    


  ultrasonicServo.attach(SERVO_PIN);
  ultrasonicServo.write(90);

  Wire.begin(); // Uses A4 (SDA) and A5 (SCL)
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Waiting...");

  pinMode(ULTRASONIC_TRIGGER_PIN, OUTPUT);
  pinMode(ULTRASONIC_ECHO_PIN, INPUT);
}

void loop() {
  if (EspSerial.available()) {
    String command = EspSerial.readStringUntil('\n');
    command.trim();
    handleCommand(command);
  }

  if (sdgModeActive) {
    roamAutomatically();
  }

  if (intruderModeActive) {
    monitorIntruder();
  }

  checkSensors();
}

// --- Handle incoming ESP32 commands ---
void handleCommand(String cmd) {
  if (cmd.startsWith("SERVO:")) {
    int angle = cmd.substring(6).toInt();
    ultrasonicServo.write(angle);
  }
  else if (cmd == "COMMAND: SDG_MODE_ON") {
    sdgModeActive = true;
    intruderModeActive = false;
    lcd.clear();
    lcd.print("SDG Mode ON");
    beep();
    setLEDColor(0, 255, 0);
  }
  else if (cmd == "COMMAND: SDG_MODE_OFF") {
    sdgModeActive = false;
    lcd.clear();
    lcd.print("Manual Mode");
    beep();
    setLEDColor(255, 255, 255);
  }
  else if (cmd == "COMMAND: INTRUDER_MODE_ON") {
    intruderModeActive = true;
    sdgModeActive = false;
    lcd.clear();
    lcd.print("Guard Mode");
    beep();
    setLEDColor(255, 0, 0);
  }
  else if (cmd == "COMMAND: INTRUDER_MODE_OFF") {
    intruderModeActive = false;
    lcd.clear();
    lcd.print("Manual Mode");
    beep();
    setLEDColor(255, 255, 255);
  }
  else if (cmd == "COMMAND: MANUAL_MODE") {
    sdgModeActive = false;
    intruderModeActive = false;
    lcd.clear();
    lcd.print("Manual Mode");
    beep();
    setLEDColor(255, 255, 255);
  }
  else if (cmd == "COMMAND: BUZZER_BEEP") {
    beep();
  }
  else if (cmd == "COMMAND: LED_BLINK") {
    blinkLED();
  }
  else {
    if (!sdgModeActive && !intruderModeActive) {
      handleManualDrive(cmd);
    }
  }
}

// --- Simulated roaming movement ---
void roamAutomatically() {
  unsigned long now = millis();

  if (now - lastMoveTime > 2000) {
    lastMoveTime = now;
    roamingState = (roamingState + 1) % 4;

    switch (roamingState) {
      case 0:
        moveForward();
        break;
      case 1:
        rotateLeft();
        break;
      case 2:
        moveForward();
        break;
      case 3:
        rotateRight();
        break;
    }
  }
}

// --- Intruder Monitoring ---
void monitorIntruder() {
  distance = readUltrasonic();

  if (distance < 20) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Intruder Detected!");
    beep();
    setLEDColor(255, 0, 0);

    moveBackward();
    delay(1000);
    rotateLeft();
    delay(1000);
    stopMoving();
  } else {
    // No intruder and no other warnings – turn off LCD display
    lcd.clear();
  }
}

float getTemperature(int analogValue) {
  float voltage = analogValue * 5.0 / 1023.0;
  float resistance = (5.0 - voltage) * 10000.0 / voltage;
  float tempK = 1.0 / (log(resistance / 10000.0) / 3950.0 + (1.0 / 298.15));
  return tempK - 273.15;
}

int getDistance() {
  digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(ULTRASONIC_TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
  long duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void setColor(int r, int g, int b) {
  analogWrite(LED_R_PIN, r);
  analogWrite(LED_G_PIN, g);
  analogWrite(LED_B_PIN, b);
}


// --- Sensor Checks ---
void checkSensors() {
  // Example for a multi-sensor system (temperature + light + distance)
  
  // --- Temperature Monitoring ---
  int digitalTemp = digitalRead(4); // Assume A0 for thermistor
  float temperature = getTemperature(digitalTemp);
  
  if (temperature >= HIGH_TEMP_THRESHOLD) {
    lcd.setCursor(0, 0);
    lcd.print("TEMP ALERT: ");
    lcd.print(temperature);
    lcd.print("C  ");
    lcd.setCursor(0, 1);
    lcd.print("High Heat Level");

    // High temp: rapid purple flashing + buzzer
    tone(BUZZER_PIN, 1000);
    digitalWrite(LED_R_PIN, HIGH);
    digitalWrite(LED_B_PIN, HIGH);
    digitalWrite(LED_G_PIN, LOW);
    delay(100);
    noTone(BUZZER_PIN);
    digitalWrite(LED_R_PIN, LOW);
    digitalWrite(LED_B_PIN, LOW);
    delay(100);
  }

  // --- Light Intrusion Detection ---
  int lightValue = digitalRead(2);
  if (lightValue > lightThreshold) {
    lcd.setCursor(0, 0);
    lcd.print("INTRUDER ALERT   ");
    lcd.setCursor(0, 1);
    lcd.print("Bright Light     ");

    for (int i = 0; i < 5; i++) {
      digitalWrite(BUZZER_PIN, HIGH);
      digitalWrite(LED_R_PIN, HIGH);
      digitalWrite(LED_G_PIN, LOW);
      digitalWrite(LED_B_PIN, LOW);
      delay(100);
      digitalWrite(BUZZER_PIN, LOW);
      digitalWrite(LED_R_PIN, LOW);
      delay(100);
    }
  }

  // --- Ultrasonic Distance Alert ---
  int distance = getDistance();
  if (distance > 0 && distance <= dangerDistance) {
    lcd.setCursor(0, 0);
    lcd.print("MOTION DETECTED  ");
    lcd.setCursor(0, 1);
    lcd.print("Dist: ");
    lcd.print(distance);
    lcd.print(" cm ");

    for (int i = 0; i < 3; i++) {
      digitalWrite(BUZZER_PIN, HIGH);
      setColor(255, 0, 0); // Red
      delay(150);
      digitalWrite(BUZZER_PIN, LOW);
      setColor(0, 0, 0); // Off
      delay(150);
    }
  }

  // --- Normal State ---
  if (temperature < HIGH_TEMP_THRESHOLD && lightValue <= lightThreshold && (distance > dangerDistance || distance <= 0)) {
    lcd.setCursor(0, 0);
    lcd.print("Monitoring...    ");
    lcd.setCursor(0, 1);
    lcd.print("All Normal       ");
    noTone(BUZZER_PIN);
    setColor(0, 255, 0); // Green
    delay(500);
  }
}



// --- Helper Functions ---

void beep() {
  digitalWrite(BUZZER_PIN, HIGH);
  delay(100);
  digitalWrite(BUZZER_PIN, LOW);
}

void setLEDColor(int r, int g, int b) {
  analogWrite(LED_R_PIN, r);
  analogWrite(LED_G_PIN, g);
  analogWrite(LED_B_PIN, b);
}

void blinkLED() {
  setLEDColor(255, 255, 0);
  delay(100);
  setLEDColor(0, 0, 0);
  delay(100);
  setLEDColor(255, 255, 0);
  delay(100);
  setLEDColor(0, 0, 0);
}

long readUltrasonic() {
  digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(ULTRASONIC_TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);

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


void moveForward() {
  if (obstacleDetected && !ramModeActive) {
        stopMoving();
    return;
}

  setAllMotors(FORWARD);
  Serial.println("MOVING: FORWARD");
}

void moveBackward() {
  setAllMotors(BACKWARD);
  Serial.println("MOVING: BACKWARD");
}

void rotateLeft() {
  motor1.setSpeed(motorSpeed);
  motor2.setSpeed(motorSpeed);
  motor3.setSpeed(motorSpeed);
  motor4.setSpeed(motorSpeed);

  motor1.run(BACKWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(FORWARD);
  Serial.println("MOVING: ROTATE LEFT");
}

void rotateRight() {
  motor1.setSpeed(motorSpeed);
  motor2.setSpeed(motorSpeed);
  motor3.setSpeed(motorSpeed);
  motor4.setSpeed(motorSpeed);

  motor1.run(FORWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(BACKWARD);
  Serial.println("MOVING: ROTATE RIGHT");
}

void stopMoving() {
  motor1.setSpeed(0);
  motor2.setSpeed(0);
  motor3.setSpeed(0);
  motor4.setSpeed(0);

  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  Serial.println("MOVING: STOPPED");
}

void setAllMotors(uint8_t dir) {
  motor1.setSpeed(motorSpeed);
  motor2.setSpeed(motorSpeed);
  motor3.setSpeed(motorSpeed);
  motor4.setSpeed(motorSpeed);

  motor1.run(dir);
  motor2.run(dir);
  motor3.run(dir);
  motor4.run(dir);
}

void handleManualDrive(String cmd) {
  if (cmd == "COMMAND: FORWARD") moveForward();
  else if (cmd == "COMMAND: BACKWARD") moveBackward();
  else if (cmd == "COMMAND: LEFT") rotateLeft();
  else if (cmd == "COMMAND: RIGHT") rotateRight();
  else if (cmd == "COMMAND: FORWARD_SMOOTH") moveForward();
 else if (cmd == "COMMAND: BACKWARD_SMOOTH") moveBackward();
 else if (cmd == "COMMAND: LEFT_SMOOTH") rotateLeft();
 else if (cmd == "COMMAND: RIGHT_SMOOTH") rotateRight();

else if (cmd == "COMMAND: ROTATE_LEFT_SERVO") {
  ultrasonicServo.write(45);  // Rotate servo to the left
  Serial.println("Ultrasonic Sensor Rotated Left.");
}

else if (cmd == "COMMAND: ROTATE_RIGHT_SERVO") {
  ultrasonicServo.write(135); // Rotate servo to the right
  Serial.println("Ultrasonic Sensor Rotated Right.");
}

else if (cmd == "COMMAND: ROTATE_180_SERVO") {
  ultrasonicServo.write(180); // Rotate servo to 180 degrees
  Serial.println("Ultrasonic Sensor Rotated to 180 degrees.");
}


  else if (cmd == "COMMAND: KICK_LEFT") rotateLeft();
  else if (cmd == "COMMAND: KICK_RIGHT") rotateRight();
  else if (cmd == "COMMAND: STOP") stopMoving();
  else if (cmd == "COMMAND: RAM") {  // Cross button pressed
    ramModeActive = true;
    motorSpeed = 255;
    moveForward();
    delay(1000);
    motorSpeed = 128;
    ramModeActive = false;
    stopMoving();
  }
  else if (cmd == "COMMAND: AUTO_RAM") { // Triangle button pressed
    ramModeActive = true;
    motorSpeed = 255;
    moveForward();
  }
  else if (cmd == "COMMAND: MAX_SPEED") motorSpeed = 255;
  else if (cmd == "COMMAND: MIN_SPEED") motorSpeed = 128;

  else if (cmd == "COMMAND: STOP_RAM") {
  ramModeActive = false;
  stopMoving();
}
else if (cmd == "COMMAND: NORMAL_SPEED") {
  motorSpeed = 128;
}

}

ESP32 Code (AI Thinker ESP32 board)

#include <Bluepad32.h>

ControllerPtr myController;

// Servo Rotation control flag
int servoAngle = 90; // Default servo angle

// Mode activation flags
bool sdgModeActive = false;
bool intruderModeActive = false;

// Function to process PS4 controller inputs
void processGamepad(ControllerPtr ctl) {
  if (!ctl) return;

  int axisRX = ctl->axisRX();  // Right joystick X-axis
  int axisRY = ctl->axisRY();  // Right joystick Y-axis

  // Map the R-joystick X-axis to a servo angle between 0 and 180
  servoAngle = map(axisRX, -512, 512, 0, 180);


// --- L-stick for smooth movement ---
  int axisLX = ctl->axisX();  // Left joystick X-axis (left-right)
  int axisLY = ctl->axisY();  // Left joystick Y-axis (up-down)

  // If the left analog stick is pushed up (forward), move forward
  if (axisLY < -200) {  // Threshold for moving forward
    Serial.println("L-Stick Up: Move Forward Smoothly");
    Serial.println("COMMAND: FORWARD_SMOOTH");
    Serial1.println("L-Stick Up: Move Forward Smoothly");
    Serial1.println("COMMAND: FORWARD_SMOOTH");
  }
  // If the left analog stick is pushed down (backward), move backward
  else if (axisLY > 200) {  // Threshold for moving backward
    Serial.println("L-Stick Down: Move Backward Smoothly");
    Serial.println("COMMAND: BACKWARD_SMOOTH");
    Serial1.println("L-Stick Down: Move Backward Smoothly");
    Serial1.println("COMMAND: BACKWARD_SMOOTH");
  }

  // If the left analog stick is pushed left (left), move left
  if (axisLX < -200) {  // Threshold for moving left
    Serial.println("L-Stick Left: Move Left Smoothly");
    Serial.println("COMMAND: LEFT_SMOOTH");
    Serial1.println("L-Stick Left: Move Left Smoothly");
    Serial1.println("COMMAND: LEFT_SMOOTH");
  }
  // If the left analog stick is pushed right (right), move right
  else if (axisLX > 200) {  // Threshold for moving right
    Serial.println("L-Stick Right: Move Right Smoothly");
    Serial.println("COMMAND: RIGHT_SMOOTH");
    Serial1.println("L-Stick Right: Move Right Smoothly");
    Serial1.println("COMMAND: RIGHT_SMOOTH");
  }

  // Send the servo angle to Arduino
  Serial1.print("SERVO: ");
  Serial1.println(servoAngle);
  Serial.print("SERVO: ");
  Serial.println(servoAngle);

  uint16_t buttons = ctl->buttons();

// --- D-Pad for movement ---
if (ctl->dpad() == DPAD_UP) {
  Serial.println("D-Pad Up: Move Forward");
  Serial.println("COMMAND: FORWARD");
  Serial1.println("D-Pad Up: Move Forward");
  Serial1.println("COMMAND: FORWARD");
}
else if (ctl->dpad() == DPAD_DOWN) {
  Serial.println("D-Pad Down: Move Backward");
  Serial.println("COMMAND: BACKWARD");
  Serial1.println("D-Pad Down: Move Backward");
  Serial1.println("COMMAND: BACKWARD");
}
else if (ctl->dpad() == DPAD_LEFT) {
  Serial.println("D-Pad Left: Move Left");
  Serial.println("COMMAND: LEFT");
  Serial1.println("D-Pad Left: Move Left");
  Serial1.println("COMMAND: LEFT");
}
else if (ctl->dpad() == DPAD_RIGHT) {
  Serial.println("D-Pad Right: Move Right");
  Serial.println("COMMAND: RIGHT");
  Serial1.println("D-Pad Right: Move Right");
  Serial1.println("COMMAND: RIGHT");
}



  // --- SDG Mode Toggle (L3 + R3) ---
  if (buttons == (0x0100 | 0x0200)) {  // L3 + R3 pressed
    delay(200); // Small delay for stable button reading
    if (!sdgModeActive) {
      Serial.println("L3 + R3: Activate SDG Mode");
      Serial.println("COMMAND: SDG_MODE");
      Serial1.println("L3 + R3: Activate SDG Mode");
      Serial1.println("COMMAND: SDG_MODE");
      sdgModeActive = true;
      intruderModeActive = false; // Ensure intruder mode is off
    } else {
      Serial.println("L3 + R3: Deactivate SDG Mode (Return to Manual)");
      Serial.println("COMMAND: SDG_MODE_OFF");
      Serial1.println("L3 + R3: Deactivate SDG Mode (Return to Manual)");
      Serial1.println("COMMAND: SDG_MODE_OFF");
      sdgModeActive = false;
    }
  }

  // --- Intruder Alert Mode Toggle (R3 only) ---
  else if (buttons == 0x0200) {  // R3 pressed
    delay(200); // Small delay for stable button reading
    if (!intruderModeActive) {
      Serial.println("R3: Activate Intruder Alert Mode");
      Serial.println("COMMAND: INTRUDER_ALERT_MODE");
      Serial1.println("R3: Activate Intruder Alert Mode");
      Serial1.println("COMMAND: INTRUDER_ALERT_MODE");
      intruderModeActive = true;
      sdgModeActive = false; // Ensure SDG mode is off
    } else {
      Serial.println("R3: Deactivate Intruder Mode (Return to Manual)");
      Serial.println("COMMAND: INTRUDER_ALERT_MODE_OFF");
      Serial1.println("R3: Deactivate Intruder Mode (Return to Manual)");
      Serial1.println("COMMAND: INTRUDER_ALERT_MODE_OFF");
      intruderModeActive = false;
    }
  }

  // --- L3 Only ---
  else if (buttons == 0x0100) {  // L3 pressed alone
    delay(200);
    Serial.println("L3: Manual Mode Activated (Forced)");
    Serial.println("COMMAND: MANUAL_MODE");
    Serial1.println("L3: Manual Mode Activated (Forced)");
    Serial1.println("COMMAND: MANUAL_MODE");

    // Reset modes
    sdgModeActive = false;
    intruderModeActive = false;

    // Feedback: Buzzer beep and LED blink command
    Serial.println("COMMAND: BUZZER_BEEP");
    Serial.println("COMMAND: LED_BLINK");
    Serial1.println("COMMAND: BUZZER_BEEP");
    Serial1.println("COMMAND: LED_BLINK");
  }

  // --- Normal manual controls ---
  else if (!sdgModeActive && !intruderModeActive) {
    // Handle button commands ONLY if no mode is active
    if (buttons == 0x0001) {  // Cross button
      Serial.println("CROSS: RAM FORWARD");
      Serial.println("COMMAND: FORWARD");
      Serial1.println("CROSS: RAM FORWARD");
      Serial1.println("COMMAND: FORWARD");
    }

    if (buttons == 0x0002) {  // Circle button
      Serial.println("CIRCLE: Kick Left");
      Serial.println("COMMAND: KICK_LEFT");
      Serial1.println("CIRCLE: Kick Left");
      Serial1.println("COMMAND: KICK_LEFT");
    }

    if (buttons == 0x0004) {  // Square button
      Serial.println("SQUARE: Rotate Left");
      Serial.println("COMMAND: ROTATE_LEFT");
      Serial1.println("SQUARE: Rotate Left");
      Serial1.println("COMMAND: ROTATE_LEFT");
    }

    if (buttons == 0x0008) {  // Triangle button
      Serial.println("TRIANGLE: Rotate Right");
      Serial.println("COMMAND: ROTATE_RIGHT");
      Serial1.println("TRIANGLE: Rotate Right");
      Serial1.println("COMMAND: ROTATE_RIGHT");
    }

    if (buttons == 0x0040) {  // L2 button
      Serial.println("L2: Decelerate and Stop");
      Serial.println("COMMAND: STOP");
      Serial1.println("L2: Decelerate and Stop");
      Serial1.println("COMMAND: STOP");
    }

    if (buttons == 0x0080) {  // R2 button
      Serial.println("R2: Accelerate at Max Speed");
      Serial.println("COMMAND: MAX_SPEED");
      Serial1.println("R2: Accelerate at Max Speed");
      Serial1.println("COMMAND: MAX_SPEED");
    }

    // Handle L1 and R1 (Servo Rotation)
    if (buttons == 0x0010) {  // L1
      Serial.println("L1: Rotate Servo Left");
      Serial.println("COMMAND: ROTATE_LEFT_SERVO");
      Serial1.println("L1: Rotate Servo Left");
      Serial1.println("COMMAND: ROTATE_LEFT_SERVO");
    }

    if (buttons == 0x0020) {  // R1
      Serial.println("R1: Rotate Servo Right");
      Serial.println("COMMAND: ROTATE_RIGHT_SERVO");
      Serial1.println("R1: Rotate Servo Right");
      Serial1.println("COMMAND: ROTATE_RIGHT_SERVO");
    }

    if (buttons == (0x0010 | 0x0020)) {  // L1 + R1
      Serial.println("L1 + R1: Rotate Servo to 180 degrees");
      Serial.println("COMMAND: ROTATE_180_SERVO");
      Serial1.println("L1 + R1: Rotate Servo to 180 degrees");
      Serial1.println("COMMAND: ROTATE_180_SERVO");
    }
  }
}

void onConnect(ControllerPtr ctl) {
  Serial1.println("Controller Connected");
  myController = ctl;
}

void onDisconnect(ControllerPtr ctl) {
  Serial1.println("Controller Disconnected");
  myController = nullptr;
}

void setup() {
  Serial.begin(19200);
  // Use GPIO2 as RX and GPIO4 as TX for Serial1
  Serial1.begin(19200, SERIAL_8N1, 2, 4);

  BP32.setup(&onConnect, &onDisconnect);
  BP32.forgetBluetoothKeys();
}

void loop() {
  bool dataUpdated = BP32.update();
  if (dataUpdated) {
    processGamepad(myController);
  }
  delay(10);  // Small delay for smoother operation
}

Does the code compile? I assume it does, or you would have mentioned it. So now it runs, and you have shown us no log of it running. Do you think it's possible to help you without some debug info?
We will also need a picture (or several) of hand-drawn wiring diagrams.

Is the power supply adequate for the system, especially the motors?

No need for secret code here. Just say what you mean.

Have your plans worked? Do the PS4 commands/controls make the ESP show the command/control arrived?

Where did you obtain the code?

How does the esp32cam communicate with the UNO?

power supply is adequate enough for the whole system. It's a security robot. The plan was to establish a connection between the arduino and the esp32, and the ps4 commands have indeed shown in the esp32. I made the code myself while studying the code and how to make it in youtube and other sources. I also searched through ai search engines on how to proceed with the coding, like ChatGPT, Bing, etc.

using serial1 communication which will send the serial commands to the UNO

Sorry, but it's honestly one of my first time in coding, really. But I was too ambitious with what my robot project would be, so I've had a really hard time, even with practice and reference from other sources. It does compile and upload, of course; also, I can't seem to provide some debug info yet of the arduino since as i mentioned, there's no connection yet between it and esp32. Also, I'll try to provide wiring connections of the diagram in the mean time.

How does the esp32cam communicate with the UNO?

Basically through Serial1 communication from esp32 to Arduino w/ SoftwareSerial

ESP32 -------- Arduino
GPIO2 (RX) - Pin 4 (TX)
GPIO4 (TX) - Pin 2 (RX) w/ level shifter
GND - GND
5V - 5V

Why are two boards needed? Put all the code on a normal ESP32 if you are not using the camera.

First off, actually, we were required to use an Arduino UNO for robot projects, so I was kinda forced to have 2 boards. Second, It's actually a groupwork, so my groupmate bought a different kind of ESP32 model, but I think they should work fine and same as a normal esp32. Third, It'd actually be much better for me in my case since I'm quite already familiar with how an Arduino code works, rather than esp32 only because there would only be needed a connection between it and the arduino uno and also that I'm not quite familiar with how to make the coding of esp32. And fourth, it gives me more pins for my other components to be pinned on.

Coding for the UNO and esp32 is almost identical.
Without legible wiring diagrams (actual, not the plan) and an attempt by you to debug with Serial.print statements I can't do much more as there is nothing to work with.

You need to solve this first. Plug in another PC to the esp32 so you can do Serial.print.

Start with the required material only. Remove the "COMMAND" and redundant "distance" part from your copy/paste of multiple sketches. Use one "distance" result to determine direction of travel. Use the "temperature" sensor to activate bells and whistles.

Leave the comms, ESP32 and PS4 for when you learn to code. What you are asking right now, is for someone else to do your work. Do this yourself, for your learning.

Another example of copy/paste... roamAutomatically() will never happen.

  if (sdgModeActive) {
    roamAutomatically();
  }

Draw up a plan. Write "pseudo code" to explain how the plan works. Read about "finite state machine" (many use switch(case)) to move among "automatic" and "obstacle avoidance" and "intruder" and "?heat sensor?firetruck?"