Stepper Motor Directional Shift Causes Stalling

Hello - I have an issue whilst running two stepper motors in tandem. Motor 1 runs in one direction continuously, while Motor 2 moves back and forth in short bursts. When I'm running Motor 1 alone, it can run up to 1000rpm without any problems.

When I run the two motors in tandem (using AccelStepper library, .run() commands in a loop with nothing else), Motor 1 will stall and lose place whilst Motor 2 is doing its back and forth strafing.

I'm just wondering if there's possibly a large draw of current when Motor 2 is stopping and switching directions at high acceleration rates. The speed of Motor 2 isn't high at all, but I'm just taking a guess here.


Hardware:

  • ESP32 - split into two independent cores (1 core is focused solely on motor control, and the run() commands are alone in a loop. When a certain distance for Motor 2 is hit, it will stop and switch to another loop to send it back the other way.).

  • DM556 drivers (2) - using 800 steps per revolution (located here).

  • S-400-48 PSU - 48v/8.3A, 3-channels (each driver has its own channel, and a PCB breakout board for the MCU gets the third).

  • NEMA 23 motors (2) - bipolar, 4-wire, 1.8°, 2.8A, 2.5mH (located here).


I'm going to do some tests tomorrow to see if I can narrow things down (lowering microstepping interval, changing amperage etc).

The motors have no load on them whatsoever, and are physically not touching each other (sitting on the floor a few feet away from each other).

The motors themselves are rated for 2.8A but I have the drivers on 2.7A - is it safe to increase the driver amperage to 3.2A?

That depends on the driver and the step mode. The problem is overheating. Don't let the motor casing exceed 80 C during long term operation, unless the manufacturer states otherwise.

Motor current draw should not strongly (or perhaps even noticeably) be affected by changes in direction. Steppers do not behave like brushed DC motors.

OK I'll give that a try tomorrow. There's a couple other things on my list to try too, so I'll have to report back.

This actually isn't a new problem for me, I had the same thing going on with a pair of TB6600 drivers and a 32v 9A PSU. I thought it might be resonance issues between the two motors, so I separated them and made sure there was no vibrational transfer or anything that might interfere - no change. Then I switched to a higher voltage PSU and higher end drivers after people suggested the TB6600s weren't to be trusted.

Anyway...I just noticed that I don't have any .stop() commands in my motor code, it just switches directions:

    case OSCILLATE:

            while ((stepper1.distanceToGo() != 0) && (cancel_run == false)) {
              stepper2.moveTo(Move_2_B);
              while (stepper2.distanceToGo() != 0) {
                  stepper1.run();
                  stepper2.run();
                  };
              stepper2.moveTo(Move_2_A);
              while (stepper2.distanceToGo() != 0) {
                  stepper1.run();
                  stepper2.run();
                  };
                  vTaskDelay(1);
                  };
              if (cancel_run == true) {Motor_State = CANCELLED;}
              if (stepper1.distanceToGo() == 0) {Motor_State = SELECTOR_A;}
              vTaskDelay(1);
    break;

Move_2A and Move_2B are the same distance, just positive and negative to send the direction of stepper2 back and forth.

Is it possible that I've been very stupid by neglecting to stick some stop() commands in before the directional shift?

e: never mind, that wasn't it. The stalling definitely occurs when the motor switches directions though. Perhaps it's the fact that Motor 1 has a very quick break in the run() command when the loop switches and it just loses its place..

Hey I did it!

It was the loop switch after all. I suppose the inertia at higher RPM was just causing Motor 1 to overrun and lose its place for that couple microseconds of time between run() commands while the loop was switching.

The solution was to just keep the run() commands in constant loop with each other in core 1 of the ESP32, then use core 0 to monitor the position of Motor 2 and send the directional changes.

Just sticking this solution here for anyone else.