controlling TB6600 stepper driver with push button

Hi.

Before i start, here the point from my problem:

1> About wiring connection between push button and TB6600 stepper driver
2> About code between push button and TB6600 stepper driver

Here, i want to control stepper motor rotation using push button.

What i want is when i push the button the motor will keep rotating, and then when i pull it, the motor will stop.

I want use it for calibrating of my CNC machine and manual control.
But i cant find correct wiring and the code:(, i am still trying until now.

so far right now, my code is :

int PUL = 7; 
int DIR = 6; 
int ENA = 5;

const int buttonPinA  = 3;
const int buttonPinB  = 8;
 
int LED = 4;

int buttonStateA = 0;
int buttonStateB = 0;


void setup() 
{
  pinMode (PUL, OUTPUT);
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);

  pinMode (LED, OUTPUT);
  pinMode (buttonPinA, OUTPUT);
  pinMode (buttonPinB, OUTPUT);

  Serial.begin(9600);
}

void loop() 
{
  Serial.println("\t");
  
  buttonStateA = digitalRead (buttonPinA);
  buttonStateB = digitalRead (buttonPinB);

   ///     *MOTOR START*   
  if (buttonStateA == HIGH && buttonStateB == LOW)
  {
    do
  {
    X_AxisA();
    digitalWrite(LED, LOW);
  }
    while (buttonStateB == HIGH);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }

  ///   
  if (buttonStateB == HIGH)
  {
    X_AxisB();
    digitalWrite(LED, LOW);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }
}


void X_AxisA()
{
  for (int i=0; i < 400; i++) 
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    ///---
    digitalWrite(LED, HIGH);
    Serial.println(i);
  }
  for (int i=0; i < 400; i++) 
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    ///---
    digitalWrite(LED, HIGH);
    Serial.println(i);
  }
}

void X_AxisB()
{
  for (int i=0; i < 0; i++) 
  {
  digitalWrite(DIR, LOW);
  digitalWrite(ENA, LOW);
  digitalWrite(PUL, LOW);
  delayMicroseconds(100);
  digitalWrite(PUL, LOW);
  delayMicroseconds(100);
  ///---
  digitalWrite(LED, LOW);
  delayMicroseconds(100);
  }
}

*I looking for reference on google, mostly they using POLOLU A4988 driver with push button,and on the arduino examples too. I have try using digitalRead(A0) command and if else commad.
But its not work correctly.

Can someone help me fix this?

What happens when you press the button? Motor just hums?
What motor? What voltage to the motor.
What do you know about pull-in torque?
Your pulse loop is 200us. This translates, full step on a 1.8 degree stepper, to 1500rpm. That's kinda like asking your car to go from 0-60 in about 0.1 seconds - it won't work.

The concept of infinite acceleration is that which starts a stepper motor from zero. The pull-in torque curve for a particular motor will dictate how fast that is based on no load. With 12V motors it's typically 100-120 rpm, 24V motors maybe 200+. To get to speeds above that you must accelerate.

The TB6600 requires a pulse duration of a minimum 1us, soo holding the pulse high for 100us is unnecessary. The timing between pulses determines the speed. Basic formula is 300,000/rpm equals pulse timing in microseconds. Switch that around, 300,000/us equals rpm which is where you speed of 1500 fits in. Try increasing your delay at PUL,LOW to 1000 and see what happens.

Hi DKWatson.
Thank for your response sir.

Yes, when i keep push the button the stepper motor will keep rotating untill i release the button.
i dont know why my code wasnt work correctly?

this my stepper motor specification
-- 1.5A to 1.8A current per phase
-- 1-4 volts
-- 3 to 8 mH inductance per phase
-- 44 N·cm (62oz·in, 4.5kg·cm) or more holding torque
-- 1.8 or 0.9 degrees per step (200/400 steps/rev respectively)

i got reference for TB6600 code from TB6600_Stepper_Motor_Driver_SKU__DRI0043-DFRobot

based on stepper driver table that 6400pulse/1 revolution.
so i using 6400 pulse for the code.
So far for the stepper motor rotation is no problem, the motor when i input 6400 pulse will rotate 1 revolution.

But the problem is i cant controlled it using push button.

buttonPinA and buttonPinB are both declared in setup as OUTPUT. Should be INPUT and depending on yout circuit, may require pull-up or pull-down resistors on the switch.

ohh okay, how about the void loop() ?

void loop() 
{
  Serial.println("\t");
  
  buttonStateA = digitalRead (buttonPinA);
  buttonStateB = digitalRead (buttonPinB);

   ///     *MOTOR START*   
  if (buttonStateA == HIGH && buttonStateB == LOW)
  {
    do
  {
    X_AxisA();
    digitalWrite(LED, LOW);
  }
    while (buttonStateB == HIGH);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }

  ///   
  if (buttonStateB == HIGH)
  {
    X_AxisB();
    digitalWrite(LED, LOW);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }
}

void X_AxisA()
{
  for (int i=0; i < 400; i++) 
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    ///---
    digitalWrite(LED, HIGH);
    Serial.println(i);
  }
  for (int i=0; i < 400; i++) 
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    ///---
    digitalWrite(LED, HIGH);
    Serial.println(i);
  }
}

void X_AxisB()
{
  for (int i=0; i < 0; i++) 
  {
  digitalWrite(DIR, LOW);
  digitalWrite(ENA, LOW);
  digitalWrite(PUL, LOW);
  delayMicroseconds(100);
  digitalWrite(PUL, LOW);
  delayMicroseconds(100);
  ///---
  digitalWrite(LED, LOW);
  delayMicroseconds(100);
  }
}

*This is the main problem, when i push the button, the stepper motor wont rotating.
But i want the motor stepper keep rotating along i push the button.

These links may help
Stepper Motor Basics
Simple Stepper Code

Start simple - with the motor working very slowly with full steps

...R

The buttons could not have worked before so fix that first.

Hi Robin2,

Thanks for the code you share sir.
I have try it.

But still didnt work:(
I am confusing with the "byte" because i using TB6600 driver, the output pin is ENA, PUL, DIR.

so far right now i have try your code with a little modification

byte ENA = 5;
byte DIR = 6;
byte PUL = 7;

byte buttonCWpin = 10;
byte buttonCCWpin = 11;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

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

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

  pinMode(ENA, OUTPUT);
  pinMode(PUL, OUTPUT);
  pinMode(PUL, 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(ledPin,HIGH);
 digitalWrite(DIR, HIGH);
 digitalWrite(ENA, HIGH);
 digitalWrite(PUL, HIGH);
 singleStep();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
 if (buttonCCWpressed == true) 
 {
 digitalWrite(ledPin, HIGH);
 digitalWrite(DIR, HIGH);
 digitalWrite(ENA, HIGH);
 digitalWrite(PUL, HIGH);
 singleStep();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
}

void singleStep() 
{
 if (curMillis - prevStepMillis >= millisBetweenSteps) 
 {
 prevStepMillis += millisBetweenSteps;
 digitalWrite(DIR, LOW);
 digitalWrite(ENA, LOW);
 digitalWrite(PUL, LOW);
 }
}

when i push the button, just the LED turns on, but stepper motor didnt rotate.
I think my code is false, because i didnt know how to input ENA, PUL, DIR output to your code:(

Can you help me check the code?

Hi DKWatson,

Thanks for your opinion sir about the wiring, my button now works correctly.

You should set the enable pin in setup() and then leave it unchanged. In many situations people just hard-wire it to GND or 5v (depending on which is required to enable the driver). Also, many drivers will work without the enable pin connected to anything.

With that in mind, have you tried my code with the absolute minimum of changes - at least get to the stage where the motor moves reliably before worrying about buttons.

...R

Hi Robin2.

Yes i am testing now sir, hopefully i can find correct code for the rotation.
Until now i am using the simple code for stepper push button :

void loop()
{
  int buttonAstate = digitalRead(buttonA);
  int buttonBstate = digitalRead(buttonB);

  if (buttonAstate == HIGH)
  {
    digitalWrite(ledA, LOW);
  }
  else
  {
    digitalWrite(ledA, HIGH);
    X_AxisA();
  }
}



void X_AxisA()
{
  for (int i=0; i< 0; i++) /// Arah +++
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledA, HIGH);
  }
  for (int i=0; i< 800; i++) /// Arah ---
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledA, HIGH);
  }
}

thats for the void loop()
i just push the button once and then motor rotate untill 800 pulse.

But i am stil trying right now to use millis() command, to make the button keep rotating when i press it.

I have interesting qustion for you Robin2,

what is the diffrence? between

1.#DEFINE pin 
2.byte = pin;
3.int = pin;
4.const int = pin;

*Can you explain to me, and what the function of each type of the code? thanks.

nielyay:
Hi Robin2.

Yes i am testing now sir, hopefully i can find correct code for the rotation.
Until now i am using the simple code for stepper push button :

That does not look like the code from my example - which is what I suggested in Reply #8

what is the diffrence? between

1.#DEFINE pin 

2.byte = pin;
3.int = pin;
4.const int = pin;





*Can you explain to me, and what the function of each type of the code? thanks.

The line #define dirPin 9 just tells the compiler that wherever is sees the text dirPin it should replace it with the letter 9

The other versions create a variable. An int variable occupies 2 bytes so it just wastes space for values that will fit into a single byte.

The "const" tells the compiler that the value of the variable will never change so if you accidentally write a line that tries to change it you will get an error.

const byte dirPin = 9; is probably the best option

...R

Hi Robin2.

I told you i have a problem with the void loop().
i have do modification for your code but still didnt works.

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

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

//void...(2)
void actOnButtons() 
{
 if (buttonCWpressed == true) 
 {
 digitalWrite(ledPin,HIGH);
 singleStep();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
 if (buttonCCWpressed == true) 
 {
 digitalWrite(ledPin, HIGH);
 singleStep();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
}

//void...(3)
void singleStep() 
{
 if (curMillis - prevStepMillis >= millisBetweenSteps) 
 {
 prevStepMillis += millisBetweenSteps;
 digitalWrite(DIR, LOW);
 digitalWrite(ENA, LOW);
 digitalWrite(PUL, LOW);
 }
}

//void...(4)
void X_AxisA()
{
  for (int i=0; i< 6400; i++) /// Arah +++
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledPin, LOW);
  }
  for (int i=0; i< 6400; i++) /// Arah ---
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledPin, LOW);
  }
}

*i have input the void X_AxisA() for the rotation of the stepper motor based on its table, like 6400pulse for 1 revolution.
But still didnt works for now.
i know there is a wrong code.

nielyay:
i have do modification for your code but still didnt works.

Please post your complete program. Then I can compare it side by side with my original to see what changes you have made.

...R

Hi robin2.

byte ENA = 5;
byte DIR = 6;
byte PUL = 7;

byte buttonCWpin = 11;
byte buttonCCWpin = 12;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

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

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

  pinMode(ENA, OUTPUT);
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  
  pinMode(ledPin, OUTPUT);
  
  pinMode(buttonCWpin, INPUT_PULLUP);
  pinMode(buttonCCWpin, INPUT_PULLUP);
}

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

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

//void...(2)
void actOnButtons() 
{
 if (buttonCWpressed == true) 
 {
 digitalWrite(ledPin,HIGH);
 singleStep();
 X_AxisA();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
 if (buttonCCWpressed == true) 
 {
 digitalWrite(ledPin, HIGH);
 singleStep();
 X_AxisA();
 }
 else 
 {
  digitalWrite(ledPin, LOW);
 }
}

//void...(3)
void singleStep() 
{
 if (curMillis - prevStepMillis >= millisBetweenSteps) 
 {
 prevStepMillis += millisBetweenSteps;
 digitalWrite(DIR, LOW);
 digitalWrite(ENA, LOW);
 digitalWrite(PUL, LOW);
 }
}

//void...(4)
void X_AxisA()
{
  for (int i=0; i< 400; i++) /// Arah +++
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledPin, LOW);
  }
  for (int i=0; i< 400; i++) /// Arah ---
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(100);
    digitalWrite(PUL,LOW);
    delayMicroseconds(100);
    
    Serial.println(i);
    digitalWrite(ledPin, LOW);
  }
}

here the code.

Thanks. Unfortunately you have made a lot of irrelevant formatting changes (adding extra lines) which means it has taken me a long time to get my code to align with yours so I could compare them.

The main change seems to be your function X_AxisA(). What is it supposed to do? And why is it using delay() rather than millis() ?

What happens if you delete that function?

...R

Hi Robin2.

actually, l using X_AxisA() to setup the stepper motor rotation, based on TB6600 table, tells if DIP switch set up to 32 microstep, it will set 6400 pulse for 1 revolution.

if X_AxisA() deleted, the motor will not run 1 rev.

i didnt know how to combine my code into yours.. so i am asking you how to use that millis() function for the button.

here my first code for stepper motor rotate 1 rev.

int PUL=7;
int DIR=6; 
int ENA=5;
void setup() {
  pinMode (PUL, OUTPUT);
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);

}

void loop() {
  for (int i=0; i<6400; i++)    //Forward 5000 steps
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
  for (int i=0; i<6400; i++)   //Backward 5000 steps
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
}

*the code is without push button, so the motor correctly moved to 1 rev. Now,how to combine this code into your code using millis() function, so i can controlled the stepper motor with push button.

nielyay:
if X_AxisA() deleted, the motor will not run 1 rev.

That function is altogether the wrong way to do what you want.

Just get the program to call my singleStep() function as often as needed. Maybe when you press the button arrange for it to set a counter variable with the number of steps and then decrement the count for every singleStep()

...R

Hi Robin2.

Oah.. I understand now, thanks for your help :smiley:

I will try it again and show you the result.