i have one project in that i have to control three stepper motor at same time sometime in that one motor is just running in one direction and i can change it's speed with button and other two should run when i press forward or reverse button
my problem is when motor 1 is running and i press forward or reverse button motor 1 stops until motor 2 done running
i want to run my motor 1 in interrupt timer but i don't know how to add other function like speed control and start stop for motor 1
#include <Arduino.h>
// Define the stepper motor pins for motor 1
#define STEP_PIN_1 9
#define DIRECTION_PIN_1 10
// Define the stepper motor pins for motor 2
#define STEP_PIN_2 11
#define DIRECTION_PIN_2 12
// Define the button pins for motor 2
#define FORWARD_BUTTON_PIN 4
#define BACKWARD_BUTTON_PIN 5
// Define stepper motor parameters
const int stepsPerRevolution = 200; // Number of steps per revolution for your motor
int stepSpeed_1 = 1000; // Step delay for motor 1 (in microseconds)
bool direction_1 = HIGH; // HIGH for motor 1 clockwise, LOW for motor 1 counterclockwise
bool direction_2 = HIGH; // HIGH for motor 2 clockwise, LOW for motor 2 counterclockwise
volatile int stepCounter_1 = 0;
void setup() {
// Initialize stepper motor pins for motor 1
pinMode(STEP_PIN_1, OUTPUT);
pinMode(DIRECTION_PIN_1, OUTPUT);
// Set the initial direction for motor 1
digitalWrite(DIRECTION_PIN_1, direction_1);
// Initialize stepper motor pins for motor 2
pinMode(STEP_PIN_2, OUTPUT);
pinMode(DIRECTION_PIN_2, OUTPUT);
// Set the initial direction for motor 2
digitalWrite(DIRECTION_PIN_2, direction_2);
// Initialize button pins for motor 2
pinMode(FORWARD_BUTTON_PIN, INPUT_PULLUP);
pinMode(BACKWARD_BUTTON_PIN, INPUT_PULLUP);
// Set up Timer1 for motor 1
cli(); // Disable global interrupts
TCCR1A = 0; // Clear Timer1 control registers
TCCR1B = 0;
OCR1A = 50000; // Set the compare value (adjust for desired speed)
TCCR1B |= (1 << WGM12); // Set CTC mode
TCCR1B |= (1 << CS10); // Set prescaler to 1
TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt
sei(); // Enable global interrupts
}
void loop() {
// Motor 2 responds to button presses
if (digitalRead(FORWARD_BUTTON_PIN) == LOW) {
direction_2 = HIGH; // Set direction forward
digitalWrite(DIRECTION_PIN_2, direction_2);
stepMotor_2(50); // Step 50 steps forward
}
if (digitalRead(BACKWARD_BUTTON_PIN) == LOW) {
direction_2 = LOW; // Set direction backward
digitalWrite(DIRECTION_PIN_2, direction_2);
stepMotor_2(50); // Step 50 steps backward
}
}
// Timer1 interrupt service routine for motor 1
ISR(TIMER1_COMPA_vect) {
digitalWrite(STEP_PIN_1, HIGH);
delayMicroseconds(1);
digitalWrite(STEP_PIN_1, LOW);
delayMicroseconds(1);
// Update the step counter for motor 1
if (direction_1 == HIGH) {
stepCounter_1++;
if (stepCounter_1 == stepsPerRevolution)
stepCounter_1 = 0;
} else {
stepCounter_1--;
if (stepCounter_1 < 0)
stepCounter_1 = stepsPerRevolution - 1;
}
}
void stepMotor_2(int steps) {
for (int i = 0; i < steps; i++) {
digitalWrite(STEP_PIN_2, HIGH);
delayMicroseconds(160);
digitalWrite(STEP_PIN_2, LOW);
delayMicroseconds(160);
}
}
You really don't need interrupts at all and you are handling your buttons wrong.
For speed changes I would suggest using state change detection on your buttons because you may detect multiple presses because of bouncing. See State Change Detection
For the steppers it would be much easier to use a nonblocking stepper library like Accelstepper. See AccelStepper
Also, for most switches, wiring to ground and using the internal pullup resistor is better practice. My state change detection for active low inputs has code examples and wiring schematics for switches wired to ground.
I highly recommend using the mobatools-library for driving the stepper-motors.
The reason is:
The mobatools create the step-pulses in the backround. Similar to how you are doing it with a timer-interrupt. The difference is: the mobatools have evolved over a long time to version 2.5
and work very reliably in all aspects.
This enables to do things like:
reacting on button-presses all the time without disturbing the stepper-motors,
changing speed,
reading sensors etc. etc.
start / stop any stepper-motor at any time even as emergency stop
print to the serial monitor
start / stop / change speed of a stepper-motor invoked by a signal on an interrupt-IO-pin
while the stepper-motors run smoothly in parallel to all these actions.
Including user-configurable acceleration / decceration
The Mobatools offer button-management too even with double-press or long-press
The author of the MobaTools microbahner is active on the forum.
if you have a special question it is very likely that he will answer you.
You can download the mobatools with the library-manager of the arduino-IDE
All these advantages is it worth to learn the function-calls of the mobatools.
my application is very simple first motor will run in one direction continues until I press start and stop and two pin for speed up and down other two motors will run with two switch each forward or backward if I press forward motor will run 50 steps in one direction and vice versa
problem with my first code was when motor 1 was running when I press forward or backward first motor was getting stop unit other motor ran, so I thought to run first motor in interrupt timer
and one more extra thing i change my driver to TMC2209 for smoothness so if any one knows basic code please lat me know
what is the final purpose of running the stepper-motors?
some random examples:
do you want to create sounds with the stepper-motors?
do you move back and forth a waving hand with the stepper-motors for greeting if you open the door to your house?
do your stepper-motors drive peristaltic pumps?
What is the final purpose of having three stepper-motors run as you described above?
The TMC2209 can be driven with step-dir-input exact the same way as a A4988 or DRV8825
additionally the TMC2209 offers controlling it over a serial interface but this is not a must.
First you should write and test the logic for button-press => wanted driving of the stepper-motor.
You should write this logic as its own section of code.
Give the MobaTools a try. After learning the function-calls you will have an easy time to do all the rest.
If you stay with your self-written timer-interrupt you will have to hassle around with all the details that are solved and ready to use in the mobatools.
The author of the MobaTools microbahner is active on the forum. if you have a special question it is very likely that he will answer you.
The mobatools create the step-pulses in the backround. Similar to how you are doing it with a timer-interrupt. The difference is: the mobatools have evolved over a long time to version 2.5
and work very reliably in all aspects.
This enables to do things like:
reacting on button-presses all the time without disturbing the stepper-motors,
changing speed,
reading sensors etc. etc.
start / stop any stepper-motor at any time even as emergency stop
print to the serial monitor
start / stop / change speed of a stepper-motor invoked by a signal on an interrupt-IO-pin
while the stepper-motors run smoothly in parallel to all these actions.
Including user-configurable acceleration / decceration
The Mobatools offer button-management too even with double-press or long-press
i have try and use Mobatools and it works but i have two doubts first how to control and change speed of main motor when it is running in my current code it is not working when i push speed down its slowing to much and when i push it again it increases speed
and how to run other motor on push button let's say one push 50 step in one direction
#include <MobaTools.h>
#define Step_pin 11
#define Dir_pin 12
#define StratBtn A1
#define StopBtn A0
#define SpeedUp A2
#define SpeedDown A3
#define MOTOR_STEPS 600
#define STEP_PER_REVALUATION 600
long speed = 35000;
boolean startState = 0; // current state of the button
boolean laststartButtonState = 0; // previous state of the button
boolean stopState = 0; // current state of the button
boolean laststopButtonState = 0; // previous state of the button
boolean speedUpState = 0; // current state of the button
boolean lastspeedUpButtonState = 0; // previous state of the button
boolean speedDownState = 0; // current state of the button
boolean lastspeedDownButtonState = 0; // previous state of the button
MoToStepper mainStepper(STEP_PER_REVALUATION, STEPDIR);
void setup(){
Serial.begin(9600);
mainStepper.attach(Step_pin,Dir_pin);
mainStepper.setSpeed(speed);
mainStepper.setRampLen(20);
pinMode(StratBtn, INPUT_PULLUP);
pinMode(StopBtn, INPUT_PULLUP);
pinMode(SpeedUp, INPUT_PULLUP);
pinMode(SpeedDown, INPUT_PULLUP);
}
void loop(){
startState = digitalRead(StratBtn);
stopState = digitalRead(StopBtn);
speedUpState = digitalRead(SpeedUp);
speedDownState = digitalRead(SpeedDown);
if (startState != laststartButtonState){
if (startState == LOW){
mainStepper.rotate(1);
Serial.println("motoe startes");
}
laststartButtonState = startState;
}
if (stopState != laststopButtonState) {
if (stopState == LOW) {
mainStepper.stop();
Serial.println("motoe stop");
}
laststopButtonState = stopState;
}
if (speedUpState != lastspeedUpButtonState) {
if (speedUpState == LOW) {
speed += 2000;
mainStepper.setSpeed(speed);
Serial.println("motoe speed");
Serial.println(speed);
// Ensure speed stays within the bounds
if (speed > 50000) {
speed = 50000;
mainStepper.setSpeed(speed);
Serial.println("motoe speed");
Serial.println(speed);
}
}
lastspeedUpButtonState = speedUpState;
}
if (speedDownState != lastspeedDownButtonState) {
if (speedDownState == LOW) {
speed -= 2000;
mainStepper.setSpeed(speed);
Serial.println("motoe speed");
Serial.println(speed);
// Ensure speed stays within the bounds
if (speed < 10000) {
speed = 10000;
mainStepper.setSpeed(speed);
Serial.println("motoe speed");
Serial.println(speed);
}
}
lastspeedDownButtonState = speedDownState;
}
}
By default speed is limited to 2500 steps/sec ( 25000 steps/10sec ) on AVR processors. This becuase MobaTools is designed to drive up to 6 steppers with that speed. If you need only 2 steppers it is possible to tune this up to 5000 steps/sec by a define in MobaTools.h
Really? What stepper are you using? Usually they need 200 steps/rev with fullstep. And with microstepping it may be 400,800,1600 .... depending on the microstep setting of the TMC2209.
You don't debounce your buttons. I would suggest you use the MotoButtons class for your buttons.