ESP32 code for forklift not working 100%

I'm trying to code a ESP32 board for a RC forklift project. I have everything working except the drive motors wont make both motors go forward and back. Only 1 spins and it spins the wrong direction. It also doesn't appear to be adjusting speed with the joystick as well as not spinning very fast.

I'm using a esp32 board with ps3 controller. I'm also using n20 motors with h-bridges. If you think your able to help, let me know how I can post the code as I can't upload the file being a new user.

The other issue is I have no idea the code language yet and the code so far is based off what AI helped make. I do have another file that works but it doesn't work as well as this one to control the mast and steering servos.

Thanks in advance.

Welcome!
Connect this to that and press the thing on the left. That is about the same information you gave us.

How to Get the Right Help Faster:

You can spend weeks spinning your wheels, or you might get lucky and solve your problem quickly. To avoid unnecessary delays, it’s crucial to provide an annotated schematic of your circuit as you have it wired, showing all connections, including power, ground, and supplies.

Why Detailed Information Matters:

  • Annotated Schematics: These are essential because they show exactly how your circuit is set up. Without them, it's difficult for anyone to understand what you’ve done, which makes troubleshooting nearly impossible. Fritzing diagrams or unclear pictures are not enough.
  • Technical Information: Many modules look similar and may even have the same name, but they can function differently. This is why we always ask for links to detailed technical information—not just sales pages like those on Amazon, which often lack the specifics we need.
  • Post your Software Without that we do not have a clue as to how it is expected to operate.
  • Show All Connections: It’s important to include every connection, especially power and ground, in your schematic. Missing these details makes it hard to determine if a setup issue might be causing your problem.

My Process:

When I see a question, I spend a moment assessing it. If it’s missing critical information, I might ask for it. However, if it's repeatedly lacking important details, I may assume the questioner is not serious and move on to another query.

What You Need to Consider:

We don’t know your skill level or what resources you have available. If you’re missing key technical details or seem unprepared, it may indicate that you need to spend more time learning the basics before starting your project.

Providing the right information upfront will help you get the best possible assistance and avoid the frustration of running into dead ends. Let us help you by sharing what you have clearly and completely!

Try reading this: How to get the best out of this forum

ESP32 Dev Kit v1 Board

Software Audrino IDE
ESP32 v2.0.1.7
ESP32Servo by Kevin Harrington
PS3 Controller Host by Jeffery van Pernis

Here is the code that was written for the forklift that doesn't work the greatest.

#include <Ps3Controller.h>
#include <ESP32Servo.h>  // by Kevin Harrington

#define steeringServoPin 23
#define mastTiltServoPin 22
#define cabLights 32
#define auxLights 33

#define mastMotor0 25  // Used for controlling auxiliary attachment movement
#define mastMotor1 26  // Used for controlling auxiliary attachment movement
#define auxAttach0 18  // Used for controlling auxiliary attachment movement
#define auxAttach1 17  // Used for controlling auxiliary attachment movement

#define leftMotor0 21   // Used for controlling the left motor movement
#define leftMotor1 19   // Used for controlling the left motor movement
#define rightMotor0 33  // Used for controlling the right motor movementc:\Users\JohnC\Desktop\SOLIDWORKS Connected.lnk
#define rightMotor1 32  // Used for controlling the right motor movement

Servo steeringServo;
Servo mastTiltServo;

int servoDelay = 0;
int lightSwitchTime = 0;

float adjustedSteeringValue = 86;
float adjustedThrottleValue = 0;
float steeringAdjustment = 1;
int steeringTrim = 0;

int mastTiltValue = 90;
int mastTilt = 0;


bool lightsOn = false;
bool moveMastTiltServoDown = false;
bool moveMastTiltServoUp = false;
bool hardLeft;
bool hardRight;


void notify() {
  //--------------- Digital D-pad button events --------------
  if (Ps3.event.button_down.up) {
    Serial.println("Started pressing the up button");
    mastTilt = 1;
  }
  if (Ps3.event.button_down.down) {
    Serial.println("Started pressing the down button");
    mastTilt = 2;
  }
  if (Ps3.event.button_up.up) {
    Serial.println("Released the up button");
    mastTilt = 0;
  }
  if (Ps3.event.button_up.down) {
    Serial.println("Released the down button");
    mastTilt = 0;
  }

  //---------------- Analog stick value events ---------------
  if (abs(Ps3.event.analog_changed.stick.lx) + abs(Ps3.event.analog_changed.stick.ly) > 2) {
    // Serial.print("Moved the left stick:");
    // Serial.print(" x=");
    // Serial.print(Ps3.data.analog.stick.lx, DEC);
    // Serial.print(" y=");
    // Serial.print(Ps3.data.analog.stick.ly, DEC);
    // Serial.println();
    int LYValue = Ps3.data.analog.stick.ly * 2;
    processThrottle(LYValue);
  }

  if (abs(Ps3.event.analog_changed.stick.rx) + abs(Ps3.event.analog_changed.stick.ry) > 2) {
    //  Serial.print("Moved the right stick:");
    // Serial.print(" x=");
    // Serial.print(Ps3.data.analog.stick.rx, DEC);
    // Serial.print(" y=");
    // Serial.print(Ps3.data.analog.stick.ry, DEC);
    // Serial.println();
    int RXValue = (Ps3.data.analog.stick.rx);
    adjustedSteeringValue = 90 - (RXValue / 3);
    int RYValue = (Ps3.data.analog.stick.ry);
    steeringServo.write(adjustedSteeringValue + steeringTrim);

    if (adjustedSteeringValue > 100) {
      steeringAdjustment = ((200 - adjustedSteeringValue) / 100);
    } else if (adjustedSteeringValue < 80) {
      steeringAdjustment = ((200 - (90 + (90 - adjustedSteeringValue))) / 100);
    }
    processThrottle(adjustedThrottleValue);

    if (RYValue > 100 || RYValue < -100) {
      moveMotor(mastMotor0, mastMotor1, RYValue);
    } else {
      moveMotor(mastMotor0, mastMotor1, 0);
    }
  }
  //------------------------shoulder buttons events ----------------
  if (Ps3.event.button_down.r1) {
    if (steeringTrim < 20) {
      steeringTrim = steeringTrim + 2;
      steeringServo.write(adjustedSteeringValue + steeringTrim);
      delay(50);
    }
  }
  if (Ps3.event.button_down.l1) {
    if (steeringTrim > -20) {
      steeringTrim = steeringTrim - 2;
      steeringServo.write(adjustedSteeringValue + steeringTrim);
      delay(50);
    }
  }
  //------------------------trigger buttons events ----------------
  if (Ps3.event.button_down.l2) {
    hardLeft = true;
    processThrottle(adjustedThrottleValue);
    delay(10);
    Serial.println("Started pressing the left trigger button");
  }
  if (Ps3.event.button_up.l2) {
    hardLeft = false;
    processThrottle(adjustedThrottleValue);
    delay(10);
    Serial.println("Released the left trigger button");
  }
  if (Ps3.event.button_down.r2) {
    hardRight = true;
    processThrottle(adjustedThrottleValue);
    delay(10);
    Serial.println("Started pressing the right trigger button"); 
  }
  if (Ps3.event.button_up.r2) {
    hardRight = false;
    processThrottle(adjustedThrottleValue);
    delay(10);
    Serial.println("Released the right trigger button");
  }

  //------------------------ Joystick Button events ----------------
  if (Ps3.event.button_down.r3) {
    if ((millis() - lightSwitchTime) > 200) {
      if (lightsOn) {
        digitalWrite(auxAttach0, LOW);
        digitalWrite(auxAttach1, LOW);
        lightsOn = false;
      } else {
        digitalWrite(auxAttach0, HIGH);
        digitalWrite(auxAttach1, LOW);
        lightsOn = true;
      }
      lightSwitchTime = millis();
    }
    Serial.println("Started pressing the right stick button");
  }
  if (servoDelay >= 5) {
    if (mastTilt == 1 && mastTiltValue >= 10 && mastTiltValue < 170) {
      mastTiltValue = mastTiltValue + 1;
      mastTiltServo.write(mastTiltValue);
      servoDelay = 0;
    }
    if (mastTilt == 2 && mastTiltValue <= 170 && mastTiltValue > 10) {
      mastTiltValue = mastTiltValue - 1;
      mastTiltServo.write(mastTiltValue);
      servoDelay = 0;
    }
  }
  servoDelay++;
}
void processThrottle(int throttleValue) {
  adjustedThrottleValue = throttleValue;
  if (adjustedThrottleValue > 15 || adjustedThrottleValue < -15) {
    if (hardRight) {
      moveMotor(rightMotor0, rightMotor1, -1 * (adjustedThrottleValue * steeringAdjustment));
    } else if (hardLeft) {
      moveMotor(leftMotor0, leftMotor1, -1 * (adjustedThrottleValue * steeringAdjustment));
    } else if (adjustedSteeringValue > 100) {
      moveMotor(leftMotor0, leftMotor1, adjustedThrottleValue * steeringAdjustment);
      moveMotor(rightMotor0, rightMotor1, adjustedThrottleValue);
    } else if (adjustedSteeringValue < 80) {
      moveMotor(leftMotor0, leftMotor1, adjustedThrottleValue);
      moveMotor(rightMotor0, rightMotor1, adjustedThrottleValue * steeringAdjustment);
    } else {
      moveMotor(leftMotor0, leftMotor1, adjustedThrottleValue);
      moveMotor(rightMotor0, rightMotor1, adjustedThrottleValue);
    }
  } else {
    moveMotor(leftMotor0, leftMotor1, 0);
    moveMotor(rightMotor0, rightMotor1, 0);
  }
}

void moveMotor(int motorPin0, int motorPin1, int velocity) {
  if (velocity > 15) {
    analogWrite(motorPin0, velocity);
    analogWrite(motorPin1, LOW);
  } else if (velocity < -15) {
    analogWrite(motorPin0, LOW);
    analogWrite(motorPin1, (-1 * velocity));
  } else {
    analogWrite(motorPin0, 0);
    analogWrite(motorPin1, 0);
  }
}

void onConnect() {
  Serial.println("Connected.");
}

void setup() {

  Serial.begin(115200);

  Ps3.attach(notify);
  Ps3.attachOnConnect(onConnect);
  Ps3.begin("8c:7c:b5:fc:3b:06");
  Serial.println("Ready.");

  pinMode(auxAttach0, OUTPUT);
  pinMode(auxAttach1, OUTPUT);
  digitalWrite(auxAttach0, LOW);
  digitalWrite(auxAttach1, LOW);
  pinMode(leftMotor0, OUTPUT);
  pinMode(leftMotor1, OUTPUT);
  pinMode(rightMotor0, OUTPUT);
  pinMode(rightMotor1, OUTPUT);
  pinMode(mastMotor0, OUTPUT);
  pinMode(mastMotor1, OUTPUT);


  steeringServo.attach(steeringServoPin);
  steeringServo.write(adjustedSteeringValue);

  mastTiltServo.attach(mastTiltServoPin);
  mastTiltServo.write(mastTiltValue);
}
void loop() {
  if (!Ps3.isConnected())
    return;
  delay(500);
}


Here is the code that works well minus the drive motors wont go as noted in my above post

#include <Ps3Controller.h>
#include <ESP32Servo.h>

// --- Pin Definitions ---
#define steeringServoPin     23
#define mastTiltServoPin     22
#define cabLights            32
#define auxLights            33
#define mastMotor0           25  // Fork Lift Motor A
#define mastMotor1           26  // Fork Lift Motor B
#define leftMotor0           21  // Left Motor Forward
#define leftMotor1           19  // Left Motor Reverse
#define rightMotor0          33  // Right Motor Forward
#define rightMotor1          32  // Right Motor Reverse

// --- Servo Objects ---
Servo steeringServo;
Servo mastTiltServo;

// --- State Variables ---
int mastTiltValue = 90;
int mastTiltDirection = 0;
int servoDelay = 0;
int steeringTrim = 0;

// --- Constants ---
const int MAST_MIN = 10;
const int MAST_MAX = 170;
const int MAST_STEP = 3;
const int MAST_INTERVAL = 1;
const float steeringCenter = 90;
const int DEAD_ZONE = 10;

// --- PS3 Events ---
void onConnect() {
  Serial.println("PS3 controller connected!");
}

void notify() {
  if (Ps3.event.button_down.up) mastTiltDirection = 1;
  if (Ps3.event.button_down.down) mastTiltDirection = 2;
  if (Ps3.event.button_up.up || Ps3.event.button_up.down) mastTiltDirection = 0;

  if (Ps3.event.button_down.r1 && steeringTrim < 20) steeringTrim += 2;
  if (Ps3.event.button_down.l1 && steeringTrim > -20) steeringTrim -= 2;
}

// --- Setup ---
void setup() {
  Serial.begin(115200);

  Ps3.attach(notify);
  Ps3.attachOnConnect(onConnect);
  Ps3.begin("8c:7c:b5:fc:3b:39");  // Your PS3 controller MAC

  pinMode(leftMotor0, OUTPUT);
  pinMode(leftMotor1, OUTPUT);
  pinMode(rightMotor0, OUTPUT);
  pinMode(rightMotor1, OUTPUT);
  pinMode(mastMotor0, OUTPUT);
  pinMode(mastMotor1, OUTPUT);
  pinMode(cabLights, OUTPUT);
  pinMode(auxLights, OUTPUT);

  steeringServo.attach(steeringServoPin);
  mastTiltServo.attach(mastTiltServoPin);
  steeringServo.write(steeringCenter);
  mastTiltServo.write(mastTiltValue);

  moveMotor(leftMotor0, leftMotor1, 0);
  moveMotor(rightMotor0, rightMotor1, 0);
  moveMotor(mastMotor0, mastMotor1, 0);

  Serial.println("Waiting for PS3 controller...");
}

// --- Motor Control Helper ---
void moveMotor(int pinFWD, int pinREV, int speed) {
  speed = constrain(speed, -255, 255);
  if (speed > 0) {
    analogWrite(pinFWD, speed);
    analogWrite(pinREV, 0);
  } else if (speed < 0) {
    analogWrite(pinFWD, 0);
    analogWrite(pinREV, -speed);
  } else {
    analogWrite(pinFWD, 0);
    analogWrite(pinREV, 0);
  }
}

// --- Main Loop ---
void loop() {
  if (!Ps3.isConnected()) return;

  // --- Drive (Left Stick Y) ---
  int ly = Ps3.data.analog.stick.ly;
  int drive = abs(ly) > DEAD_ZONE ? map(ly, -128, 127, -255, 255) : 0;  // Inverted based on your test

  // --- Steering (Right Stick X) ---
  int steer = Ps3.data.analog.stick.rx;
  float steerAdjust = abs(steer) > DEAD_ZONE ? steer / 128.0 : 0;

  // Calculate left and right power
  int leftPower = constrain(drive + (steerAdjust * abs(drive)), -255, 255);
  int rightPower = constrain(drive - (steerAdjust * abs(drive)), -255, 255);

  moveMotor(leftMotor0, leftMotor1, leftPower);
  moveMotor(rightMotor0, rightMotor1, rightPower);

  // --- Steering Servo ---
  float steeringAngle = steeringCenter - (steer / 3.0) + steeringTrim;
  steeringServo.write(constrain(steeringAngle, 45, 135));

  // --- Mast Tilt (D-pad) ---
  if (servoDelay >= MAST_INTERVAL) {
    if (mastTiltDirection == 1 && mastTiltValue < MAST_MAX) {
      mastTiltValue += MAST_STEP;
      mastTiltServo.write(mastTiltValue);
      servoDelay = 0;
    } else if (mastTiltDirection == 2 && mastTiltValue > MAST_MIN) {
      mastTiltValue -= MAST_STEP;
      mastTiltServo.write(mastTiltValue);
      servoDelay = 0;
    }
  }
  servoDelay++;

  // --- Fork Lift (Right Stick Y) ---
  int ry = Ps3.data.analog.stick.ry;
  int fork = abs(ry) > DEAD_ZONE ? map(ry, -128, 127, -255, 255) : 0;
  moveMotor(mastMotor0, mastMotor1, fork);

  delay(20);
}

Please let me know if the electronics schematics are needed or if this code is sufficient. I can also provide pin numbers items are on.

Yes. Always supply code and drawing.

Both motors are probably wired or mounted backwards.

This could mean:

  1. One motor goes forward and back
  2. both motors go forward
  3. both motors go backward
  4. one motor goes forward and the other goes backwards
  5. one motor goes backward while the other goes forward.

Be more descriptive.

Motor problems are usually due to power and wiring.

Pay attention to the teacher while in class and you will not have this problem.

  1. AI does not make, it generates. It takes statistics from online code and guesses.
  2. AI does not help, because you have stated, even with AI, "I have no idea the code language"

You must be more descriptive.

All you said "above" was "it works but doesn't work"... be descriptive.

AI can't write code that complex unless it finds a 100% match on the net.
If you don't have at least a few hundred hours of experience, you are not ready for this project UNLESS you find the exact code online.
Those of us with decades of experience still build complex projects by building simple sub-projects, then merging them. That might be a big clue.
There is a book called the Arduino Cookbook that is a good teaching resource (YouTube can't bookmark, highlight or easily go back and forth several pages)
The Arduino Project HUB most likely has 99% of your project already done.
https://id.arduino.cc/?iss=https%3A%2F%2Flogin.arduino.cc%2F#/register


This is the Canadian link, change to your country

Thank you I will look in to it. I need a good place to start because I want to get into making and designing stuff as now I have fusion 360 down.

I was unaware how ai worked. I rather do the code myself as I prefer less things ai is doing but I learn by seeing things changed. Unfortunately in this case, I'm just not knowing enough on this to see what I need to do.

Also I know someone is going to say, why not ask the person that made this, they tend to not respond back to help as they are one person and get bombarded with questions.

So I'm trying to be vague on this a little bit because it's a paid project that someone made that the code was good but it's not doing exactly what it needs to.

So the orginal code works but the following items are an issue for me.

The mast tilt, (servo based), it is moving slow and jerky. It seems like sometimes I double press the arrow and it moves fast.
Now in the ai code, it moves perfect and responds well.

The steering works in the orginal code but what happens is, it moves with the stick and then doesn't return to netural position when letting off. I have to hit the stick in the same position again to return it.

In the ai code, the steering responds perfect. It moves exactly where I put the stick.

So the drive motors work fine in the orginal code. The ai code makes only the one turn, not very fast, and backwards. I did do a test with the controller with 4 push buttons to make sure the motors work properly forward and back and to map the pin numbers. The ai code would be perfect if it wasn't for the drive motor issue.

The drive motors are on the front both sides, one needs to spin opposite of the other to move forward.

If this is not enough to go off knowing the orginal code does work, I will withdraw my question. I didn't know if it was something someone could look at and tell me where I should be making changes. I tried changing things in a copy of the orginal file to see if I could get the servos operating to how I need them but I made them worse. That is why I was wondering if explaining the 2 codes if someone was able to be like, take this and this and it should work.

Like I said I'm new to this side and I'm trying to learn and figure this out at the same time.

And being a new member I can't upload pictures yet.

There is your answer. Start a new sketch using any of the stepper libraries and examples. Build a simple vehicle with proper speed and direction control. Once perfected, carefully merge it into the rest of the sketch you say is perfect.

You will find we do not ask for schematics unless they will help answer your question. Your project is way to complex for a word salad (pins and number) or frizzy. A good schematic will show all the pins, labels and connections along with all power, ground, and of course power sources.