Lag encounter when interfacing multiple servos

Hi! Still trying to build an Arduino Uno arm. Came across a different issue now. A Servo - that controls the base axis of the arm - is doing well when it's controlling just the arm and another servo, that isn't connected to the Arduino. The problem arises when I try to connect it, so it can act as another joint.
(Note: Both servos are controlled using a joystick.)

The Axis-Arm servo starts to lag, move inconsistently and sometimes even stops for a while. For some reason, the second servo moves flawlessly. Just to clear up any questions - no, it's not because of the weight, the Axis-Arm servo moves just right when the second is not connected, I even tried to attach some extra weight to the arm, and it's doing fine without concern.


Reference picture:


Code:

#include <AccelStepper.h>
#include <Servo.h>

#define HALFSTEP 8
#define STEPPER_DEADBAND 75
#define STEPPER_MAX_ROTATION 1536
#define SERVO_MIN_PULSE_WIDTH 544
#define SERVO_MAX_PULSE_WIDTH 2400
#define SERVO_AXIS_MAX_ANGLE 30

#define POTENTIOMETER_PIN A0
#define SERVO_AXIS_PIN 3
#define SERVO_ARM_PIN 5
#define JOYSTICK_AXIS_X_PIN A4
#define JOYSTICK_AXIS_Y_PIN A5

int potentiometerValue = 0;
int previousPotentiometerValue = 0;
int stepperMoveToPosition = 0;

const int servoAxisBoundaries = (SERVO_MAX_PULSE_WIDTH + SERVO_MIN_PULSE_WIDTH) / (180 / SERVO_AXIS_MAX_ANGLE);
int servoAxisPosition = 1500;
int servoArmPosition = 1500;

int joystickXValue = 0;
int joystickYValue = 0;

AccelStepper stepper(HALFSTEP, 8, 10, 9, 11);
Servo servoAxis;
Servo servoArm;

void setup() {
  Serial.begin(9600);
  
  pinMode(POTENTIOMETER_PIN, INPUT);
  pinMode(JOYSTICK_AXIS_X_PIN, INPUT);
  pinMode(JOYSTICK_AXIS_Y_PIN, INPUT);

  stepper.setMaxSpeed(1000.0);
  stepper.setAcceleration(100.0);
  stepper.setSpeed(500);

  servoAxis.attach(SERVO_AXIS_PIN, SERVO_MIN_PULSE_WIDTH, SERVO_MAX_PULSE_WIDTH);
  servoArm.attach(SERVO_ARM_PIN, SERVO_MIN_PULSE_WIDTH, SERVO_MAX_PULSE_WIDTH);
  servoAxis.writeMicroseconds(servoAxisPosition);
  servoArm.writeMicroseconds(servoArmPosition);
}

void loop() {
  potentiometerValue = constrain(analogRead(POTENTIOMETER_PIN), 100, 900);
  joystickXValue = constrain(analogRead(JOYSTICK_AXIS_X_PIN), 100, 900);
  joystickYValue = constrain(analogRead(JOYSTICK_AXIS_Y_PIN), 100, 900);


  if (abs(previousPotentiometerValue - potentiometerValue) > STEPPER_DEADBAND) {
      previousPotentiometerValue = potentiometerValue;
      stepperMoveToPosition = map(potentiometerValue, 100, 900, -STEPPER_MAX_ROTATION , STEPPER_MAX_ROTATION);
      stepper.moveTo(stepperMoveToPosition);
  }

  if (joystickYValue < 525 && servoAxisPosition > SERVO_MIN_PULSE_WIDTH + servoAxisBoundaries) {
    servoAxisPosition -= (abs(500 - joystickYValue)) / 125;
  }
  if (joystickYValue > 475 && servoAxisPosition < SERVO_MAX_PULSE_WIDTH - servoAxisBoundaries) {
    servoAxisPosition += (abs(500 - joystickYValue)) / 125;
  }
  if (joystickXValue < 525) {
    servoArmPosition -= (abs(500 - joystickXValue)) / 125;
  }
  if (joystickXValue > 475) {
    servoArmPosition += (abs(500 - joystickXValue)) / 125;
  }
  
  servoAxis.writeMicroseconds(servoAxisPosition);
  servoArm.writeMicroseconds(servoArmPosition);
  stepper.run();
}

I've already tried implementing timers, but I doesn't do anything, because the idea is to try and move every motor, every time the loop function repeats. I'm concerned that Arduino just can't keep up with updating the position of the motors. Does anyone know if creating a separate C++ file and rewriting the "servo-stepper" part with constructors would do anything here? Any other solutions? I would be grateful.

P.S. I can post the wiring and more pictures if necessary.

Servo.h updates all the servo outputs every 50 ms. The value for each servo is updated at that rate, there is no lag or other timing irregularity. Look elsewhere.
For example, you update both servo positions, then immediately call stepper.run(). Is it possible that that function blocks interrupts, preventing servo.h from updating when it should? I don't know, so I'm asking.

How are you powering the servos?

I've ran a test, completely without the stepper part, still the same results.

5V, 0.5A, USB-B Cable. I know it's not a lot, but it shouldn't have a problem with 2 servos and a stepper right?

You need a better power supply for the stepper and servos, 0.5A is not going to be enough with a servo under load.

Thank you, I will try that. Also, do you have any idea how to reduce noise from the joystick? Sometimes it interferes with the potentiometer output and the stepper starts moving by itself.

What @david_2018 said is correct.

Also, it may be intentional or not, but your two if clauses for the arm have a range overlap, whereas those for the axis have a center deadband. So one will be unresponsive with the stick centered, while the other will do ?
Correction. Both overlap:

  if (joystickYValue < 525 && servoAxisPosition > SERVO_MIN_PULSE_WIDTH + servoAxisBoundaries)     servoAxisPosition -= (abs(500 - joystickYValue)) / 125;
  if (joystickYValue > 475 && servoAxisPosition < SERVO_MAX_PULSE_WIDTH - servoAxisBoundaries)     servoAxisPosition += (abs(500 - joystickYValue)) / 125;
  if (joystickXValue < 525)   servoArmPosition -= (abs(500 - joystickXValue)) / 125;
  if (joystickXValue > 475) servoArmPosition += (abs(500 - joystickXValue)) / 125;

they only act within a narrow range around 500. Is that intentional?

@dheb another edit. Apologies. More coffee reveals:
both act in overlapping ranges. So between 525 and 475, both adjustments are made.

I would get the power supply fixed first, you are likely getting a lot of variation in the analog input because of voltage drop caused by drawing too much current.

As noted in post #8, two conflicting adjustments are being made. If the joystick hovers around either threshold boundary, you'll get 'creep'. Better you have a true deadband, and adjust it's boundaries to suit the 'center' of your joystick, which in some cheap models can be well off of the ADC center of 511. Which, by the way, is not where your deadband is centered, it's centered at 500, so you're well off to the side.

Yes, the narrow range is intentional
(the plastic is 5mm thick, so it's kinda heavy for a servo. It didn't want to come back to straight angle after being completely bent to one of the sides, so I had to implement a range), but the range overlap wasn't. At some point during the project it was > 525 and < 475.
I must have changed it by accident

Using what I could read in the serial monitor - leaving the joystick untouched left a value of nearly perfect 500, so I used that, it isn't really off.

Was bored..
Here's a simulator..

Your project simulated..

think I hooked it up right..
don't see no lag either..
servos tend to be current hungry..

good luck.. ~q

Thank you very much!