Hi guys a complete beginner here trying to get my hands dirty in the world of Arduino, i am trying to use a limit switch to change the direction of rotation of the Nema23 Stepper motor. What I want to achieve is say that the stepper motor is rotating in clockwise direction at a low rpm, say If the limit switch is pressed it should complete one entire circle in the anti-clockwise direction/opposite direction and should break out of the clockwise/(earlier direction of) rotation.
#include <Servo.h> //Servo library
// Pin Definitions
#define LIMIT_SWITCH_PIN 7
#define dirPin 2 // Direction
#define stepPin 3 // Step Pulse
#define enaPin 4 // Enable Motor
// Variables
int stepDelay = 1250; // Delay between steps in microseconds
int stepsToMove = 800;
void setup() {
Serial.begin(9600);
pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
// // Set pin modes
pinMode(enaPin, OUTPUT);
digitalWrite(enaPin, LOW); // Enable motor
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
}
void switchHit() {
digitalWrite(dirPin, HIGH);
for (int i = 0; i < stepsToMove; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(20);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepDelay - 20);
}
}
void loop() {
digitalWrite(dirPin, LOW);
for (int i = 0; i < stepsToMove; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(20);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepDelay - 20);
if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
switchHit();
break;
}
}
delay(3000);
Here is the code that I am using.
The problem I am facing is that, say the stepper motor is in the process of rotating in a specific direction and I press the limit switch it changes direction but doesn't complete one full rotation in the opposite direction for some reason, it misses some steps, and ideas how can this be fixed?
This delay makes your engine rotate n turns and stops for 3 seconds.
But this delay also impacts the button reading.
I suggest using millis() instead of delay().
HI man , no actually i am trying to make a string art machine , not a school project , I want to caliberate my machine and my idea is that I plan to use a limit switch at nail position 0 so that everytime that position is hit , I know that I am at nail 0 , this questions is a pretty common one , I totally agree , but all the solutions I could find online on ask how to change the direction , I was actually unable to solve the problem of steps being missed once the direction is changed , that's why I asked this question.
See if I understand your project correctly:
The engine rotates in cycles with 3-second stops.
When you feel the limit, it should rotate in the opposite direction for a few cycles and stop completely.
This is it?
yes kinda right, what i want to achieve is that , say the motor is completing a turn in a specific direction and in the middle of the turn say I hit the limit switch then it should complete one turn (360*) entirely in the opposite direction and then move out of the loop of the initial turn .
but dont you think that the limit switch is being hit in the for loop part and that has no impact what so ever on how whether the motor is completing one entire revolution in the opposite direction once the limit switch is hit since the delay of 3secs in induced only when I break out of the for loop.
Trying to find ready "solutions" often (always?) give You unknown code. Go a step lower, understanding what is done and why.
Often the name "Home switch" is used and it's a calibrating switch used a start up.
Hi man , thanks for replying first of all , coming to what I could make out from what u meant , if this is what u were suggesting , then even with the the stepper misses some steps in the opposite direction when the limit switch is hit.
digitalWrite(dirPin, LOW); // Set direction to clockwise
for (int i = 0; i < stepsToMove; i++) {
if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
Serial.println("Activated!");
switchHit();
break;
}
digitalWrite(stepPin, HIGH);
delayMicroseconds(20);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepDelay - 20);
}
Part 1. You turn on your project and the step motor rotates 800 steps;
Part 2. Wait 3000 mS;
Part3. Tests whether the limit has been pressed;
Part4. If not, go to part 1;
Part5. If pressed, it rotates 800 steps in reverse;
Part6. Stop and stay still forever.
Stepper starts to rotate 800 steps at a low rpm in a particular direaction
If the limit switch is hit while the stepper is rotating and hasn't yet finished its turn completely (that's 360*) , it should start rotating in the opposite direction for one complete circle and break out of the earlier rotation loop.
If the limit switch wasn't hit then it should complete its rotation in which ever direction it started rotating.
Finally it should wait for 3 secs before the entire process starts again.
Using break or return is like GoTo programming for me.
I would go by
for (int i = 0; i < stepsToMove; i++) {
if (digitalRead(LIMIT_SWITCH_PIN) =! LOW) {// No limit switch, make the step
digitalWrite(stepPin, HIGH);
delayMicroseconds(20);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepDelay - 20);
}
}