Arduino Servo rotate randomly back after a while (NEMA17)

Hello everyone,
I couldn't find any solution to my problem when searching the forum, so I hope its fine if I post it here. :slight_smile:

I am working on a project where I wanna use an Arduino Uno in combination with a CNC shield and 4 NEMA17 stepper motors (currently I am using only 2 of them).

In our little company, we wanna automate a paper feed in for a lasercutter. That means, we do have setup a homemade construction from aluminium and want to use two servos to shift some sort of an "infinite paper roll" into the lasercutter. It works like this: The lasercutter cuts its job into the paper. Afterwards the stepper should move the paper by a certain amount >into< the lasercutter fo the next lasercutting job and so on.

We do have a processing GUI with buttons that allow me to trigger the Arduino to rotate the steppers by a certain amount (example below "-700"). I attach you a shortened code version here for clarity.

#include <AccelStepper.h>
#include <MultiStepper.h>

// Define the stepper motor and the pins that is connected to
AccelStepper stepper1(1, 2, 5); // (Typeof driver: with 2 pins, STEP, DIR)
AccelStepper stepper2(1, 3, 6);
AccelStepper stepper3(1, 4, 7);

MultiStepper steppersControl;  // Create instance of MultiStepper

long gotoposition[3]; // An array to store the target positions for each stepper motor

void setup() {

  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

  stepper1.setMaxSpeed(800); // Set maximum speed value for the stepper
  stepper2.setMaxSpeed(800);
  stepper3.setMaxSpeed(800);

  // Adding the 4 steppers to the steppersControl instance for multi stepper control
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);
  steppersControl.addStepper(stepper3);

}

void loop() {


int CurPosLCServosFront = 0; // Initialise PositionServo variable of both Servos (mirrored)
int rotateNextCard = -700; // single movement of Arduino after button click


int counter = 1; // counts number of movements of servos
while (counter<100) {
      [...]
        moveServos(CurPosLCServosFront+rotateNextCard); 
        CurPosLCServosFront = CurPosLCServosFront+rotateNextCard;
        delay(1500);
     [...]
}

void moveServos(int positionServosLCFront) {
           // Store the target positions in the "gotopostion" array
          Serial.println("Start rotating Servos...");
          
          gotoposition[1] = positionServosLCFront; // Servos in Feed-In

          steppersControl.moveTo(gotoposition); // Calculates the required speed for all motors
          steppersControl.runSpeedToPosition(); // Blocks until all steppers are in position

          Serial.println("Finished!");
}

So when starting up the Arduino, the servos has a position "0" and after each click it rotates (always in the same direction!) by "-700" (a few round trips of the servo). Afterwards the current position variable of the stepper gets updated and on the next movement another "-700" are added.

Therefore the steppers move always in one direction and aquire over time a pretty big value for its position. What happens is that after about 10-20 movements the stepper rotates a lot back in the other direction throwing the paper out of the lasercutter. To me it looks like the servo would get the command from the Arduino to go to a positive position (for which it needs to rotate all the way back). But from my code I simply cant understand where is the problem.

So I wanted to ask if someone could help me out, had a similar problem already or maybe knows a solution i could try?

Thank you very much and cheers from Austria :slight_smile:

PS: I should maybe add. After that problem happened, I restart the Arduino and everything works fine from the beginning until that problem appears again).

I think your current software trategy could be improved, but the first thing that catches my eye is he use of ints to hold your position values

using long ints ior unsigned long ints will possibly delay the occurrence of the problem, but beyond that, you’ll need to review your control strategy.

Steppers are not specifically servo motors, but depending on your feedback & control could be part of a servo subsystem.

Thanks for the quick reply :slight_smile:

I have to admit, that I am by far no expert with steppers/servos :sweat_smile:

Do I understand you correctly, that you think the problem is simply that the position-variable get too big over time?
The idea of using unsigned long ints is great! I will give that a try and see how much it improves :slight_smile:

NEMA outlines apply to stepper motors. You seem to use steppers, not servos?

Thanks for clarifying. I wasnt even aware of the difference between servos and steppers :sweat_smile: so I updated the post above.

The solution of using unsigned longs works perfectly! I simply wasnt aware that a normal int variable is actually pretty small ^^ Now with an unsigned long I have more than enough room to let the steppers run for a whole day :slight_smile:

Thanks a lot for the quick help to everyone!

Btw: If there are any further suggestion on how to improve our code, I would be glad to learn about it :slight_smile:

You can reset the stepper position to zero after each cut. Doing so will definitely prevent long term overflows.