Stepper Motor Unstable at Longer Running Times

Hey! I took a look around and cant seem to find anything that has worked to solve this problem.

Backstory: I am making a 'jukebox' of sorts for my nintendo collection (see video here), which, based off of a number input will spin 1 of 4 respective motors to the game chosen.

Surprisingly, I got all of the coding for this figured out and it works as it should. My problem is that if the game I choose is more than 8-10 or so from the current position the motor reaches some sort of odd frequency and begins to not move consistently. Without accel and decel this causes some loss of step count and an accumulation of error. With accel and decel, it still does it but the steps seem to still be accurate.

I have messed with step intervals and adjusted the motor current up and down from the driver with almost no change (except that it would either stop working when too low, or get hot when too high).

Thoughts to troubleshoot this? Is it a torque issue? An RPM issue? Operating approximately 2 rpm at max speed.

Equip: Zyltech Nema 17 84 oz-in Stepper, with polulu A4988 driver, 12V input to driver
Running in 1/16th step mode

Without seeing your code ... ?

And post a link to the datasheet for the stepper motor.

I recently had a problem with a stepper motor because another part of my code had the effect of causing some very short steps that resulted in missed steps.

...R

Cant seem to find a legitimate datasheet for these but the basic specs are:

Shaft diameter: 5mm
Shaft length: 20mm
Motor body length: 48mm
Full length: 70mm
Weight: 380g
Step Angle: 1.8°
Step Accuracy: 5%
Holding Torque: 0.59N·m (84oz·in)
Rated Current/phase: 1.7 A
Phase Resistance: 1.8 ohms
Rated Voltage (≠driving voltage): 3.06 V
Inductance: 3.8 mH ±20%
Weight: 380 g

Will have to post the code tonight

1.7 amps is a bit on the high side for an A4988. If it overheats and cuts out to protect itself that could be a cause of missed steps.

Have you tried it with the current set to 1.4 amps? Does that provide enough motor torque?

If not a DRV8825 driver would be better or one of the drivers with a TB66xx chip as they can go up to about 3 amps.

...R

Could very well be the drive not pushing enough current, I will play with that again to double check if I cant get the current low enough to still function. Here is my code (without accel/decel), which is the code that was running in the video.

Basically it just pulls a number of steps from an array based on what number is entered on the keypad, the code is just set up for one motor at the moment until I can figure out the 'pulsing' issue

#include <Keypad.h>
#include <LiquidCrystal.h>

// defines pins numbers
const int stepPin = 3; 
const int dirPin = 4; 
const int microStep1 = 22;
const int microStep2 = 23;
const int microStep3 = 24;


//array of steps for each game from gameStep[0] to gameStep[37]
const int gameStep[37] = {0, 86, 173, 259, 346, 432, 519, 605, 692, 778, 865, 951, 1038, 1124, 1211,
                      1297, 1384, 1470, 1557, 1643, 1730, 1816, 1903, 1989, 2076, 2162, 2249, 2335,
                      2422, 2508, 2595, 2681, 2768, 2854, 2941, 3027, 3114};
    

LiquidCrystal lcd(5, 6, 7, 8, 9, 10);

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {45, 43, 41, 39}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {37, 35, 33, 31}; //connect to the column pinouts of the keypad

int firstnumber=99;
int secondnumber=99;
int thirdnumber=99;
int keyfullnumber=0;
int motorValue1 = 1;
int motorValue2 = 38;
int motorValue3= 75;
int motorValue4 = 112;

Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  digitalWrite(microStep1,HIGH); //sixteenth step for all high
  digitalWrite(microStep2,HIGH);
  digitalWrite(microStep3,HIGH);
  Serial.begin(9600);

}

void loop() {
  int GetNumber();
{
   int num = 0;
   char key = keypad.getKey();
         switch (key)
      {
      case NO_KEY:
      break;

      case '1':
      checknumber(1);
      break;
        
      case '2':
        checknumber(2);
      break;

      case '3':
        checknumber(3);
      break;

      case '4':
        checknumber(4);
      break;

      case '5':
        checknumber(5);
      break;

      case '6':
        checknumber(6);
      break;

      case '7':
        checknumber(7);
      break;

      case '8':
        checknumber(8);
      break;

      case '9':
        checknumber(9);
      break;

      case '0':
        checknumber(0);
      break;

      case '*':
        deletenumber();
      break;

      case '#':
        calculatesteps();
      break;
            
      }
   
}
}

void checknumber(int x){
  if (firstnumber == 99){
    lcd.clear();
    firstnumber=x;
    String displayvalue= String(firstnumber);
    lcd.print("Enter Game #");
    lcd.print(displayvalue);
    //return(displayvalue);
  }
  else {
    if (secondnumber == 99) {
      lcd.clear();
      secondnumber=x;
      String displayvalue= (String(firstnumber)+String(secondnumber));
      lcd.print("Enter Game #");
      lcd.print(displayvalue);
      //return(displayvalue);
    }
    else {
      lcd.clear();
      thirdnumber=x;
      String displayvalue=(String(firstnumber)+String(secondnumber)+String(thirdnumber));
      lcd.print("Enter Game #");
      lcd.print(displayvalue);
      //return(displayvalue);
    }
  }
}

void deletenumber() {
  if (thirdnumber !=99) {
    lcd.clear();
    String displayvalue= (String(firstnumber)+String(secondnumber));
    lcd.print("Enter Game #");
    lcd.print(displayvalue);

    thirdnumber=99;
  }
  else {
    if (secondnumber !=99) {
      lcd.clear();
      String displayvalue=String(firstnumber);
      lcd.print("Enter Game #");
      lcd.print(displayvalue);

      secondnumber=99;
    }
    else {
      if (firstnumber !=99) {
        lcd.clear();
        String displayvalue ="";
        lcd.print("Enter Game #");
        lcd.print(displayvalue);

        firstnumber=99;
      }
    }
  }
}

void calculatesteps() {
  lcd.clear();
  lcd.print("Going to #");
  
      if (thirdnumber == 99 && secondnumber == 99 && firstnumber != 99) {
      keyfullnumber=firstnumber;
      lcd.print(keyfullnumber);
      calculatedGame(keyfullnumber);
    }
    
    if (secondnumber != 99 && thirdnumber == 99) {
      keyfullnumber=(firstnumber*10)+secondnumber;
      lcd.print(keyfullnumber);
      calculatedGame(keyfullnumber);
    }
    
    if (thirdnumber != 99) {
      keyfullnumber=(firstnumber*100)+(secondnumber*10)+thirdnumber;
      lcd.print(keyfullnumber);
      calculatedGame(keyfullnumber);
    }
  firstnumber=99;
  secondnumber=99;
  thirdnumber=99;
    //resetnumbers();// Reset numbers to get ready for new entry
  } 

void calculatedGame(int z) {
  if (z > 0 && z < 38) {
    int calculatedMove = gameStep[keyfullnumber - 1] - gameStep[motorValue1 - 1];
    moveMotor1(calculatedMove);
    motorValue1 = keyfullnumber;
    }
}

void moveMotor1(int calculatedMove) {
  if (calculatedMove > 0) {
  digitalWrite (dirPin, LOW); //clockwise
    for (int i=0; i<calculatedMove; i++) {
    digitalWrite (stepPin, HIGH);
    delayMicroseconds(30);
    delay(12);
    digitalWrite (stepPin, LOW);
    delayMicroseconds(30);
    delay(12);
    }
  }
  else if (calculatedMove < 0) {
  digitalWrite (dirPin, HIGH); //counterclockwise
  calculatedMove = abs(calculatedMove);
    for (int i=0; i<calculatedMove; i++) {
    digitalWrite (stepPin, LOW);
    delayMicroseconds(30);
    delay(12);
    digitalWrite (stepPin, HIGH);
    delayMicroseconds(30);
    delay(12);
    }
  }
}

But also using just this code I get the same effect. The steps appear to be tracking correctly, but it pulses the whole way around. If I cut the current it ends up getting 'stuck' at some point before a full rev and bounces back and forth.

#include <AccelStepper.h>

#define STEP_PIN 3
#define DIR_PIN 4

AccelStepper stepper(1, STEP_PIN, DIR_PIN);

const int microStep1 = 22;
const int microStep2 = 23;
const int microStep3 = 24;

void setup()
{
  digitalWrite(microStep1,HIGH); //sixteenth step for all high
  digitalWrite(microStep2,HIGH);
  digitalWrite(microStep3,HIGH);
  stepper.setMaxSpeed(40);
  stepper.setAcceleration(5);
  stepper.moveTo(3200);

}

void loop()
{
    stepper.run();
}

amt346:
The steps appear to be tracking correctly, but it pulses the whole way around.

I don't understand.

And I can't see any video in the link in your Original Post. Can you put it on YouTube? And preferably a video from the latest version of the program.

...R

Robin2:
I don't understand.

And I can't see any video in the link in your Original Post. Can you put it on YouTube? And preferably a video from the latest version of the program.

...R

Without the video, I would imagine that it doesn't make as much sense...not sure whats up with the link, I can click on it and it brings me right to the video, odd.
Try this

I messed with the delays (shortened) and it seemed to help some, but it still gets off before a full revolution can be made. I am thinking it may be the driver current as you mentioned up front, I may order one and try it. Fortunately they appear to have the same pinouts.

I can't say that I see any unacceptable behaviour in the video.

When you say "it pulses the whole way around" are you referring to the fact that there appear to be brief pauses between movements rather than smooth motion?

To my mind that is probably due to inadequate torque, excessive friction in the mechanism and/or some flexibility between the motor shaft and the turntable.

Does the system guarantee that the correct cartridge is selected?

...R

amt346:
Without the video, I would imagine that it doesn't make as much sense...not sure whats up with the link, I can click on it and it brings me right to the video, odd.
Try this

I messed with the delays (shortened) and it seemed to help some, but it still gets off before a full revolution can be made. I am thinking it may be the driver current as you mentioned up front, I may order one and try it. Fortunately they appear to have the same pinouts.

If it was accurate regardless of the pulsing I wouldnt be too worried about it. But in short intervals from 1 to 6 or 7 games it doesn't do it and its spot on. Anything over that it starts to fluctuate at that frequency and produces some error. I do know it has the holding torque to stop it from full speed (125-150 steps/s) without the motor slipping. Would the driver overheating cause a problem like this? Always easy enough to drop 25-30 bucks to up the driver current and motor torque to test it.

I mean the idea is that the game selection is guaranteed, lol. The alternative to this method would be something along the lines of a disk optical encoder or something? I do have a small CNC that I could potentially make my own disk to match the specs of my turntable (37 equally spaced slots).

Well, I see some part of the table dragging on something. Nothing to do with the driving mechanism.

Paul

amt346:
Would the driver overheating cause a problem like this?

You need to provide more information about the mechanical system - drawings and photos of the critical parts.

...R

Paul_KD7HB:
Well, I see some part of the table dragging on something. Nothing to do with the driving mechanism.

Paul

Its not dragging on anything, lol. What are you seeing?

Robin2:
You need to provide more information about the mechanical system - drawings and photos of the critical parts.

...R

There's not much to this, its attached to a 300lb capacity 4" diameter lazy susan bearing. Total weight with all of the games is around 12 lb. I have a coupler attached to the motor shaft on one end and pressure fitted into 1/2" plywood (the base of the turntable). I don't have any slippage or see any eccentricity between the center of the disk and shaft. In short, the system is a lazy susan bearing, basic rigid coupler, and the motor.

I dont have any qualms with the bearing, here is a video of just the bearing in use with nothing else attached

I was seeing a pulsing slowing-speed up of about a 1 second period. Then it went away.

Is the load spread equally all around the table, or is some section weighted more than other parts?

Paul

Is the code in Reply #4 the program that is driving the table in the video in Reply #7?

If so I suspect the problem is a mechanical one.

You are using microstepping which is never as precise as full steps and the loaded turntable will have a lot of rotational inertia which will make it difficult for the motor to get the table moving. That may get lost in the "flexibility" of microsteps, including some missed microsteps. I suspect what you perceive as pulses occurs when the motor reaches a full-step position.

If this was my problem I would start my experiments with full steps and either a very very slow stepper speed or gentle acceleration to a higher speed.

...R