Ive been struggling all week on this trying to learn.
Im using MEGA 2560 and TB6600 with NEMA 17 stepper.
I would like do this operation:
Press button "home", stepper will move to home limit switch and set position to zero.
Press button "CW", stepper will move clockwise until I release button.
Press button "CCW", stepper will move counter clockwise until I release button.
Stepper should only be permitted to move within ZERO and 10,000.
Id like to remove the joystick control as its not needed.
Id like to use the accelstepper library to control speed and acceleration.
The homing function works good.
Any help on this would be appreciated. Or at least a small example to point me in right direction. Ive tried so many tutorials and they are all diff or something is missing from them. Thank you!
#include <AccelStepper.h>
#include <MultiStepper.h>
// Define the Pins used
#define step_pin 2 // Pin 2 connected to Step pin
#define dir_pin 3 // Pin 3 connected to Direction pin
#define x_pin A0 // Pin A0 connected to joystick x axis pin
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch)
#define cw_button 7 // Pin 7 connected to clockwise button
#define ccw_button 8 // Pin 8 connected to counter clockwise button
#define home_button 10 // Pin 10 connected to home button (press to send the stepper home)
int direction; // Variable to set Rotation (CW-CCW) of the motor
int steps; // Used to set HOME position after Homing is completed
void setup() {
pinMode(dir_pin, OUTPUT);
pinMode(step_pin, OUTPUT);
pinMode(x_pin, INPUT);
pinMode(home_switch, INPUT_PULLUP);
pinMode(cw_button, INPUT_PULLUP);
pinMode(ccw_button, INPUT_PULLUP);
pinMode(home_button, INPUT_PULLUP);
// Start Homing procedure of Stepper Motor at startup
while (digitalRead(home_switch)) { // Do this until the switch is activated
digitalWrite(dir_pin, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(step_pin, HIGH);
delay(5); // Delay to slow down speed of Stepper
digitalWrite(step_pin, LOW);
delay(5);
}
while (!digitalRead(home_switch)) { // Do this until the switch is not activated
digitalWrite(dir_pin, LOW);
digitalWrite(step_pin, HIGH);
delay(10); // More delay to slow even more while moving away from switch
digitalWrite(step_pin, LOW);
delay(10);
}
steps=0; // Reset position variable to zero
}
void loop() {
// Enable movement of Stepper Motor using the Joystick
while (analogRead(x_pin) >= 0 && analogRead(x_pin) <= 100) {
if (steps > 0) { // To make sure the Stepper doesn't go beyond the Home Position
digitalWrite(dir_pin, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(step_pin, HIGH);
delay(1);
digitalWrite(step_pin, LOW);
delay(1);
steps--; // Decrease the number of steps taken
}
}
while (analogRead(x_pin) > 900 && analogRead(x_pin) <= 1024) {
if (steps < 10000) { // Maximum steps the stepper can move away from the Home Position
digitalWrite(dir_pin, LOW);
digitalWrite(step_pin, HIGH);
delay(1);
digitalWrite(step_pin, LOW);
delay(1);
steps++; // Increase the number of steps taken
}
}
}
The code you posted does not make any use of the AccelStepper library and you don't want most of the functionality (joystick) - so it is completely useless for you.
How will you specify the speed? Or is it a constant value?
Mobatools also has acclerleration, and its Stepper_03.ino example uses a driver and state machine to bounce back and forth. It might not be too difficult to extend and adapt to your needs:
Does it have to be AccelStepper?
Here is a sketch with my MobaTools lib, derived from an other example and adapted to your needs ( you have to change pin numbers according to your HW );
It's fairly simple and I think it doesn't need a FSM at all.
Presumably I will use it as an additional example
/* Example for the control of a bipolar stepper with 3 buttons and a potentiometer (for speed)
Homing is initiated at start and when the Zero button is pressed
The stepper moves CW if the CW button is pressed and stopped if it is released
The stepper moves CCW if the CCW button is pressed and stopped if it is released
Moving of the stepper is limited between zero and POS_MAX
*/
#define MAX8BUTTONS // saves RAM because only 4 switches are used
#include <MobaTools.h>
const int STEPS_PER_REV = 800;
const int POS_MAX = 10000;
//create stepper object ( 800 steps / rev - 1/4 microstep )
MoToStepper myStepper( STEPS_PER_REV, STEPDIR );
const byte dirPin = 5; // adjust to your needs
const byte stepPin = 6;
const byte enaPin = 7;
// buttons must switch to Gnd
enum { buttonZero, buttonCW, buttonCCW } ; // create names for the buttons
const byte buttonPins[] = {A2, A3, A4 }; // assign pins to the buttons
const byte buttonCnt = sizeof(buttonPins);
MoToButtons myButton( buttonPins, buttonCnt, 20, 500 );
// limit switch at refpoint
const byte refPin = A5; // limit pin
const byte atRefpoint = LOW; // dependig wether it is a NO or NC switch
MoToTimebase speedIntervall; // time interval to read speed pot
const byte potPin = A0; // pin for speed pot
int vspeed = 0; // speed in rev/min*10
int oldSpeed = 0; // to recognize speed changes
void toRefPoint(); // Homing function defined after loop()
void setup()
{ Serial.begin(115200); while (!Serial);
myStepper.attach( stepPin, dirPin );
myStepper.attachEnable( enaPin, 10, LOW ); // Enable active
myStepper.setSpeed( 200 );
vspeed = 200;
myStepper.setRampLen( 100 ); // Ramp 100 steps at 20rev/min
speedIntervall.setBasetime( 100 ); // read pot every 100ms
pinMode(LED_BUILTIN, OUTPUT);
pinMode(refPin, INPUT_PULLUP );
toRefPoint();
Serial.println("Starting loop");
}
void loop() {
myButton.processButtons(); // reading and processing the buttons ( e.g. debouncing and state change detection)
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
// read speed pot
if ( speedIntervall.tick() ) {
// called every 100ms ( Tickertime = 100ms in setup() )
vspeed = map((analogRead(potPin)), 0, 1023, 20, 1800); //map to 2 ... 180 rev/min
if ( abs( oldSpeed - vspeed ) > 5 ) { // suppress jitter at analogRead
myStepper.setSpeed( vspeed );
oldSpeed = vspeed;
}
}
// check buttons and react accordingly
if ( myButton.pressed(buttonZero) ) {
Serial.println(" Find ref point");
toRefPoint();
}
if ( myButton.pressed(buttonCW) ) {
Serial.println("Move towards maximum position");
myStepper.moveTo( POS_MAX );
}
if ( myButton.pressed(buttonCCW) ) {
Serial.println("Move towards 0 position");
myStepper.moveTo(0);
}
if ( myButton.released(buttonCW) || myButton.released(buttonCCW) ) {
Serial.println("Stop the stepper");
myStepper.rotate(0);
}
}
void toRefPoint() {
// Homing: move stepper to ref point and set zeropoint
Serial.println("homing");
if ( digitalRead( refPin ) != atRefpoint ) {
// quick move to ref point it it's not already there
Serial.println("Quick move to limit switch");
myStepper.setSpeedSteps( 10000, 100 );
myStepper.rotate(-1);
while ( digitalRead( refPin ) != atRefpoint );
}
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
Serial.println("ref point reached, stop the stepper");
myStepper.rotate(0);
while ( myStepper.moving() ); // wait till stop
Serial.println("move slowly back to the switching point of the limit switch");
myStepper.setSpeedSteps( 500 );
myStepper.setRampLen(0);
myStepper.rotate( 1 );
while ( digitalRead( refPin ) == atRefpoint );
Serial.println("Switch point reached - set zero");
myStepper.setZero();
myStepper.moveTo(0);
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
Serial.println("homing finished");
myStepper.setSpeed( 200 );
myStepper.setRampLen( 100 ); // Ramp 100 steps bei 20rev/min
oldSpeed = 0; //
}
Each step is commented by a print to the serial monitor. So I hope it is understandable what is happening, but of course you can ask.
Interesting! It does not have to be accelstepper. I’ve read about your mobatools
Library and noticed it will only control up to 6 steppers. I will ultimately need to control 9 - 12 steppers. Not at the same time though. They will all go to a preset position using the EEPROM memory. I will have 3 total memory presets. This will be way later of course as I have a lot to learn first haha.
Oops. I had mistakenly thought the Stepper_03 example used a FSM, but it is the Stepper_02 that uses one:
Thanks. The Stepper_02 example's bounce-and-pause code is a nice demonstration of a state machine and provides a straightforward path for modifying and extending it to other practical applications. (As compared to that other library's Bounce example.)
Here's a Wokwi simulation of the MobaTools Stepper_02 Finite State Machine: