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:
- As long as button is pressed, the motor spins clockwise
- As long as button is pressed, the motor spins counterclockwise
- 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
}