Using accelstepper with button control and home

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
      }
    }
}

Show your code ... or use the search function of the forum.

Oops sorry, I added it to my post.

Sounds much like:

I'd code it with a Finite State Machine as in

... but add a HOMING state:

image Graphviz online

So you pasted code you found somewhere. What do you want now?

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?

I like the acceleration ramp up and down feature of the accelstepper library. But if it’s too difficult, a preset speed value would be fine also.

Have you looked at the accelstepper library examples?

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:

image https://wokwi.com/projects/386819655605368833

1 Like

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 :wink: :sunglasses:


/* 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.

1 Like

I have read seen the accelstepper library examples and am still studying them.

I will look into this! Thank you for the example.

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.

I will look into this example you have sent.

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:

Thank you for this! I am looking more into this now.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.