New to Arduino and have been learning about stepper motors and how they are controlled using AccelStepper. What I would like is for a stepper motor to run until it hits a limit switch, stop and then back off it a bit, but no matter what I do, it doesn't want to change direction after it hits the limit switch. Anyone see what I'm doing wrong? Appreciate any help and advice.
I'm using an Arduino UNO with a CNC shield.
at time of pasting code it now no longer does anything after i have pressed the limit switch,
#include <AccelStepper.h>
#include <Servo.h>
#define limitSwitch4 A3
AccelStepper stepper4(1, 12, 13);
void setup() {
pinMode(limitSwitch4, INPUT_PULLUP);
stepper4.setMaxSpeed(4000);
stepper4.setAcceleration(1000);
stepper4.setCurrentPosition(0);
homing();
}
void homing () {
// Homing Z
while (digitalRead(limitSwitch4) != 1) {
stepper4.setSpeed(1000);
stepper4.runSpeed();
stepper4.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
}
delay (100);
while (stepper4.currentPosition() != 0) {
stepper4.moveTo(800); //absolute movment
stepper4.run();
}
}
void loop() {
}
this should be outside the while loop if you want this to happen only when the button has been touched
I noticed you have setSpeed(1000) which usually means rotate clockwise and then once you've hit the switch you as moveTo(800) which would still be clockwise ➜ you want to go the other way if you want to move away from the limitswicth
Interestingly, if I remove the code that I thought was giving a command to move to a amount of steps (negative or positive) from 0 it still moves three whole rotations (stepper motor) after it pauses on the limit switch, showing clearly I don't understand programming! Code looks like this with line deleted.
#include <AccelStepper.h>
#include <Servo.h>
#define limitSwitch4 A3
AccelStepper stepper4(1, 12, 13);
void setup() {
pinMode(limitSwitch4, INPUT_PULLUP);
stepper4.setMaxSpeed(4000);
stepper4.setAcceleration(1000);
stepper4.setCurrentPosition(0);
homing();
}
void homing () {
// Homing Z
stepper4.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
while (digitalRead(limitSwitch4) != 1) {
stepper4.setSpeed(1000);
stepper4.runSpeed();
}
delay (100);
while (stepper4.currentPosition() != 0) {
stepper4.run();
}
}
void loop() {
}
to avoid the bouncing issue you could use a library. I would suggest Toggle
try something like this
(you press and release the limit switch yourself)
click to see the code
#include <AccelStepper.h>
#include <Servo.h>
#include <Toggle.h>
const byte limitSwitchPin = A3;
Toggle limitSwitch;
AccelStepper stepper(AccelStepper::DRIVER, 12, 13);
void homing () {
Serial.println("Homing - press the button to simulate limitswitch hit");
stepper.setSpeed(200);
while (true) { // run CW at constant speed until we hit the button
stepper.runSpeed();
limitSwitch.poll();
if (limitSwitch.onPress()) break;
}
Serial.println("Limit switch touched. backing up until release");
stepper.setSpeed(-100);
while (limitSwitch.isPressed()) { // run CCW at constant speed until we leave the button
stepper.runSpeed();
limitSwitch.poll();
}
Serial.println("Limit switch free. Setting position to 0");
stepper.setCurrentPosition(0);
}
void setup() {
Serial.begin(115200);
limitSwitch.begin(limitSwitchPin);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(200);
homing();
}
void loop() {}
does this say that the motor should be going forward then backwards between set limits, mine just always speeds up anti clockwise the slows down, then speeds up again (anticlockwise) I beginning to think something is broken.
Love the website! so in simulation it works, motor goes anticlockwise when switch is pressed and held down. Mine though, just stops when limit switch is pressed and held down.. I stuck a - value in the below to try and get the motor to run clockwise, but no.
Serial.println("Homing - press the button to simulate limitswitch hit");
stepper.setSpeed(-2000);
while (true) { // run CW at constant speed until we hit the button
#include <AccelStepper.h>
#include <Servo.h>
#include <Toggle.h>
const byte limitSwitchPin = A3;
Toggle limitSwitch;
AccelStepper stepper(AccelStepper::DRIVER, 12, 13);
void homing () {
Serial.println("Homing - press the button to simulate limitswitch hit");
stepper.setSpeed(-2000);
while (true) { // run CW at constant speed until we hit the button
stepper.runSpeed();
limitSwitch.poll();
if (limitSwitch.onPress()) break;
}
Serial.println("Limit switch touched. backing up until release");
stepper.setSpeed(2000);
while (limitSwitch.isPressed()) { // run CCW at constant speed until we leave the button
stepper.runSpeed();
limitSwitch.poll();
}
Serial.println("Limit switch free. Setting position to 0");
stepper.setCurrentPosition(0);
}
void setup() {
Serial.begin(115200);
limitSwitch.begin(limitSwitchPin);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(200);
homing();
}
void loop() {}
the AccelStepper library is not happy with speed above 1000, so don't use -2000 and +2000.
also, with inertia you might either hit hard the limit switch or run over it. Be gentle to your gig !
Sorry its been a week, I've been teaching all week. The above didn't work either, the motor moves then stops when it hits the switch and then just sits on it! Any other ideas will be welcome!
Okay, here's what I have worked out this morning, it's not you, it me! I tried the program on a different port and used different pins for the switch, Pin 9 for switch and 4, 7, [Z] for motor instead of [A] servo on the CNC Shield of Pin A3 for switch and 12, 13 for motor.
So I must be misunderstanding the pin configuration for [A] servo on the CNC Shield).
I had jumpered the ones using a red line (see image) which should be correct for Z-axis motor and switch 4 to work but doesn't.
You might need to read this a few times as the diagram says Z-axis but its connected to [A] on the CNC shield....
Yes and now I know that it works! I figured it out. I had the switch in the wrong pin.... I feel I ow you a beer, putting you through all that. You helped me break it down and figure out the root cause, thank you!