Using the following code causes the steppers to accelerate before cruising at max speed when the button is first pressed; however all subsequent presses it will rapidly vibrate or not spin at all, I think it starts running at max speed instead of accelerating again.
Driver is EasyDriver HW-135, Stepper is NEMA17
The circuitry works, it is only after the second press that the steppers stop working.
I have tried swapping out setCurrentPosition() with moveTo(), or putting run() in the if statement and stop() in the else, all have the exact same result described above.
On first button press -> accelerate steppers to max speed, the continue running for essentially infinite time
Second press -> Stop steppers
Then it just repeats
I added a 10kΩ resistor in between the ground pin, but it still doesn't work. The issue has changed to now it just doesn't spin at all, only the first time spinning for a little bit before stopping, which is worse than before.
That's not what your sketch does.
To get the stepper moving with acceleration/deceleration you must use .move() or .moveto(). .setCurrentPosition() is completely wrong for this purpose.
To stop the stepper with deceleration use the .stop() method.
And you must not call these functions with every loop cycle, but only once when you press the button. Only .run() must be called in every loop cycle.
The next point: If you are using an AVR (UNO/Nano..) then speed=2000 is too much for 3 steppers with AccelStepper.
I will try this, although like I said I tried moveTo (I did it as a one time thing as you stated) and the issue persisted, but maybe with the resistor it will be different. What I tried today was the following code:
#include <AccelStepper.h>
#include <MultiStepper.h>
#define stp 3
#define stp2 4
#define stp3 5
#define dir 6
#define dir2 7
#define dir3 8
AccelStepper stepper1(AccelStepper::DRIVER, stp, dir);
AccelStepper stepper2(AccelStepper::DRIVER, stp2, dir2);
AccelStepper stepper3(AccelStepper::DRIVER, stp3, dir3);
int button = 9;
int buttonVal, lastButtonVal, counter;
int speed = 2000;
int accel = 300;
bool firstPress = true;
void setup() {
// put your setup code here, to run once:
stepper1.setMaxSpeed(speed);
stepper2.setMaxSpeed(speed);
stepper3.setMaxSpeed(speed);
stepper1.setAcceleration(accel);
stepper2.setAcceleration(accel);
stepper3.setAcceleration(accel);
pinMode(button, INPUT_PULLUP);
Serial.begin(9600);
stepper1.moveTo(1e9);
stepper2.moveTo(1e9);
stepper3.moveTo(1e9);
}
void loop() {
// put your main code here, to run repeatedly:
buttonVal = digitalRead(button);
if (buttonVal && lastButtonVal != buttonVal){
counter++;
}
lastButtonVal = buttonVal;
if (counter % 2 == 1) {
stepper1.run();
stepper2.run();
stepper3.run();
} else {
stepper1.stop();
stepper2.stop();
stepper3.stop();
}
}
.run() must be called allways! ,run() 'knows' whether pulses have to be created or not. Without callung run(), the steppers does not receive any steppulses and so there will be no deceleration - it stops immediately.
Trial and error is not a good strategy when programming - you should learn how Accelstepper works if you want to use it.
If you still want to use Accelstepper you can try this:
The wrong way of doing it. The pin will be "floating" during switchover, which could be problematic.
Connect the button only to pin and ground.
And use internal pull up on the pin with pinMode, like this
pinMode(button, INPUT_PULLUP); // enable internal pull up on the pin
Note that the pin will now idle HIGH, and is LOW when the button is pushed.
if (buttonVal && ...
becomes now inverted if (!buttonVal && ...
Leo..