Moving stepper motor to its origin with a button

Hello!

I have a stepper motor with a rotary encoder and a i2d LCD display which shows the angle(degree) it turns, and I would like to turn the motor back to its starting position once an external button is pressed.

For now, I am referring to the code from brainy-bits.com (https://www.brainy-bits.com/nema-motor-with-rotary-encoder-part-2/).

The code seldom works but mostly tends to keep rotating forever once the button is pressed rather than stopping at a certain position.

The code I am using now is as below.

/ #include <LiquidCrystal.h> // includes the LiquidCrystal Library
//LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//i2c pins
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //

// defines pins numbers
#define stepPin 8
#define dirPin 9

const int PinCLK=  10;
const int PinDT= 11;
const int PinSW = 12;
const int PinButton = 6;

int direction;

int StepsToTake=4;
int counter=0;
int angle=0;
int aState;
int aLastState;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  delay(50);
  
  pinMode (PinCLK, INPUT);
  pinMode (PinDT, INPUT);
  pinMode (PinButton,INPUT_PULLUP);
  pinMode (PinSW, INPUT);
  digitalWrite (PinSW, HIGH);
 
  Serial.begin(9600);
  aLastState = digitalRead(PinCLK);
  lcd.begin(16, 2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display }
}


void loop() {

if (digitalRead(PinButton) == LOW)  {
  if (angle == 0) {  // check if button was already pressed
               delay(100);
  } else {
      if (angle > 0) {  // Stepper was moved CW
        while (angle !=0 ){  //  Do until Motor position is back to ZERO
          digitalWrite(dirPin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
          for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(stepPin, HIGH);
              delay(1);
              digitalWrite(stepPin, LOW);
              delay(1);            
            }
            angle = angle - StepsToTake;
        }
      }
      else {
        delay(100);
        while (angle != 0){ 
          digitalWrite(dirPin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
              for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(stepPin, HIGH);
              delay(1);
              digitalWrite(stepPin, LOW);
              delay(10);            
            }
           angle = angle + StepsToTake;
        }
      }
      angle = 0; // Reset position to ZERO after moving motor back
    }
  }
  

aState = digitalRead(PinCLK);
 
  if (aState != aLastState) {
    if (digitalRead(PinDT) != aState) {
      counter ++;
      angle ++;
      rotateCW();
    }
    else {
      counter--;
      angle --;
      rotateCCW();
    }
    if (counter >= 10 ) {
      counter = 0;
    }

    lcd.clear();
    lcd.print("Position: ");
    lcd.print(int(angle * (0.9)));
    lcd.print("deg");
    lcd.setCursor(0, 0);

  }
  aLastState = aState;
  Serial.println(angle, DEC);
}

void rotateCW() {
  digitalWrite(dirPin, LOW);
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(2000);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(2000);
}
void rotateCCW() {
  digitalWrite(dirPin, HIGH);
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(2000);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(2000);
}

Could you guys please let me know if there is any mistake in my code that makes the motor keeps rotating?

Waiting for your reply. Thank you in advance!

What is the purpose of this

  if (angle == 0) {  // check if button was already pressed
               delay(100);
  }

How can the value of the angle variable identify whether a button was pressed?

Why should there be a short delay() if the angle is 0 ?

...R

it's not clear to me what this chunk of code is doing. i think it's looking at the encoder pins which can be used to track position. but instead of just inc/decrementing angle, rotateCW() and rotateCCW() are also called which rotate the motor. you could try commenting out those calls

  aState = digitalRead(PinCLK);
 
  if (aState != aLastState) {
    if (digitalRead(PinDT) != aState) {
      counter ++;
      angle ++;
      rotateCW();
    }
    else {
      counter--;
      angle --;
      rotateCCW();
    }