Stepper motor missing steps/ inaccurate

Hey all,

I'm making a school project where i wanna use a stepper motor to move a carriage. I'm using a keypad to provide input and an lcd board to show the ouput. I'm using an Accelstepper library and a microstepper controller.

the problem is, its very inaccurate when it comes to steps, i.e. i need it to be very accurate , to .mm to be precise, and its missing steps. I know the code is very wonky, but is there a way to solve this?

Below is the code:

#include <AccelStepperWithDistance.h>
#include <Keypad.h>
//#include <AccelStepper.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
AccelStepper stepperX(1, 12, 11);   // 1 = Easy Driver interface
//const uint8_t KEYPAD_ADDRESS = 0x27;
//I2CKeyPad Keypad(KEYPAD_ADDRESS);

const byte home_switch =  13;
// Stepper Travel Variables
long TravelX;  // Used to store the X value preovided by the user
bool moveComplete = true;
bool halt=false;

//keypad setup
const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 4; //four columns

char keys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

//byte pin_rows[ROW_NUM]      = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
//byte pin_column[COLUMN_NUM] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
//alternate
byte pin_rows[ROW_NUM]      = {6,7,8,9}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {3,2,4,5}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

String keypadInput;

void lcdEnterValue() {
  lcd.clear();
  lcd.print(F("set value:"));
  lcd.setCursor(0, 1);
  lcd.print("now at ");
  lcd.print(stepperX.currentPosition());
   lcd.setCursor(10, 0);
  Serial.println(F("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): "));
}


bool readKeypad(long& newDestination) {
  long userInput = 0;
  char key = keypad.getKey();
  if (key) {
    if (key >= '0' && key <= '9') {     // only act on numeric keys ==> HOW DO YOU ENTER NEGATIVE VALUES?
      keypadInput += key;               // append new character to input string
      lcd.print(key);

    } else if (key == '#') {
      if (keypadInput.length() > 0) {
        stepperX.enableOutputs();
        userInput = keypadInput.toInt();
        keypadInput = "";               // clear input
        halt=false;
        }
    

        if (userInput < 0 || userInput > 69500) {  // Make sure the position entered is not beyond the HOME or MAX position
          Serial.println(F("\nPlease enter a value greater than zero and smaller or equal to 69500.....\n"));
          lcd.clear();
          lcd.print(F("invalid value."));
          delay(2000);
          lcdEnterValue();
          return false;
        } else {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print(F("Moving to:"));
          lcd.print(userInput);
          Serial.print(F("Moving stepper into position: "));
          Serial.println(userInput);
          delay(1000);  // Wait 1 seconds before moving the Stepper
          newDestination = userInput;
          return true;
        }
    }
  else if (key == '*') {
      keypadInput = "";                 // clear input
      lcdEnterValue();
        }
  else if (key == 'A'){
      stepperX.disableOutputs();
      lcd.print("Halted");
      halt=true;
  }
      
    
  }
  return false;
}

void homing() {
  //  Set Max Speed and Acceleration of each Steppers at startup for homing
  stepperX.setMaxSpeed(800.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(800.0);  // Set Acceleration of Stepper

  // Start Homing procedure of Stepper Motor at startup
  lcd.setCursor(0, 0);
  lcd.print(F("HOMING"));
  Serial.print("Stepper is Homing");

  long initial_homing = -1; // Used to Home Stepper at startup

  while (digitalRead(home_switch) == HIGH) {
    stepperX.moveTo(initial_homing);  // Set the position to move to
    initial_homing--;  // Decrease by 1 for next move if needed
    stepperX.run();  // Start moving the stepper
    delay(1);
  }

  stepperX.setCurrentPosition(0);   // Set the current position as zero for now
  stepperX.setMaxSpeed(100.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(100.0);  // Set Acceleration of Stepper
  initial_homing = 1;
  delay(15);                        // anti-bounce

  while (digitalRead(home_switch) == LOW) {
    stepperX.moveTo(initial_homing);
    initial_homing++;
    stepperX.run();
    delay(1);
  }

  stepperX.setCurrentPosition(0);

  lcd.clear();
  lcd.print(F("HOMING DONE!"));
  delay(2500);
  Serial.println(F("Homing OK\n"));

}

void setup() {
  pinMode(home_switch, INPUT_PULLUP);
  Serial.begin(115200);     // don't go slow.

  keypadInput.reserve(10);  // avoid dynamic allocation
  keypadInput == "";        // empty the String

  lcd.init();               // initialize the lcd
  lcd.clear();
  lcd.backlight();

  homing();

  stepperX.setMaxSpeed(1000.0);      // Set Max Speed of Stepper (Faster for regular movements)
  stepperX.setAcceleration(500.0);  // Set Acceleration of Stepper

  // Print out Instructions on the Serial Monitor at Start
  lcdEnterValue();
}

void loop() {

  if (readKeypad(TravelX)) {
    stepperX.moveTo(TravelX);  // Set new moveto position of Stepper
    moveComplete = false;
  }

  // Check if the Stepper has reached desired position
  if ((stepperX.distanceToGo() != 0) && halt== false) {
    stepperX.run(); //stepperX.runSpeed() DID NOT WORK
  } else {
    if (!moveComplete) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("COMPLETED!");
      delay(2500);
      Serial.println("COMPLETED!");
      lcdEnterValue();
      moveComplete = true;
     
    }
  }
}

You need to post links to the data sheets of the driver and the stepper.
Schematics as well.

Did you set maximum acceleration and speed as appropriate?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.