Servo motor not working

I'm using an esp32 to control 4 motors, a stepper motor, and a servo, and everything works except the servo. I troubleshooted and found out the servo fails to work due to the analog write command to control the motors. Why does the analogwrite cause issues with the servo?

Hi, @luke_jewison
Welcome to the forum.

Have you got code that JUST controls the servo?
If not, then write some simple code, or use one of the library's examples, to prove you have hardware and software control.

Can you post your code?
can you please post a schematic?

Thanks, Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Hi.
Using analogWrite isn't recommended to use in a servo motor. You have to use the library included for controlling servo motors using ESP32 in order to get full 360 degrees of rotation (since it sends the right frequency to control the servo motor).

1 Like

I'm not using analogwrite for the servo. I'm using the servo library, but there are analogwritrs in the code because of the DC motors. they shouldn't have anything to do with the servo.

Oh. Looks like I got this wrong.
Anyways, would you mind posting the schematic (and maybe the sketch) so we could see where the problem is?

Maybe it doesn't. Maybe powering issue...Try the code with "analog" motors disconnected.
There would be much less guessing if you simply post your code and wiring scheme.

AI response ?

1 Like

(I thought about it being like AI responding, but no, I'm not AI...)

Are you using the ESP32 Servo library?

1 Like

Yes it works just fine when there are no analogwrites in the code.

Hi, @luke_jewison

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:


I'm not sure how to do a schematic but there's a picture of the project. 2 motor drivers each controlling two motors powered by 9 volts in the wall dropped down to about 6 volts.

#include <XboxSeriesXControllerESP32_asukiaaa.hpp>
#include <ESP32Servo.h>
#include <Stepper.h>

// Required to replace with your xbox address
// XboxSeriesXControllerESP32_asukiaaa::Core
// xboxController("44:16:22:5e:b2:d4");

// any xbox controller
XboxSeriesXControllerESP32_asukiaaa::Core xboxController;
Servo myServo;

uint16_t joystickMax = XboxControllerNotificationParser::maxJoy;
float LJoystickX;
float RJoystickX;
float LJoystickY;
float RJoystickY;
int frontLeftMotorPin = 4;
int frontRightMotorPin = 15;
int backLeftMotorPin = 0;
int backRightMotorPin = 2;
double throttle;
int dirLeftPin1 = 5;
int dirLeftPin2 = 18;
int dirRightPin1 = 17;
int dirRightPin2 = 16;
int connectionLEDPin = 32;
int notConnectedLEDPin = 33;
bool Ldirection; //1 is forward 0 is backward
bool Rdirection;
bool firstStart = 1;
float Lspeed;
float Rspeed;
float Lvelocity;
float Rvelocity;
float Lpower;
float Rpower;
float powerMag; 
int servoPin = 21;
int servoPos = 0;
int stepperSpeed = 15;
int stepsPerRevolution = 2048;
int stepperInOne = 14;
int stepperInTwo = 27;
int stepperInThree = 26;
int stepperInFour = 25;

Stepper myStepper(stepsPerRevolution,stepperInOne,stepperInThree,stepperInTwo,stepperInFour);


void setup() {
  Serial.begin(115200);
  Serial.println("Starting NimBLE Client");
  xboxController.begin();

  pinMode(frontLeftMotorPin,OUTPUT);
  pinMode(frontRightMotorPin,OUTPUT);
  pinMode(backLeftMotorPin,OUTPUT);
  pinMode(backRightMotorPin,OUTPUT);
  pinMode(dirLeftPin1,OUTPUT);
  pinMode(dirLeftPin2,OUTPUT);
  pinMode(dirRightPin1,OUTPUT);
  pinMode(dirRightPin2,OUTPUT);
  pinMode(connectionLEDPin,OUTPUT);
  pinMode(notConnectedLEDPin,OUTPUT);
  pinMode(servoPin,OUTPUT);

  myServo.attach(servoPin);
  myStepper.setSpeed(stepperSpeed);
}

void loop() {
  xboxController.onLoop();
  if (xboxController.isConnected()) {
    if (xboxController.isWaitingForFirstNotification()) {
      Serial.println("waiting for first notification");
    } else {
      digitalWrite(connectionLEDPin,1);
      digitalWrite(notConnectedLEDPin,0);

      throttle = ((double)xboxController.xboxNotif.trigRT - (double)xboxController.xboxNotif.trigLT) / 1023;
      LJoystickX = (((float)xboxController.xboxNotif.joyLHori * 255) / joystickMax) - 127.5;
      LJoystickY = 127.5 - (((float)xboxController.xboxNotif.joyLVert * 255) / joystickMax);
      RJoystickX = (((float)xboxController.xboxNotif.joyRHori * 255) / joystickMax) - 127.5;
      RJoystickY = 127.5 - (((float)xboxController.xboxNotif.joyRVert * 255) / joystickMax); 


      if (xboxController.xboxNotif.btnX==1) {
        servoPos = 0;        
      }
      if (xboxController.xboxNotif.btnB==1) {
        Serial.println(Rvelocity);
        myStepper.step(stepsPerRevolution);
      }
      if (xboxController.xboxNotif.btnA==1) {
        Serial.println(servoPos);
        servoPos++;
        myServo.write(servoPos);
        delay(100);
      }
 
      while (xboxController.xboxNotif.btnXbox==1) {
      analogWrite(frontLeftMotorPin,0);
      analogWrite(frontRightMotorPin,0);
      analogWrite(backLeftMotorPin,0);
      analogWrite(backRightMotorPin,0);
      }

        if (LJoystickX >= -5 && LJoystickX <= 5) {
          LJoystickX = 0;         
        }
        if (LJoystickY >=-5 && LJoystickY <= 5) {
          LJoystickY = 0;
        }

        powerMag = pow((pow(LJoystickX,2)+pow(LJoystickY,2)),0.5);
        if (powerMag > 127.5) {
          powerMag = 127.5;
        }
        powerMag = powerMag * 2;

      if (LJoystickX >= 0 && LJoystickY >= 0) {
        Lpower = powerMag;
        Rpower = (LJoystickY - 63.75) * (powerMag / 63.75);
      } else if (LJoystickX <= 0 && LJoystickY >= 0) {
        Rpower = powerMag;
        Lpower = (LJoystickY - 63.75) * (powerMag / 63.75);        
      }  else if (LJoystickX <= 0 && LJoystickY < 0) {
         Lpower = powerMag;
        Rpower = (-LJoystickY - 63.75) * (powerMag / 63.75);
      } else if (LJoystickX > 0 && LJoystickY < 0) {
        Rpower = powerMag;
        Lpower = (-LJoystickY - 63.75) * (powerMag / 63.75);
      } 

      Lvelocity = Lpower * throttle;
      Rvelocity = Rpower * throttle;

      if (Lvelocity > 0) {
        Ldirection = 1;
      } else {
        Ldirection = 0;
      }

      if (Rvelocity > 0) {
        Rdirection = 1;
      } else {
        Rdirection = 0;
      }

      Lspeed = abs(Lvelocity);
      Rspeed = abs(Rvelocity);

      digitalWrite(dirLeftPin1,Ldirection);
      digitalWrite(dirLeftPin2,abs(Ldirection - 1));
      digitalWrite(dirRightPin1,Rdirection);
      digitalWrite(dirRightPin2,abs(Rdirection - 1));   

      analogWrite(frontLeftMotorPin,Lspeed);
      analogWrite(frontRightMotorPin,Rspeed);
      analogWrite(backLeftMotorPin,Lspeed);
      analogWrite(backRightMotorPin,Rspeed);

//      myServo.write(servoPos);
//      myStepper.step(stepsPerRevolution);       
    }
  } else {
      analogWrite(frontLeftMotorPin,0);
      analogWrite(frontRightMotorPin,0);
      analogWrite(backLeftMotorPin,0);
      analogWrite(backRightMotorPin,0);
    Serial.println("not connected");
    digitalWrite(connectionLEDPin,0);
    digitalWrite(notConnectedLEDPin,1);
    if (xboxController.getCountFailedConnection() > 2) {
      Serial.println("restarting");
      ESP.restart();
    }
  } 

}

Hi, @luke_jewison
I think this is your problem.


int backLeftMotorPin = 0;

int servoPos = 0;

Tom... :smiley: :+1: :coffee: :australia:

What's wrong with that? The motor pin is a pin, the servoPos is just telling it where to turn the servo it's not a pin.

Sorry my mistake.

Tom.. :smiley: :+1: :coffee: :australia:

Here's a sketch I just wrote that uses ESCs and the ESP32 servo library to vary the speed of the BLDC motors. Worked great (until my son capsized the RC boat and forked the lot; c'est la vie) and hopefully you find something to help you out in here:

/***********************************************************************
  ************** QUINT PROP WATER MOCCASIN with ROCKET BOOSTERS *********
  **********************************************************************

  Counter rotating 2 x 3 motor, flat bottomed airboat
  Since the thrust on this is more like a twin engine
  airplane than a single-fan airboat that uses central
  rudders to control direction, the general design is that
  of a counter-rotating twin engine plane.

  Many twin engine planes use engines that rotate in the same direction,
  as their sole purpose is to provide thrust and allow the other 
  control surfaces to give aerodynamic control over pitch, roll
  and yaw. 

  Since this airboat design uses no ailerons, flaps, elevators, or
  rudder and the motors can respond to virtually instant
  changes in rotational speed (as a boat only moves across 
  two dimensions and not three as an airplane), counter rotating
  propellors are necessary to turn. 

  Some history... 

  In order to maintain aerobatic capability in multi engine military
  airplanes in WWII in terms of agility 
  against single engine fighter planes and still maintain ability
  to fulfill other combat roles such as bomber, the counter rotating 
  props gained popularity, particularly by the Germans, as exemplified
  by the widely different mission design of the American Lockheed P-38 as 
  compared to the German Heinkel He 177 heavy bomber or the 
  Messerschmitt Me 323 Gigante six-engine transport plane, the largest 
  land-based transport aircraft to fly during the war 
  (V2 Prototype which became the standard for 
  D production series, and the ME 323D-1 on through the series). 

  Traditionally, Counter-rotating propellers generally turn clockwise 
  on the left engine and counterclockwise on the right. 
  The advantage of such designs is that counter-rotating propellers 
  balance the effects of torque and P-factor, meaning that such aircraft 
  do not have a critical engine in the case of engine failure.

  However, this was changed in WWII in the Lockheed P-38 Lightning. 
  In order to gain greater accuracy in gunnery, the XP-38 Prototype
  was designed such that the propellers would deviate from the typical
  orientation so that the P-38 blades would spin outward (away from the
  cockpit) at the top of their arc, rather than inward as in earlier
  twin engine counter rotating airplane designs.

  Therefore, from the pilot's perspective, the left engine (port)
  would rotate counterclockwise (CCW) and the right engine (starboard)
  would rotate clockwise (CW).

  This airboat design will adopt the prop orientation of the legendary
  Lockheed P-38 Lightning.
  Since the main motors face in the direction of the stern and the aux
  motors face in the direction of the bow, they will be opposite to one 
  another. 

  The aux motors and propellers are oriented in the same direction as a
  twin engine airplane so the aux motors will use the P-38 configuration
  and therefore the main motors will use the traditional counter-rotating
  configuration, since they are pushing the boat forward unlike an airplane
  that pulls forward through the air. 



----------------   MOTOR ORIENTATION:   -------------------
                        
                        bow
                      _______
                     _________
             port   |         |  starboard     
                   |           |
                  |             |
                 |               |
                 |               |
                 |               |  
                 |               |
                 |               |
aux motor       /                 \        aux motor
   CCW         /                   \          CW
              /                     \
             |_______________________|
             |_______________________|
        main motor                main motor
           CW                        CCW

                    main central
                       CCW

ALL REAR MOTORS HAVE PROPS ON UPSIDE DOWN TO MAKE PUSHER VARIETY
TWO FRONT PROPS ON NORMAL WAY FOR TRACTION ACTION

  >>>> IMPORTANT!!!!! USE ONLY DX8 MODEL NAME CobraV2  <<<<<<<<<<<<<<<< 

  Added three more motors
  Added Estes B6-0 Rocket boost control (untested in practice so far but triggers nicely in Serial)
  Added three-second "countdown" to fire rockets after switch toggled


 >CONTROLLER SETTINGS:
    FRAME RATE 22mS: (DSMX 22ms frame rate, frequency of 1/0.022 = 45.454 Hz.)
    MODE: ACRO; 
    TRAVEL: Throttle: 125% 150%; Elevator: 125% 100%; aileron 125% 125%; Rudder 125% 125%; else normal
    SUB TRIM: Throttle 125L; Aileron 125R; Elevator 125U; Rudder 125R; all else 0
    REVERSE: NONE
    D/R-EXPO: Aileron: Pos: Pos0; D/R: 100 100; Expo: 100 100; Sw: D/R
                            Pos1; D/R: 100 100; Expo: 0 0; Sw: D/R
                            Pos2; D/R: 100 100; Expo: 0 0; Sw: D/R

              Elevator: Pos: Pos0; D/R: 100 100; Expo: 100 100; Sw: Elev D/R 
                             Pos1; D/R: 100 100; Expo: 0 0; Sw: D/R
                             Pos2; D/R: 100 100; Expo: 0 0; Sw: D/R

              Rudder: : Pos: Pos0; D/R: 100 100; Expo: 100 100; Sw: Rudd D/R
                             Pos1; D/R: 100 100; Expo: 100 100; Sw: D/R
                             Pos2; D/R: 100 100; Expo: 100 100; Sw: D/R

    DIFFERENTIAL: Inhibit
    THROTTLE CUT: Pos: 0%; Sw: Gear0
    THR CURVE: Low: 0%; 25%: 25%; 50%: 50%; 75%: 75%; High: 100%; Expo: Inh; Switch: On
    FLAP SYSTEM: Inhibit
    MIX:  Ail>Rud: Right 0%, Left 0%, Sw Inh
          Mix 1: Thr > Ele; Rate 100% 100%; Offset 0; Trim Act; Sw On
          Mix 2: Ail > Rud; Rate -125% -125%; Offset 0; Trim Act; Sw: On
 >SYSTEM SETUP:
    WING TYPE: Wing Normal, Tail Normal
    SW SETUP: Trainer, F Mode, Gear, L Trim, R Trim, Mix: Inh
              Flap: Aux1, Aux2: Aux2, Knob: Aux3
    TRIM: All 5, Trim type: Common

   DJI Opto 30A Esc specs:
    Signal Frequency 30Hz ~ 450Hz
   
   Motors: Model 2212: 920KV 920rpm/V (13,616 RPM). Nut color that holds prop on 
           Silver nut (part 9450) - counter clockwise
           Black nut (part 9450cw)- clockwise
           Use 10" props on 3s, 8" props on 4s battery (parts 1045, 8045 respectively) 

  ----- Spektrum AR 6210 RX Connections ---------
   RX:  bind/data: free
        thro: sig, gnd to 21 (thrust forward) 
        aile: sig, gnd to 22
        elev: sig, gnd to 23 (turn left and right by varying prop speeds) 
        rudd: sig, gnd to 25
        gear: CC BEC power to Gear to power RX/ VCC in ESP Expansion Board @ 7.2V
        aux1: sig, gnd to 26. Switch pos2 is idle rockets, 0 is fire. 
        ABOVE noted connections all that's required, but using servo connectors on ESP expansion shield works too

  ------ Arduino connections ---------------------
        Pin 26 signal pin in from Aux1 on RC Rx (rocket signal in)
        Pins 21 and 22 left and right side signal pins in (throttle, aileron)
        Pins 16-19, 32, 33 (signal pins out) to respective ESCs.
        ESC +5V/Gnd on shared line to +5V/Gnd ESP32 expansion shield
        Pins 32 and 33 to RC switches to ignite rockets

  ------- RC (rocket) switches  ------------------------
        3.7-28V range, max continuous load current 8A. 
        Voltage out = voltage in when switch is on.
        -100% is off; +100% is on with these switches (servo signal travel).

        Normal mode
        The module can read a pulse width that can range from 400 to 2600us.
        If the width of the pulse is more than 1600us,
        the mosfet switch will close (rockets fire), if less than 1400us,
        the mosfet switch will open (idle).

        Safe-protection function
        This module has a safe-protection feature that reduces the likelihood 
        of unexpected activation.
        In below 2 conditions the Safe-protection mode will active:
        1.The pulse is more than 1600us at first power up, the mosfet switch open. 
        The LED will blink, you should move the input to the off position, 
        then normal more will active ;
        2.The signal is bad continuously for 500ms, the mosfet switch open. 
        The LED will blink. When the signal is good, the device will 
        deactivate safe-protection mode. We'll exploit this by simply 
        servo.detach(rocketSwitch) when rockets are not called for

        LED
        Normal mode: the LED will blink quickly when input pulse >1600us; 
        the LED will blink more slowly when input pulse <1400us;
        

 ------- Rockets -------------------------------
        Estes B6-0 * 2. 
        Maximum no fire current: 500mA
        Minimum all-fire current: 2A
        Starter resistance: 0.6904Ω

        2 * 3.7V 150mAh 25C (0.5Wh) Lipo batteries used in 
        beginner hobby-grade RC airplanes (EFlite for ex)

        I = V/R
        3.7V/0.6904Ω = 5.359A

        NOTE: This is not a parallel current circuit to fire the rockets because:
               each igniter is independently powered with its own 3.7V battery.
               So no need to divide the Amperage value by two in the Ohm's Law calculation.

        So 6lbs * 2 = 12lbs thrust. The -0 is a non typical style in
        the model rocket hobby, as it means a 0 timed delay in seconds between the 
        end of the thrust phase and the ignition of the ejection charge (the timed 
        delay is usually when the recovery gear is deployed in a model rocket).
        Thus, the B6-0 has no timed delay "and are used for booster stages and 
        special purposes only" according to Estes.

  by Hallowed31
  2024-08-16 to 2024-08-28
*/


#include <ESP32Servo.h>

// 5 pins IN from RC Rx: Throttle; Elevator; Aileron; Rudder; Aux1
// Recommended pins include 2,4,12-19,21-23,25-27,32-33
// first number listed in comments is where it was no Nano Every
static const int throttleSignalPin = 21;  // throttle channel to pin d7/gpio 21
static const int aileronSignalPin = 22;   // aileron channel to pin d9/gpio 22
static const int elevatorSignalPin = 23;  // elevator channel to pin A2/gpio 23
static const int rudderSignalPin = 25;    //rudder channel to gpio 25
static const int aux1SignalPin = 26;      // Aux1 channel to gpio 26
                                          //static const int aux1SignalPin = 6;           // Aux1 channel to pin d6
                                          //static const int rudderSignalPin = 17;         // rudder channel to pin A3(alias 17 on Uno)

// 6 pins OUT to ESCs and RC (rocket) switches (if Nano Every/ if ESP32)
Servo starboardRocketSignalOut;  // pin 5/15
Servo portRocketSignalOut;       // pin 6/14
Servo starboardSignalOut;        // pin 8/16 - drives all starboard side motors
Servo portSignalOut;             // pin 10/17 - drives all portside motors
Servo sternSignalOut;            // pin 11/19 - use elevator raw sig
Servo bowSignalOut;              // pin 12/18 - N/C

// Recommended pins include 2,4,12-19,21-23,25-27,32-33
static const int portRocketSignalOutPin = 32;
static const int starboardRocketSignalOutPin = 33;
static const int starboardSignalOutPin = 16;
static const int portSignalOutPin = 17;
static const int bowSignalOutPin = 18;
static const int sternSignalOutPin = 19;
// general timer interval
const long interval = 1000;
// rocket countdown timing variables
int timer = 3;  // 3 seconds to ignition after switch flipped - Adios, Joes!
unsigned long previousLaunchTimer;
// heartbeat LED
const int heartbeatLED = 2;
unsigned long heartbeatTime;
const unsigned long rocketOnInterval = 200;  // blink interval for rockets on
const unsigned long rocketOffInterval = 600;

ESP32PWM pwm;
uint32_t spektrumTimeout = 22000;

// to store values for raw radio signals
uint32_t bowThrottleVal, sternThrottleVal, steerStarboardTrim, steerPortsideTrim, turnPortVal, turnStarVal = 0;
// to store modified values to go out to the ESCs
uint32_t bowValOut, sternValOut, steerPortOut, steerStarboardOut = 0;
// to read in Aux1 (flaps) channel
uint32_t rocketVal, rocketValOut = 0;
uint32_t rocketValMin = 400;   // from RC switch datasheet
uint32_t rocketValMax = 2600;  // from RC switch datasheet
int shouldFire = 0;
int ledFire = 0;

void setup() {  // Allow allocation of all timers
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);
  ESP32PWM::allocateTimer(3);
  Serial.begin(115200);
  starboardSignalOut.setPeriodHertz(50);
  portSignalOut.setPeriodHertz(50);
  sternSignalOut.setPeriodHertz(50);
  bowSignalOut.setPeriodHertz(50);
  pinMode(throttleSignalPin, INPUT);
  pinMode(elevatorSignalPin, INPUT);
  pinMode(rudderSignalPin, INPUT);
  pinMode(aileronSignalPin, INPUT);
  pinMode(aux1SignalPin, INPUT);
  pinMode(heartbeatLED, OUTPUT);
  attachMotors();  // just the propulsion ESCs
  portSignalOut.writeMicroseconds(900);
  starboardSignalOut.writeMicroseconds(900);
  sternSignalOut.writeMicroseconds(900);
  bowSignalOut.writeMicroseconds(900);
  Serial.println("\nwaterMoccasinFiveMotor\n");
  previousLaunchTimer = 0;
}

void loop() {
  readPWMValues();
  updateMotorValues();
  setMotors();
  // printRealTimeMotorData();
  // printRealTimeRocketData();
  switch (ledFire) {
    case 0:
      if (millis() - heartbeatTime >= rocketOffInterval) {
        heartbeatTime = millis();
        digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
      }
      break;
    case 1:
      if (millis() - heartbeatTime >= rocketOnInterval) {
        heartbeatTime = millis();
        digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
      }
      break;
    default:
      break;
  }
}


void readPWMValues() {
  bowThrottleVal = pulseIn(elevatorSignalPin, HIGH, spektrumTimeout);    // motors toward the bow
  sternThrottleVal = pulseIn(throttleSignalPin, HIGH, spektrumTimeout);  // the one mid stern motors, signal attached to throttle cut
  steerStarboardTrim = pulseIn(rudderSignalPin, HIGH, spektrumTimeout);  // not wired to anything, these are trim values as a feature of the transmitter settings
  steerPortsideTrim = pulseIn(aileronSignalPin, HIGH, spektrumTimeout);  // not wired to anything, these are trim values as a feature of the transmitter settings
  rocketVal = pulseIn(aux1SignalPin, HIGH, spektrumTimeout);
}

void printPWMValues() {
  Serial.print("bowThrottleVal: ");
  Serial.print(bowThrottleVal);
  // stern motors
  Serial.print("\tsternThrottleVal: ");
  Serial.print(sternThrottleVal);
  // steering offsets
  Serial.print("\tsteerStarboardTrim: ");
  Serial.print(steerStarboardTrim);
  Serial.print("\tsteerPortsideTrim: ");
  Serial.println(steerPortsideTrim);
}

void updateMotorValues() {
  /* 
Use Throttle signal in for two main motors up to its max
Use Elevator signal for other two aux motors up to THR max
Then use difference between Elev max and Thr max to drive top speed all motors

Ail and Rud should init about 1200 or so. (1283)
pushing right stick LEFT increases Ail val up to about 1800 while decreasing Rud val to stall
pushing right stick RIGHT increases Rud val up to about 1800 while decreasing Ail val to stall
bowValOut, sternValOut, steerPortOut, steerStarboardOut = 0;
Servo starboardSignalOut;        // pin 8/16 - drives all starboard side motors
Servo portSignalOut;             // pin 10/17 - drives all portside motors
Servo sternSignalOut;            // pin 11/19 - use throttle raw sig, just one rear mid motor
Servo bowSignalOut;              // pin 12/18 - N/C
*/

  // handle the motors
  sternValOut = sternThrottleVal;  // just stern large prop mid motor
                                   // port and star pairs, untrimmed to give max range
  if (steerStarboardTrim > 1300 && steerPortsideTrim < 1260) {
    steerStarboardOut = steerStarboardTrim * 0.90;
    steerPortOut = steerPortsideTrim * 0.90;
  } else if (steerPortsideTrim > 1300 && steerStarboardTrim < 1260) {
    steerStarboardOut = steerStarboardTrim * 0.90;
    steerPortOut = steerPortsideTrim * 0.90;
  }

  else {
    steerStarboardOut = sternValOut;
    steerPortOut = sternValOut;
    bowValOut = sternThrottleVal;
  }

  // handle the rockets
  switch (rocketVal) {
    case 900 ... 1699:
      shouldFire = 0;
      ledFire = 0;
      break;
    case 1700 ... 2000:
      shouldFire = 1;
      ledFire = 1;
      break;
    default:
      shouldFire = 0;
      ledFire = 0;
      break;
  }
  switch (shouldFire) {
    case 0:
      coolRockets();
      break;
    case 1:
      fireRockets();
      break;
    default:
      coolRockets();
      break;
  }
}

void setMotors() {
  bowSignalOut.writeMicroseconds(bowValOut);
  sternSignalOut.writeMicroseconds(sternValOut);
  starboardSignalOut.writeMicroseconds(steerStarboardOut);
  portSignalOut.writeMicroseconds(steerPortOut);
}
void coolRockets() {
  rocketValOut = rocketValMin;
  starboardRocketSignalOut.writeMicroseconds(rocketValOut);
  portRocketSignalOut.writeMicroseconds(rocketValOut);
}
void fireRockets() {
  rocketValOut = rocketValMax;
  starboardRocketSignalOut.writeMicroseconds(rocketValOut);
  portRocketSignalOut.writeMicroseconds(rocketValOut);
}
void printRealTimeMotorData() {
  // bow motors
  Serial.print("bowValOut: ");
  Serial.print(bowValOut);
  // stern motors
  Serial.print("\tsternValOut: ");
  Serial.print(sternValOut);
  // steering offsets
  Serial.print("\tsteerStarboardOut: ");
  Serial.print(steerStarboardOut);
  Serial.print("\tsteerPortOut: ");
  Serial.println(steerPortOut);
}
void printRealTimeRocketData() {
  if (shouldFire == 0) {
    Serial.print(F("\n\trocketVal: "));
    Serial.print(rocketVal);
    Serial.print(F("\trocketValOut: "));
    Serial.print(rocketValOut);
    Serial.println(F("\t\tRockets Cool\n"));
  } else if (shouldFire == 1) {
    Serial.print(F("\n\trocketVal: "));
    Serial.print(rocketVal);
    Serial.print(F("\trocketValOut: "));
    Serial.print(rocketValOut);
    Serial.println(F("\t\tRockets Ignite!\n"));
  }
}

void attachMotors() {
  starboardSignalOut.attach(starboardSignalOutPin);
  bowSignalOut.attach(sternSignalOutPin);
  portSignalOut.attach(portSignalOutPin);
  sternSignalOut.attach(bowSignalOutPin);
  starboardRocketSignalOut.attach(starboardRocketSignalOutPin);
  portRocketSignalOut.attach(portRocketSignalOutPin);
}

#include <ESP32Servo.h>
//#include <Stepper.h>

//int stepsPerRevolution = 2048;
int servoPin = 21;
int servoPos = 0;
//int motSpeed = 16;
int ledPin = 32;
Servo myServo;
//Stepper myStepper(stepsPerRevolution,14,26,27,25); //in 1, 3, 2, 4

void setup() {
  // put your setup code here, to run once:
  myServo.attach(servoPin);
  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
  //myStepper.setSpeed(motSpeed);
}

void loop() {
  // put your main code here, to run repeatedly:
  
 // analogWrite(ledPin,130);

  servoPos++;
  myServo.write(servoPos);
  Serial.println(servoPos);
  delay(100);
 // myStepper.step(stepsPerRevolution);

}
here's some simpler code but still has the same issues as the other code. Only things connected are an led and a servo, but if the analog write command is uncommented it doesn't work.

after testing, It only breaks if it runs the analogwrite, but if it doesn't run it it's fine. The second the code hits an analogwrite it breaks.

I noticed there aren't any analogwrites in this code, is it possible to control a dc motor without it?