Home steppers at beginning and then run the process once

I'm new to arduino so please forgive my stupidity if this is just a simple problem.(sorry for my poor English speaking)

i want to control two stepper motors (Nema 17) using pololu a4988 drivers.

In the setup There are

A push button [ 'Start button'-Start the process],

two stepper motors (Z axis , X axis),

two limit switches (Z axis home limit, X axis home limit)

One servo motor

Two led indicators ( Ready status((GREEN)), Processing status((RED)))

At start (when powered on the arduino) Ready Status(Green) indicator should be on so the process can be start by pushing 'Start button'. (This means that the two motors are already at the home position from last time its powered off)

If the two motors are not in the home position when powered on arduino (beacause of power failure or smt) the Processing status(Red) led should be on and both motors get to home position automatically.Then the red led turns off and Green led turns on.

The process is like this,(When pressed start button)

  • Servo at 0 position

  • Green led turns off Red led turns on

  • Z axis runs 500 steps (from home position) and stops

  • X axis runs 1000 steps (from home position) and stops

  • Servo turns 60 deg

  • Z axis goes back to home position and stops

  • X axis goes back to home position and stops

  • Red led turns off Green led turns on

After that program stops it runs again if start button is pressed.

im a beginner to arduino and dont have programming knowledge. tried lot of forums, codes and stuff but nothing was helpful. Please help me to solve this :frowning:

can some one give me some idea, tutorial, a sample code or any guidance if you have already done something like this...

Thank you !!!!

You should read this tutorial on state machines.

jay5050:
At start (when powered on the arduino) Ready Status(Green) indicator should be on so the process can be start by pushing 'Start button'. (This means that the two motors are already at the home position from last time its powered off)

If the two motors are not in the home position when powered on arduino (beacause of power failure or smt) the Processing status(Red) led should be on and both motors get to home position automatically.Then the red led turns off and Green led turns on.

At startup there is no means for the Arduino to know where the motors are. You need to do the homing movement every time the Arduino is started or reset.

In general, the way to home a stepper motor is to move it one step at a time towards the limit switch and check the switch between steps. If the switch is triggered before the motor moves at all then it would be wise to move the motor away from the switch and then back towards it.

If you want more help please post the code that represents your best attempt and tell us exactly what happens when you run it and what you want it to do that is different.

...R
Stepper Motor Basics
Simple Stepper Code

I got a code from one of my friend This is the code

#include <Servo.h>
Servo servo;
const int stepPin_X = 3;
const int dirPin_X = 4;
const int Enable_X = 7;
const int Enable_Z = 8;
const int stepPin_Z = 13;
const int dirPin_Z = 6;
const int Start_pin = 12;
const int green_led = 2;
const int red_led = 1;

const int limit_X = 9;//need GND to active
const int limit_Z = 10;//need GND to active
bool lim_X;
bool lim_Z;
int x;
int start;

void setup() {
 // Sets the two pins as Outputs
 pinMode(stepPin_X, OUTPUT);
 pinMode(dirPin_X, OUTPUT);
 pinMode(stepPin_Z, OUTPUT);
 pinMode(dirPin_Z, OUTPUT);
 pinMode(limit_X, INPUT_PULLUP);
 pinMode(limit_Z, INPUT_PULLUP);
 pinMode(Start_pin, INPUT_PULLUP);
 pinMode(Enable_X, OUTPUT);
 pinMode(Enable_Z, OUTPUT);
 pinMode(green_led, OUTPUT);
 pinMode(red_led, OUTPUT);
 servo.attach(11);
 Serial.begin(9600);
servo.write(50);
 x = 0;
}
void loop() {

 lim_X = digitalRead(limit_X);
 lim_Z = digitalRead(limit_Z);

 if (lim_X == 1) {
   stepper(1, 1);
 } else if (lim_X == 0) {
   stepper(1, 2);
 }
 if (lim_Z == 1) {
   stepper(0, 1);
 } else if (lim_Z == 0) {
   stepper(0, 2);
 }
 if (lim_X == 0 && lim_Z == 0) {
   Serial.print("--X&Z limit");
   stepper(1, 0);
   stepper(0, 0);
   operate();
 }



}
void operate() {
 while (1) {
   stepper(1, 2);
   stepper(0, 2);
   Serial.println("press_start");
   digitalWrite(red_led,LOW);
   start = digitalRead(Start_pin);
   digitalWrite(green_led,HIGH);
   if (start == 0) {
     for (int i = 0; i < 500; i++) {
       stepper(0, 0);
     }
     for (int j = 0; j < 1000; j++) {
       stepper(1, 0);
     }
     for (int k = 0; k < 500; k++) {
       stepper(0, 1);
     }
     servo.write(5);
     for (int l = 0; l < 1000; l++) {
       stepper(1, 1);
     }
     servo.write(50);
   } 

 }
}
/*
  stpr 1=x, 0=z
  dir 1=high,0=low,2= no_rotate


*/
void stepper(int stpr, int dir) {

 int stepPin;
 int direc;
 if (stpr == 0) {
   direc = dirPin_X;
   digitalWrite(green_led,LOW);
   digitalWrite(Enable_X, LOW);
   digitalWrite(red_led,HIGH);
   stepPin = stepPin_X;
   Serial.println("x_on");
 } else if (stpr == 1) {
   direc = dirPin_Z;
   stepPin = stepPin_Z;
   digitalWrite(green_led,LOW);
   digitalWrite(Enable_Z, LOW);
   digitalWrite(red_led,HIGH);
   Serial.println("z_on");

 } else {
   return;
 }
 if (dir == 1) {
   digitalWrite(direc, HIGH);
   digitalWrite(stepPin, HIGH);
   delayMicroseconds(500);
   digitalWrite(stepPin, LOW);
   delayMicroseconds(500);

 } else if (dir == 0) {
   digitalWrite(direc, LOW);
   digitalWrite(stepPin, HIGH);
   delayMicroseconds(500);
   digitalWrite(stepPin, LOW);
   delayMicroseconds(500);
 } else if (dir == 2) {
   digitalWrite(direc, LOW);
   digitalWrite(stepPin, HIGH);
   Serial.print("stop");
 }
}

but the problem is z , x steppers dont stop even they hit limit switches. they just keep running .

and also the led indicaters dont work properly.

where could be the problem ?

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

Also please use the AutoFormat tool to indent your code for easier reading.

...R

It looks like 1=X and 0=Z got swapped in the middle there. That is why magic numbers like 0 and 1 are bad.

Thank you guys for helping me on this. im new to this forum and sorry for mistakes i made.

**Now the limit switches work as i wanted, but led indicator problem remains. Red led always stay on even after the homing process. Green led works fine but its brightness is very low. where could be the problem ? **

this is the final code i have right now

#include <Servo.h>
Servo servo;
const int stepPin_X = 3;
const int dirPin_X = 4;
const int Enable_X = 7;
const int Enable_Z = 8;
const int stepPin_Z = 5;
const int dirPin_Z = 6;
const int Start_pin = 12;
const int green_led = 2;
const int red_led = 1;

const int limit_X = 9;//need GND to active
const int limit_Z = 10;//need GND to active
bool lim_X;
bool lim_Z;
int x;
int start;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin_X, OUTPUT);
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepPin_Z, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(limit_X, INPUT_PULLUP);
  pinMode(limit_Z, INPUT_PULLUP);
  pinMode(Start_pin, INPUT_PULLUP);
  pinMode(Enable_X, OUTPUT);
  pinMode(Enable_Z, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(red_led, OUTPUT);
  servo.attach(11);
  Serial.begin(9600);
servo.write(50);
  x = 0;
}
void loop() {

  lim_X = digitalRead(limit_X);
  lim_Z = digitalRead(limit_Z);

  if (lim_X == 1) {
    stepper(1, 1);
  } else if (lim_X == 0) {
    stepper(1, 2);
  }
  if (lim_Z == 1) {
    stepper(0, 1);
  } else if (lim_Z == 0) {
    stepper(0, 2);
  }
  if (lim_X == 0 && lim_Z == 0) {
    Serial.print("--X&Z limit");
    stepper(1, 0);
    stepper(0, 0);
    operate();
  }



}
void operate() {
  while (1) {
    stepper(1, 2);
    stepper(0, 2);
    Serial.println("press_start");
    digitalWrite(red_led,LOW);
    start = digitalRead(Start_pin);
    digitalWrite(green_led,HIGH);
    if (start == 0) {
      for (int i = 0; i < 500; i++) {
        stepper(0, 0);
      }
      for (int j = 0; j < 1000; j++) {
        stepper(1, 0);
      }
      for (int k = 0; k < 500; k++) {
        stepper(0, 1);
      }
      servo.write(5);
      for (int l = 0; l < 1000; l++) {
        stepper(1, 1);
      }
      servo.write(50);
    } 

  }
}
/*
   stpr 1=x, 0=z
   dir 1=high,0=low,2= no_rotate


*/
void stepper(int stpr, int dir) {

  int stepPin;
  int direc;
  if (stpr == 0) {
    direc = dirPin_X;
    digitalWrite(green_led,LOW);
    digitalWrite(Enable_X, LOW);
    digitalWrite(red_led,HIGH);
    stepPin = stepPin_X;
    Serial.println("x_on");
  } else if (stpr == 1) {
    direc = dirPin_Z;
    stepPin = stepPin_Z;
    digitalWrite(green_led,LOW);
    digitalWrite(Enable_Z, LOW);
    digitalWrite(red_led,HIGH);
    Serial.println("z_on");

  } else {
    return;
  }
  if (dir == 1) {
    digitalWrite(direc, HIGH);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);

  } else if (dir == 0) {
    digitalWrite(direc, LOW);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);
  } else if (dir == 2) {
    digitalWrite(direc, LOW);
    digitalWrite(stepPin, HIGH);
    Serial.print("stop");
  }
}

jay5050:
Now the limit switches work as i wanted, but led indicator problem remains. Red led always stay on even after the homing process. Green led works fine but its brightness is very low. where could be the problem ?

Why have you connected your red LED to one of the Serial pins?

What proportion of the time is the green LED on?

...R

Hello there , now the LED things are also fine.

**But the problem is i cannot speed up the process, i try to change the delay between steps but the motors rotate same speed. i tested steppers using normal code and with 500 microseconds delay it works fine but when using below code,even 500 microsecond delay , its really slow. so the problem could be in program. what am i missing ????? :frowning: **

#include <Servo.h>
Servo servo;
const int stepPin_X = 5;
const int dirPin_X = 6;
const int Enable_X = 7;
const int Enable_Z = 8;
const int stepPin_Z = 3;
const int dirPin_Z = 4;
const int Start_pin = 12;
const int green_led = A0;
const int red_led = A1;
int t =1000;
const int limit_X = 9;//need GND to active
const int limit_Z = 10;//need GND to active
bool lim_X;
bool lim_Z;
int x;
int start;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin_X, OUTPUT);
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepPin_Z, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(limit_X, INPUT_PULLUP);
  pinMode(limit_Z, INPUT_PULLUP);
  pinMode(Start_pin, INPUT_PULLUP);
  pinMode(Enable_X, OUTPUT);
  pinMode(Enable_Z, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(red_led, OUTPUT);
  servo.attach(11);
  Serial.begin(9600);
  servo.write(50);
  x = 0;
}
void loop() {

  lim_X = digitalRead(limit_X);
  lim_Z = digitalRead(limit_Z);

  if (lim_X == 1) {
    stepper(1, 1);
  } else if (lim_X == 0) {
    stepper(1, 2);
  }
  if (lim_Z == 1) {
    stepper(0, 1);
  } else if (lim_Z == 0) {
    stepper(0, 2);
  }
  if (lim_X == 0 && lim_Z == 0) {
    Serial.print("--X&Z limit");
    stepper(1, 0);
    stepper(0, 0);
    operate();
  }



}
void operate() {
  while (1) {
    stepper(1, 2);
    stepper(0, 2);
    Serial.println("press_start");
    analogWrite(red_led, 0);
    start = digitalRead(Start_pin);
    analogWrite(green_led, 255);
    if (start == 0) {
      for (int i = 0; i < 500; i++) {
        stepper(0, 0);
      }
      for (int j = 0; j < 1000; j++) {
        stepper(1, 0);
      }
      for (int k = 0; k < 500; k++) {
        stepper(0, 1);
      }
      servo.write(5);
      for (int l = 0; l < 1000; l++) {
        stepper(1, 1);
      }
      servo.write(50);
    }

  }
}
/*
   stpr 1=x, 0=z
   dir 1=high,0=low,2= no_rotate


*/
void stepper(int stpr, int dir) {

  int stepPin;
  int direc;
  if (stpr == 0) {
    direc = dirPin_X;
  digitalWrite(Enable_X, LOW);
    stepPin = stepPin_X;
    Serial.println("x_on");
  } else if (stpr == 1) {
    direc = dirPin_Z;
    stepPin = stepPin_Z;
 digitalWrite(Enable_Z, LOW);
    Serial.println("z_on");

  } else {
    return;
  }
  if (dir == 1) {
    digitalWrite(direc, HIGH);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(t);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(t);
    analogWrite(green_led, 0);
    analogWrite(red_led, 255);

  } else if (dir == 0) {
    digitalWrite(direc, LOW);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(t);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(t);
    analogWrite(green_led, 0);
    analogWrite(red_led, 255);
  } else if (dir == 2) {
    digitalWrite(direc, LOW);
    digitalWrite(stepPin, HIGH);
    Serial.print("stop");
  }
}

jay5050:
i tested steppers using normal code and with 500 microseconds delay it works fine

Please post the "normal code" so we can compare it.

...R

By normal i mean a code like this

int direc2 = 4;
int steps2 =3;
int t =500;

void setup() {
  
  pinMode(direc2,OUTPUT); 
  pinMode(steps2,OUTPUT);

}

void loop() {
  
digitalWrite(direc2,HIGH);
  for(int x = 0; x < 500; x++) {
    digitalWrite(steps2,HIGH); 
    delayMicroseconds(t); 
    digitalWrite(steps2,LOW); 
    delayMicroseconds(t);} 
    
    delay(1000); 

    digitalWrite(direc2,LOW);
  for(int x = 0; x < 500; x++) {
    digitalWrite(steps2,HIGH); 
    delayMicroseconds(t); 
    digitalWrite(steps2,LOW); 
    delayMicroseconds(t); 
  }
 delay(1000); 

}

i want to achieve this much speed but when um using that code with led indicators ,even 500 microseconds delay it doesnt rotate the speed like on this above code

This the speed i required (above code with 500 microsecond delay)

this is the speed with that led indicators code(500 microseconds delay)

I suspect the problem is your use of delayMicroseconds() which blocks the Arduino until it completes and does not allow the time for other actions to be interleaved with the steps.

With your code the shortest step interval is the total time taken by this block of code

   if (dir == 1) {
        digitalWrite(direc, HIGH);
        
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(t);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(t);
        
        analogWrite(green_led, 0);
        analogWrite(red_led, 255);

    }

Also I strongly recommend that you separate the pulse width (i.e. the time that digitalWrite(stepPin, HIGH); lasts) from the interval between steps which is what determines the speed. The pulse width should be fixed and about 10µsecs is usually enough. In many cases the time taken by digitalWrite() is sufficient.

Have a look the second example in this Simple Stepper Code

...R

PS ... don't use single letter names for variables except in a FOR loop as they are impossible to identify when you try to search for all occurrences of them.