Multiple buttons driving a stepper motor

I am very new to microcontrollers and programming. I am trying to control a stepper motor using 3 buttons. I am using a tb6600 stepper motor driver, arduino uno r3 and a bipolar NEMA 17 stepper motor with specs: 1 amp and 200 steps/revolution.

What I need the buttons to do:

  1. As long as button is pressed, the motor spins clockwise
  2. As long as button is pressed, the motor spins counterclockwise
  3. When button is pressed, make the motor spin clockwise 400 steps over 3 seconds then stops.

For 1 and 2, the motor speed can be controlled by a rotary encoder. The 3rd button should be unaffected by the encoder.

I have been successful setting up buttons 1 and 2 with accelstepper. However, I have no idea how to make the third button.

I have attached an image to show what wiring I have. Find the code below. Any suggestions would be appreciated.

#include <AccelStepper.h>       //AccelStepper library
AccelStepper stepper(1, 9, 8);  // pulses Digital 9 (CLK); Direction Digital 8 (CCW)




//Defining pins
const int RotaryCLK = 2;      //CLK pin on the rotary encoder
const int RotaryDT = 3;       //DT pin on the rotary encoder
const int ButtonCW = 4;       //Button for clockwise rotation
const int ButtonCCW = 5;      //Button for counterclockwise rotation
const int ButtonInject = 10;  // Button for single movement

//Defining variables
int RotateCounter = 0;  //initial position
int MotorSpeed = 50;    //some default value for steps/s

//Statuses
int CLKNow;
int CLKPrevious;

int DTNow;
int DTPrevious;

// Time
float TimeNow1;
float TimeNow2;

void setup() {

  Serial.begin(9600);



  pinMode(4, INPUT);  //CW button
  pinMode(5, INPUT);  //CCW button

  //Store states
  CLKPrevious = digitalRead(RotaryCLK);
  DTPrevious = digitalRead(RotaryDT);

  attachInterrupt(digitalPinToInterrupt(RotaryCLK), rotate, CHANGE);

  stepper.setMaxSpeed(1000);      //SPEED = Steps / second
  stepper.setAcceleration(5000);  //ACCELERATION = Steps /(second)^2
}


void loop() {
  //The motor only runs when one of the buttons are kept pressed

  CheckButtons();  //Checking the status of the buttons

  RunTheMotor();  //Running the motor
}








void RunTheMotor()  //function for the motor
{
  stepper.enableOutputs();        //enable pins
  stepper.moveTo(RotateCounter);  //tell the stepper to move to the 'RotateCounter'steps (absolute) position

  while (stepper.distanceToGo() != 0) {
    stepper.setSpeed(MotorSpeed);
    stepper.runSpeedToPosition();

    //Serial.print("DistanceToGo: "); //for debugging
    //Serial.println(stepper.distanceToGo());
  }
  //Serial.println(MotorSpeed); //for debugging
}

void CheckButtons() {
  //Serial.println(digitalRead(ButtonCW)); //Just for debugging
  if (digitalRead(ButtonCW) == HIGH)  //if the button is pressed
  {
    RotateCounter++;  //increase the value of the variable, this represents the absolute position of the stepper

    // Serial.print("ButtonCW: "); //for debugging
    // Serial.println(stepper.distanceToGo());

    //you can add delay here which is also a type of debouncing. It is useful when you want to click the button
    //once and increase the steps (value of RotateCounter) only by one.
    //delay(100); //Simplest thing to be able to use this function to add just 1 step at a time to use delay
  }
  //Serial.println(digitalRead(ButtonCCW)); //Just for debugging
  if (digitalRead(ButtonCCW) == HIGH) {
    RotateCounter--;  //decrease the value of the variable, this represents the absolute position of the stepper

    //Serial.print("ButtonCCW: "); //for debugging
    // Serial.println(stepper.distanceToGo());
    //delay(100);
  }
}

void rotate() {
  CLKNow = digitalRead(RotaryCLK);  //Read the state of the CLK pin

  // If last and current state of CLK are different, then a pulse occurred
  if (CLKNow != CLKPrevious && CLKNow == 1) {
    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so increase
    if (digitalRead(RotaryDT) != CLKNow) {
      MotorSpeed++;
    } else {
      // Encoder is rotating CW so decrease
      MotorSpeed--;
    }
    stepper.setSpeed(MotorSpeed);  //as this functions is not started from the loop() it is maybe good to update the speed here
  }
  CLKPrevious = CLKNow;  // Store last CLK state
}

That's not needed. Use the speed set functions in AccelStepper.

Use the speed set function. 400/3 steps per second and then a "goto function" sending out 400 steps.

Thanks for the reply. How could I implement this type of function?

I'm a beginner regarding the AccelStepper library and still wish I find an understandable description of how the functions work.

I use a "goto" function that doesn't return until finished. It looks like: `myStepper.runToNewPosition(anglePos);//Blocking until done

.
.

myStepper.setMaxSpeed(4000);

myStepper.setAcceleration(30000);
`

Some AccelStepper functions need to be clocked, kicked, some don't, like above.
There are helpers knowing AccelStepper well. Let's hope one steps in.

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