Stepper Motor Control

Hello all! At the moment I am trying to upgrade an induction annealer I have built to anneal brass for reloading. While my first design to lower and raise the table worked, it was crude and temporary. For those curious the table that needs to be able to go up and down for different length brass to be centered in the induction coil. later on i ended up coming up with a design in fusion 360 3D printing it off and now I am stuck.

Concept: use 2 Stepper Motors to raise the table up and down and use 1 momentary switch to make the steppers go counter clockwise and another to make them go clockwise.

Items I have: Arduino Uno, CNC Shield Expansion board V3, 4 A4988 Stepper drivers, 2 Nema 17 Stepper, 12V power supply for the CNC shield.

I just need guidance on where to start as it has been years since I have programmed anything and my first time messing with Arduinos.

I don’t know really where to start programming wise or where to throw the momentary switches on the CNC Shield.

52993908_2249470188453619_7597029481349382144_n.jpg

53113390_435587870513479_183599170320334848_n.jpg

You really need only one limit switch. Put it so that it is closed when the table is all the way down. Call that the "home" position. Since you know how far the steppers rotate for each step and the pitch of the lead screw you can calculate the number of steps from home to any position of the table. For instance 200 step per revolution stepper running at half steps (2X microstepping) takes 400 steps per rev., so a 1mm pitch lead screw will move the table 1mm for every 400 steps. To move up 10mm send 4000 steps.

You would home the system each time at power up or any time that you need to re-establish your zero reference.

Put a funtion in your code that checks for a requested movement that is past the upper limit and do not allow movement past the limit (known as a soft limit).

start with talking to your stepper modules. The A4988 modules are very easy to programm. just need to have a pin for direction (cw or ccw) and a step signal. The step signal is easy made with a digital output of the arduino which is set high/low for every step of the motor. The pins for MS1..MS3 can be useful if you want to use microstepping, this works like a software gearbox. Normal steppers have 1.8° stepangle, means for each step the motor turns 1.8° further. with microstepping you can devide this steps in halv-quarter-eights-sixteens. So you can have finer adjustmens (this is good for z-axis!)

BTW: be careful to read first, how to adjust the current setting on the a4988 modules!

Stepper basics.

Simple stepper code

So I have code now that will get the stepper motors moving up and down on the CNC Shield. However, I have no idea how to fit in the momentary push buttons into the build for Up and Down controls for the motors.

#define EN        8  

//Direction pin
#define X_DIR     5       //controls left side motor
#define Y_DIR     6       //controls right side motor
#define Z_DIR     7       //unused

//Step pin
#define X_STP     2       //controls left side motor
#define Y_STP     3       //controls right side motor
#define Z_STP     4       //unused


//DRV4988
int delayTime=160; //uS Delay between each pause - effective speed control 
int stps=3200;// Steps to move - 3200 is one rev


void step(boolean dir, byte dirPin, byte stepperPin, int steps)

{

  digitalWrite(dirPin, dir);
  digitalWrite(dirPin+1, dir);      //write direction to both pins

  delay(1000);

  for (int i = 0; i < steps; i++) {

    digitalWrite(stepperPin, HIGH);
    digitalWrite(stepperPin+1, HIGH);      //write to both sides

    delayMicroseconds(delayTime); 

    digitalWrite(stepperPin, LOW);
    digitalWrite(stepperPin+1, LOW);       //write to both sides

    delayMicroseconds(delayTime); 

  }

}

void setup(){

  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);

  pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);

  pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);

  pinMode(EN, OUTPUT);

  digitalWrite(EN, LOW);

}

void loop(){


  step(true, X_DIR, X_STP, stps); //Counterclockwise (up)
  //step(true, Y_DIR, Y_STP, stps); //Y, Counterclockwise
  //step(true, Z_DIR, Z_STP, stps); //X, Counterclockwise

  step(false, X_DIR, X_STP, stps); //Clockwise (down)
  //step(false, Y_DIR, Y_STP, stps); //Y, Clockwise
  //step(false, Z_DIR, Z_STP, stps); //Z, Clockwise


  


}

So, I’m going to try and use the ABORT and HOLD pin on the CNC Shield since they both seem to go directly to the Arduino A0 and A1 pins. If I can’t use these pins then I’m going to cut the pins that control Y and Z Dir as well as STP on the CNC so I can access them freely on the Arduino board, though I want to try the previous stated idea prior to cutting. Currently cleaning up the code of things I don’t need anymore since I also cloned the X-axis on the CNC board. Then I’ll start trying to figure out how to code for the buttons.

#define EN        8  

//Direction pin
#define X_DIR     5       //controls both motors since X-axis is cloned on CNC Shield
#define Y_DIR     6       //unused
#define Z_DIR     7       //unused

//Step pin
#define X_STP     2       //controls both motors since X-axis is cloned on CNC Shield
#define Y_STP     3       //unused
#define Z_STP     4       //unused

//Button pin
#define CW_DOWN     A0 //Abort Pin
#define CCW_UP     A1 //Hold Pin


//A4988
int delayTime=160; //uS Delay between each pause - effective speed control 

int stps=3200;// Steps to move - 3200 is one rev


void step(boolean dir, byte dirPin, byte stepperPin, int steps)

{

  digitalWrite(dirPin, dir);

  delay(1000);

  for (int i = 0; i < steps; i++) {

    digitalWrite(stepperPin, HIGH);


    delayMicroseconds(delayTime); 

    digitalWrite(stepperPin, LOW);

    delayMicroseconds(delayTime); 

  }

}

void setup(){

  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);



  pinMode(EN, OUTPUT);

  digitalWrite(EN, LOW);

}

void loop(){


  step(true, X_DIR, X_STP, stps); //Counterclockwise (up)


  step(false, X_DIR, X_STP, stps); //Clockwise (down)



  


}

Help?

#define EN        8  

//Direction pin
#define X_DIR     5       //cloned for both motors
#define Y_DIR     6       //unused
#define Z_DIR     7       //unused

//Step pin
#define X_STP     2       //cloned for both motors
#define Y_STP     3       //unused
#define Z_STP     4       //unused

//Button pin
#define CW_DOWN    A0 //Abort Pin
#define CCW_UP     A1 //Hold Pin


//A4988
//int delayTime=100; //uS Delay between each pause - effective speed control 
//int stps=3200;// Steps to move - 3200 is one rev
int UPbuttonState = 0;      //initial up button state to 0
int DOWNbuttonState = 0;      //initial up button state to 0


//void step(boolean dir, byte dirPin, byte stepperPin, int stps)

//{

  //digitalWrite(dirPin, dir);
 
  //delay(1000);

  //for (int i=0; i < stps; i++) {

    //digitalWrite(stepperPin, HIGH);
    
    //delayMicroseconds(delayTime); 

    //digitalWrite(stepperPin, LOW);

    //delayMicroseconds(delayTime); 

    //}

//}

void setup(){

  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);

  pinMode(CW_DOWN, INPUT); pinMode(CCW_UP, INPUT);

  pinMode(EN, OUTPUT);

  digitalWrite(EN, LOW);

}

void loop(){

// read the state of the pushbutton value:
  UPbuttonState = digitalRead(CCW_UP);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (UPbuttonState == HIGH) {
    // turn LED on:
    digitalWrite(X_DIR, true);
    digitalWrite(X_STP, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(X_DIR, true);
    digitalWrite(X_STP, LOW);
  }

  // read the state of the pushbutton value:
  DOWNbuttonState = digitalRead(CCW_UP);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (DOWNbuttonState == HIGH) {
    // turn LED on:
    digitalWrite(X_DIR, false);
    digitalWrite(X_STP, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(X_DIR, false);
    digitalWrite(X_STP, LOW);
  }
}

jthornton1993:
Help?

With what do you need help?

In Reply #5 you said you were going to do stuff but you have not told us how that turned out.

...R

Currently when I load the sketch the stepper motors will go up and then down and stops until I press the single button I have wired currently; which is for up. Once I press the button it seems to just go through that loop of up and down once. If I hold the button down it does nothing.

If you don't have pulldown resistors (10k) from A0 and A1 to GND, they are floating when the buttons are not pressed, and can generate false presses, fix that first. Here's your code stripped of unused, commented out and blank lines.

#define EN        8 
//Direction pin
#define X_DIR     5       //cloned for both motors
//Step pin
#define X_STP     2       //cloned for both motors

//Button pin
#define CW_DOWN    A0 //Abort Pin
#define CCW_UP     A1 //Hold Pin
//A4988
//int delayTime=100; //uS Delay between each pause - effective speed control
//int stps=3200;// Steps to move - 3200 is one rev
int UPbuttonState = 0;      //initial up button state to 0
int DOWNbuttonState = 0;      //initial up button state to 0

void setup(){
  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
  pinMode(CW_DOWN, INPUT); pinMode(CCW_UP, INPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
}
void loop(){
// read the state of the pushbutton value:
  UPbuttonState = digitalRead(CCW_UP);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (UPbuttonState == HIGH) {
    // turn LED on:
    digitalWrite(X_DIR, true);
    digitalWrite(X_STP, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(X_DIR, true);
    digitalWrite(X_STP, LOW);
  }
  // read the state of the pushbutton value:
  DOWNbuttonState = digitalRead(CCW_UP);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (DOWNbuttonState == HIGH) {
    // turn LED on:
    digitalWrite(X_DIR, false);
    digitalWrite(X_STP, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(X_DIR, false);
    digitalWrite(X_STP, LOW);
  }
}

Got it to work! Ended up using the Y and Z Dir Pins on the CNC shield to get the signals from the buttons.

#define EN        8  

//Direction pin
#define X_DIR     5       //cloned for both motors
#define Y_DIR     6       //up button
#define Z_DIR     7       //down button

//Step pin
#define X_STP     2       //cloned for both motors
#define Y_STP     3       //unused
#define Z_STP     4       //unused


//A4988
int delayTime=240; //uS Delay between each pause - effective speed control 
int stps=1;// Steps to move - 3200 is one rev
int UPbuttonState = 0;      //initial up button state to 0
int DOWNbuttonState = 0;      //initial up button state to 0


void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{

  digitalWrite(dirPin, dir);

  for (int i=0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);  
    delayMicroseconds(delayTime); 
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(delayTime); 
    }

}

void setup(){

  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
  pinMode(Z_DIR, INPUT); pinMode(Y_DIR, INPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
}

void loop(){

// read the state of the pushbutton value:
  UPbuttonState = digitalRead(Y_DIR);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (UPbuttonState == HIGH) {
    //move motors up:
    step(true, X_DIR, X_STP, stps);
  }
  if (UPbuttonState == LOW) {
    //do nothing:
    //step(true, X_DIR, X_STP, stps);
  }

  // read the state of the pushbutton value:
  DOWNbuttonState = digitalRead(Z_DIR);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (DOWNbuttonState == HIGH) {
    //move motors down:
    step(false, X_DIR, X_STP, stps);
  }
  if (DOWNbuttonState == LOW) {
    //do nothing:
    //step(false, X_DIR, X_STP, stps);
  }
}

JCA79B:
If you don't have pulldown resistors (10k) from A0 and A1 to GND, they are floating when the buttons are not pressed, and can generate false presses, fix that first. Here's your code stripped of unused, commented out and blank lines.

#define EN        8 

//Direction pin
#define X_DIR     5       //cloned for both motors
//Step pin
#define X_STP     2       //cloned for both motors

//Button pin
#define CW_DOWN    A0 //Abort Pin
#define CCW_UP     A1 //Hold Pin
//A4988
//int delayTime=100; //uS Delay between each pause - effective speed control
//int stps=3200;// Steps to move - 3200 is one rev
int UPbuttonState = 0;      //initial up button state to 0
int DOWNbuttonState = 0;      //initial up button state to 0

void setup(){
 pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
 pinMode(CW_DOWN, INPUT); pinMode(CCW_UP, INPUT);
 pinMode(EN, OUTPUT);
 digitalWrite(EN, LOW);
}
void loop(){
// read the state of the pushbutton value:
 UPbuttonState = digitalRead(CCW_UP);
 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (UPbuttonState == HIGH) {
   // turn LED on:
   digitalWrite(X_DIR, true);
   digitalWrite(X_STP, HIGH);
 }
 else {
   // turn LED off:
   digitalWrite(X_DIR, true);
   digitalWrite(X_STP, LOW);
 }
 // read the state of the pushbutton value:
 DOWNbuttonState = digitalRead(CCW_UP);
 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (DOWNbuttonState == HIGH) {
   // turn LED on:
   digitalWrite(X_DIR, false);
   digitalWrite(X_STP, HIGH);
 }
 else {
   // turn LED off:
   digitalWrite(X_DIR, false);
   digitalWrite(X_STP, LOW);
 }
}

I got the resistor thing solved. quickly realized when I pulled them the loop just continued to play itself without the button being pressed. Thanks!