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!