Step motor speed with TB6560 IC-driver and 2 push buttons

I found this topic in forum

I want to reply and continue with this topic has been created but I can't reply from this one. I have to create a new topic. Sorry if I make a mistake. Thanks.

My project uses the Arduino Uno to control a step motor NEMA 23:

and 2 buttons switches to change the direction each time pressed.

The motor diver is TB6560 IC with wiring as in video.

I found the code from Robin2 that I can apply to my application. Thanks Robin2 !

It works but the motor turns too slow.

I have changed the variable value "illisBetweenSteps" = 5 (from 25 as original) but still slow.

The code is in attached.

Could someone can tell me how to modify the code to make the motor turning faster (10x or more) ?

Thanks in advance,

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other one and it turns CCW

byte directionPin = 8;    
byte stepPin = 9;          

byte buttonCWpin = A0;
byte buttonCCWpin = A1;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 5; // milliseconds

void setup() {

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(directionPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     pinMode(buttonCCWpin, INPUT_PULLUP);
     
}

void loop() {
   
    curMillis = millis();
    readButtons();
    actOnButtons();
   
}

void readButtons() {
   
    buttonCCWpressed = false;
    buttonCWpressed = false;
   
    if (digitalRead(buttonCWpin) == LOW) {
        buttonCWpressed = true;
    }
    if (digitalRead(buttonCCWpin) == LOW) {
        buttonCCWpressed = true;
    }
}

void actOnButtons() {
    if (buttonCWpressed == true) {
        digitalWrite(directionPin, LOW);
        singleStep();
    }
    if (buttonCCWpressed == true) {
        digitalWrite(directionPin, HIGH);
        singleStep();
    }
}

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}

Use micros() instead of millis(). Are you using microstepping? Less microsteps for higher speed.

To acheive higher speeds, acceleration will be required.

viet5d:
I have changed the variable value "illisBetweenSteps" = 5 (from 25 as original) but still slow.

Can you first confirm that your change made the motor run 5 times faster than when the value was 25?

If not, then there is another problem - perhaps even 25 is too fast and the motor is missing steps? Stepper motors usually need to be accelerated to higher speeds. If you think it is missing steps increase the interval to 250 and see what happens. Then gradually reduce the value.

How many steps are needed for one revolution?

How fast (in steps per second, or revs per second) is your motor actually moving?

...R

Robin2:
Can you first confirm that your change made the motor run 5 times faster than when the value was 25?

---> Yes, value = 5 seems faster than value = 25 five times. Value higher than 25 seems slower...

How many steps are needed for one revolution?

---> As motor spec., step angle = 360/200 = 1.8 deg. or 200 steps par resolution.

How fast (in steps per second, or revs per second) is your motor actually moving?

---> If that value = 5, speed actually around 5-7 steps per seconde (both direction).

Thanks.

V5d

groundFungus:
Use micros() instead of millis(). Are you using microstepping? Less microsteps for higher speed.

To acheive higher speeds, acceleration will be required.

Thanks for reply.

As motor spec., the motor resolution is 200 steps, or step angle = 1.8 deg.

V5d

viet5d:
---> Yes, value = 5 seems faster than value = 25 five times

You have not answered the question I asked - is it exactly 5 times faster? Knowing the answer to that is essential for taking this further.

---> If that value = 5, speed actually around 5-7 steps per seconde (both direction).

With a step interval of 5 millisecs there should be close to 200 steps per second.

With a step interval of 25 millisecs there should be about 40 steps per second, or about 5 seconds for 1 revolution of 200 steps.

...R

How are the microstep switches set on the driver?

JCA34F:
How are the microstep switches set on the driver?

Microsteps sets (S3-S4 switches, Microstep revolution) at 1/8 step (ON-ON). Max. can set at 1/16 step. I will try it and let you know later.

Thanks,
V5d

Robin2:
You have not answered the question I asked - is it exactly 5 times faster? Knowing the answer to that is essential for taking this further.

Hi Robin,

Sorry, I can not measure exactly the speed. Just see visually the speed at 5 is faster than 25 value approximately 5 times.

Thanks,
V5d

viet5d:
Sorry, I can not measure exactly the speed. Just see visually the speed at 5 is faster than 25 value approximately 5 times.

Another test that you can do is get it to move 1000 steps at each speed and check that it actually move exactly 5 revolutions. Attaching a bit of sticky-tape to the motor shaft is a good way to check movement. You could also time the movements.

...R

viet5d:
Microsteps sets (S3-S4 switches, Microstep revolution) at 1/8 step (ON-ON). Max. can set at 1/16 step. I will try it and let you know later.

Thanks,
V5d

OK, here is the results with "millisBetweenSteps" = 5 (value most interested).

When I change the position of (S3-S4) to (OFF-ON) for 1/16 step ----> still slow.

But, changed (S3-S4) to (ON-OFF) for HALF step -----> Faster, 2 seconds (counted with timer) par resolution (1 turn or 360 deg.)

Others possibilities of (S3-S4) ----> Slow and slower.

Thanks,
V5d

viet5d:
OK, here is the results with "millisBetweenSteps" = 5 (value most interested).

When I change the position of (S3-S4) to (OFF-ON) for 1/16 step ----> still slow.

But, changed (S3-S4) to (ON-OFF) for HALF step -----> Faster, 2 seconds (counted with timer) par resolution (1 turn or 360 deg.)

Others possibilities of (S3-S4) ----> Slow and slower.

Thanks,
V5d

Good new ! At HAFT step position, set "millisBetweenSteps" = 1, faster what I need, for now.

Very appreciated your time.

V5d.

Hello Robin,

I'm thinking to add 2 limits switches at the end of each direction (CW/CCW). Just for protection in case the butons defected.

When a pointer (synchronized with movement of step motor) touches one of the limit switch, the motor changes also its directions.

Do I have to read the state of each switch ?

Thanks,
V5d

I will change the code for readButtons() function to readButtonsAndSw() to detect 2 limit switches as below:

void readButtonsAndSw() {
   
    buttonCCWpressed = false;
    buttonCWpressed = false;
    swCCWpressed = false;
    swCWpressed = false;
   
    if ((digitalRead(buttonCWpin) ││ (digitalRead(swCWpin)) == LOW) {
        buttonCWpressed = true;
        swCWpressed = true;
    }
    if ((digitalRead(buttonCCWpin) ││ (digitalRead(swCCWpin) == LOW) {
        buttonCCWpressed = true;
        swCCWpressed = true;
    }
}

(...)

Thanks for advise,
V5d

viet5d:
Do I have to read the state of each switch ?

That seems to me the simplest thing to do.

...R

Robin2:
That seems to me the simplest thing to do.

...R

Here is the full code, compiled without error. Will be tested with hardware.

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push bottons and switches
// press one of them (button/limit sw) and it turns CW, press the other one and it turns CCW

byte dirPin = 8;   
byte stepPin = 9;         

byte buttonCWpin  = A0;
byte buttonCCWpin = A1;
byte swCWpin  = A2;
byte swCCWpin = A3;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;
boolean swCWpressed = false;
boolean swCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepPinMillis = 0;
unsigned long millisBetweenSteps = 1; // milliseconds

void setup() {

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(dirPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);

     pinMode(buttonCWpin, INPUT_PULLUP);
     pinMode(buttonCCWpin, INPUT_PULLUP);
     pinMode(swCWpin, INPUT_PULLUP);
     pinMode(swCCWpin, INPUT_PULLUP);
}

void loop() {
   
    curMillis = millis();
    readButtonsAndSw();
    actOnButtonsAndSw();
  
}

void readButtonsAndSw() {
   
    buttonCCWpressed = false;
    buttonCWpressed = false;
    swCCWpressed = false;
    swCWpressed = false;
    
    if ((digitalRead(buttonCWpin) || (digitalRead(swCWpin)) == LOW)) {
        buttonCWpressed = true;
        swCWpressed = true;
        }
      
     if ((digitalRead(buttonCCWpin) || (digitalRead(swCCWpin)) == LOW)) {
        buttonCCWpressed = true;
        swCCWpressed = true;
        }
    }

void actOnButtonsAndSw() {
    if (((buttonCWpressed) || (swCWpressed)) == true) {
        digitalWrite(dirPin, LOW);
        singleStep();
        }
        
    if (((buttonCCWpressed) || (swCCWpressed)) == true) {
        digitalWrite(dirPin, HIGH);
        singleStep();
       }
    }

void singleStep() {
    if (curMillis - prevStepPinMillis >= millisBetweenSteps) {
        // next 2 lines changed 28 Nov 2018
        //prevStepPinMillis += millisBetweenSteps;
        prevStepPinMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
        }
    }

viet5d:
Here is the full code, compiled without error. Will be tested with hardware.

// this version uses millis() to manage timing rather than delay()

// and the movement is determined by a pair of momentary push bottons and switches
// press one of them (button/limit sw) and it turns CW, press the other one and it turns CCW

byte dirPin = 8;  
byte stepPin = 9;

byte buttonCWpin  = A0;
byte buttonCCWpin = A1;
byte swCWpin  = A2;
byte swCCWpin = A3;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;
boolean swCWpressed = false;
boolean swCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepPinMillis = 0;
unsigned long millisBetweenSteps = 1; // milliseconds

void setup() {

Serial.begin(9600);
    Serial.println("Starting Stepper Demo with millis()");

pinMode(dirPin, OUTPUT);
    pinMode(stepPin, OUTPUT);
    pinMode(ledPin, OUTPUT);

pinMode(buttonCWpin, INPUT_PULLUP);
    pinMode(buttonCCWpin, INPUT_PULLUP);
    pinMode(swCWpin, INPUT_PULLUP);
    pinMode(swCCWpin, INPUT_PULLUP);
}

void loop() {
 
   curMillis = millis();
   readButtonsAndSw();
   actOnButtonsAndSw();
 
}

void readButtonsAndSw() {
 
   buttonCCWpressed = false;
   buttonCWpressed = false;
   swCCWpressed = false;
   swCWpressed = false;
   
   if ((digitalRead(buttonCWpin) || (digitalRead(swCWpin)) == LOW)) {
       buttonCWpressed = true;
       swCWpressed = true;
       }
     
    if ((digitalRead(buttonCCWpin) || (digitalRead(swCCWpin)) == LOW)) {
       buttonCCWpressed = true;
       swCCWpressed = true;
       }
   }

void actOnButtonsAndSw() {
   if (((buttonCWpressed) || (swCWpressed)) == true) {
       digitalWrite(dirPin, LOW);
       singleStep();
       }
       
   if (((buttonCCWpressed) || (swCCWpressed)) == true) {
       digitalWrite(dirPin, HIGH);
       singleStep();
      }
   }

void singleStep() {
   if (curMillis - prevStepPinMillis >= millisBetweenSteps) {
       // next 2 lines changed 28 Nov 2018
       //prevStepPinMillis += millisBetweenSteps;
       prevStepPinMillis = curMillis;
       digitalWrite(stepPin, HIGH);
       digitalWrite(stepPin, LOW);
       }
   }

First fast testing this code with hardware, I note:

  1. With button CW direction is pressed, motor turns in this direction. When the pointer touches the limit "swCWpressed", the motor direction changes to CCW. But I can not use the button CCW (or swCCWpressed) to change the direction after that moment.

  2. Same behave to other direction.

Need helps !

Thanks,
V5d

viet5d:
First fast testing this code with hardware, I note:

  1. With button CW direction is pressed, motor turns in this direction. When the pointer touches the limit "swCWpressed", the motor direction changes to CCW. But I can not use the button CCW (or swCCWpressed) to change the direction after that moment.

  2. Same behave to other direction.

Need helps !

Thanks,
V5d

Correction point #1:

  1. With button CW direction is pressed, motor turns in this direction. When the pointer touches the limit "swCWpressed" and stays in that state (connected to GND), the motor direction changes to CCW. But I can not use the button CCW (or swCCWpressed) to change the direction after that moment. When the "swCWpressed" releases, the moter returns to CW direction immediately.

Thanks,

viet5d:
Correction point #1:

  1. With button CW direction is pressed, motor turns in this direction. When the pointer touches the limit "swCWpressed" and stays in that state (connected to GND), the motor direction changes to CCW. But I can not use the button CCW (or swCCWpressed) to change the direction after that moment. When the "swCWpressed" releases, the moter returns to CW direction immediately.

Thanks,

Please note: - The button CW/CCW is a contact SPDT type

  • The 2 limit SWs are the momentary contacts

Thanks,
V5d

I woould separate the buttons and limit switches. Have a separate function for each. One function handles the buttons and another handles the limit switches. Each time that you step, check the limit swiches. If one limit swich is activatd, reverse the current direction.