Go Down

Topic: Stepper Motors simultaneously (Read 90 times) previous topic - next topic

paweljmo

Hi! I tried to move 2 stepper motors simultaneously, but i failed. Code that i wrote looks like this. I uderstand why it doesn't work, but i have no idea how can i improve it. Now, second stepper make 5 rotations, then first stepper make another 5 rotations and it is understandable. I wrote three functions:

takeStep- which generates one step
precisionRotation- where we declare how many step we want to make
setDirection- when we declare direction of rotation

Code: [Select]

#define Dir1 2
#define Axis1 3
#define enable1 4

#define Dir2 5
#define Axis2 6
#define enable2 7


int zStepState = LOW;

unsigned long previousMicros = 0;
const long stepDelay = 50*32;
int steps = 1000;

int stepCount = 0;

void setup()
{
  pinMode(Dir1, OUTPUT);
  pinMode(Axis1, OUTPUT);
  pinMode(enable1, OUTPUT);
  digitalWrite(enable1, LOW);

  pinMode(Dir2, OUTPUT);
  pinMode(Axis2, OUTPUT);
  pinMode(enable2, OUTPUT);
  digitalWrite(enable2, LOW);
 
  Serial.begin(250000);
}

void takeStep(byte stepPin)
{
unsigned long currentMicros = micros();

    if (currentMicros - previousMicros >= stepDelay)
    {
      if (zStepState == LOW)
      {
        zStepState = HIGH;
        stepCount++;
      }

      else
      {
        zStepState = LOW;
      }
     
      digitalWrite(stepPin, zStepState);
      previousMicros = currentMicros;
    } 
}

void precisionRotation(byte stepPin, int angle)
{
  steps = angle/1.8;
 
  for(stepCount == 0; stepCount < steps;)
  {
    takeStep(stepPin);
  }
 
}

void setDirection(byte dirPin, String stringDir)
{
  boolean dir = false;
 
  if(stringDir == "Clockwise")
   {
    dir = false;
   }
   else
    dir = true;
   
  digitalWrite(dirPin,dir);
}
 
void loop()
{
  setDirection(Dir2,"Clockwise");
  precisionRotation(Axis2,5*360);
 
  setDirection(Dir1,"Counterwise");
  precisionRotation(Axis1,10*360);
 
}


I would be grateful for any tips. Dealing with this problem is very important for me, because it is a part of my Engineering Thesis.

blh64

Download the AccelStepper library and use it.  It can run two steppers simultaneously and has example code that demonstrates it.

FYI... this code
Code: [Select]

  for(stepCount == 0; stepCount < steps;)
  {
    takeStep(stepPin);
  }

Is doing a comparison ('==') not initializing stepCount

paweljmo

I was hoping that i will be able deal with it without this library. But thanks i will check it.

Right. I know the diffrence between == and =. Stupid mistakes.

Paul_KD7HB

I was hoping that i will be able deal with it without this library. But thanks i will check it.

Right. I know the diffrence between == and =. Stupid mistakes.
Then, interleave the commands to the steppers so they both get the same command in sequential instructions

Paul

Robin2

I was hoping that i will be able deal with it without this library.
The general approach in your takeStep() function is correct.

The problem is your use of FOR loops to move the motors because a FOR loop blocks until it completes. Just use a variable to keep count of the steps and allow loop() to do the repetition. That way each motor can take a step when it is next due. You will probably want to take the stepCount out of the takeStep() function so you can count the steps separately for each motor.

...R
Stepper Motor Basics
Simple Stepper Code
 
Two or three hours spent thinking and reading documentation solves most programming problems.

paweljmo

#5
May 19, 2019, 12:42 pm Last Edit: May 19, 2019, 03:54 pm by paweljmo
If i delete FOR loop still one motor works. It is because i use the same takestep function for two steppers?
 
Should I write there digitalWrite commands for every steppers instead of using parameters stepPin or maybe even every stepper should have own takeStep function? Because if i understand it well i cannot call takestep() functions again with another arguments if previous doesn't end?

Code without for loop:

Code: [Select]
#define Dir1 2
#define Axis1 3
#define enable1 4

#define Dir2 5
#define Axis2 6
#define enable2 7


int zStepState = LOW;

unsigned long previousMicros = 0;
const long stepDelay = 50*32;
int steps = 1000;

int stepCount = 0;

void setup()
{
  pinMode(Dir1, OUTPUT);
  pinMode(Axis1, OUTPUT);
  pinMode(enable1, OUTPUT);
  digitalWrite(enable1, LOW);

  pinMode(Dir2, OUTPUT);
  pinMode(Axis2, OUTPUT);
  pinMode(enable2, OUTPUT);
  digitalWrite(enable2, LOW);
 
  Serial.begin(250000);
}

void takeStep(byte stepPin)
{
boolean oneStep = false;
unsigned long currentMicros = micros();

    if (currentMicros - previousMicros >= stepDelay)
    {
      if (zStepState == LOW)
      {
        zStepState = HIGH;
      }

      else
      {
        zStepState = LOW;
      }
     
      digitalWrite(stepPin, zStepState);
      previousMicros = currentMicros;
    } 
}

void setDirection(byte dirPin, String stringDir)
{
  boolean dir = false;
 
  if(stringDir == "Clockwise")
   {
    dir = false;
   }
   else
    dir = true;
   
  digitalWrite(dirPin,dir);
}
 
void loop()
{
  setDirection(Dir2,"Clockwise");
  takeStep(Axis2);
 
  setDirection(Dir1,"Counterwise");
  takeStep(Axis1);
 
}


EDIT:

I've read a documentation of AccelStepper Library and made some tests and i really enjoyed how it works. At the beginning i was not convinced to use it but now i think it is great.  Thanks!

Robin2

#6
May 19, 2019, 04:02 pm Last Edit: May 19, 2019, 04:03 pm by Robin2
Simplify your takeStep() function like this
Code: [Select]
void takeStep(byte stepPin)
{
    boolean oneStep = false;
    unsigned long currentMicros = micros();

    if (currentMicros - previousMicros >= stepDelay)
    {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(stepPin, LOW);

        previousMicros = currentMicros;
    }  
}

and then it will not be necessary for the takeStep() function to remember the stepState for the different motors.

You may find it necessary to double the value of stepDelay

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up