Go Down

Topic: Increase Steppe motor speed (Read 2285 times) previous topic - next topic

Armindo

Oct 21, 2017, 03:29 pm Last Edit: Oct 21, 2017, 04:20 pm by Armindo
Hi I am newbie on stepper motors so I need a little of help…

What I have:
Stepper Motor:  Wantai WT57STH115-4204A with 4.2A(U) and 1.8deg/step --> 200 steps
Datasheet here:
http://euro.gr/products/russia-warehouse-ship-4-pcs-nema-23-wantai-stepper-motor-425oz-in4-2a-wt57sth115-4204a-4-pcs-dq542ma-drivers/

Driver: HY-DIV268N-5A
Datasheet here:
http://wiki.kreitek.org/_media/proyectos:cnc:div268n-5a-datasheet.pdf
 Arduino Mega2560
Power Supply 350 W 36 V S-350-36

Arduino-Driver connections

The Dir-  is connected to Pull-
Pull+ -->  pin 4
Dir+ -->  pin 5

Step motor-driver connections

Blue --> B-
Pink --> B+
Green --> A-
Black --> A+




I am using a simple code like this to test some motors (similar to this: http://forum.arduino.cc/index.php?topic=454293.0):

Code: [Select]
byte stepPin = 2;
byte directionPin = 3;

int numberOfSteps = 1000; // number of steps
int pulseWidthMicros = 1;  // microseconds
int millisbetweenSteps = 1; // milliseconds

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting StepperTest");
  delay(2000);
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
 
  digitalWrite(directionPin, HIGH);
  for(int n = 0; n < numberOfSteps; n++)
  {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros); // this line is probably unnecessary
    digitalWrite(stepPin, LOW);
    delay(millisbetweenSteps);
  }
}


1) But I cant get enough speed. The AccelStepper seems to give more speed and I cant understand why (the library is more optimized?). I am missing something  here? I don't want to use the AccelStepper library there is any other way to get more speed changing the code above?
With the motor above I get 200 steps (i.e. 1.8/360) per revolution this means that I get 200 steps per second? Or this will depend of other conditions?
2) What calculations should I perform to understand what would be the better timing for the delayMicroseconds or delay? Or this is trial an error?

3) To optimize speed should I use microstepping? Like 1/8 or 1/16?
I tried but I didn't see  any difference.

Any help would be apreciated.

Lorenzogrosso06

try this code



int bluePin = 2;    //IN1 on the ULN2003 Board, BLUE end of the Blue/Yellow motor coil
int pinkPin = 3;    //IN2 on the ULN2003 Board, PINK end of the Pink/Orange motor coil
int yellowPin = 4;  //IN3 on the ULN2003 Board, YELLOW end of the Blue/Yellow motor coil
int orangePin = 5;  //IN4 on the ULN2003 Board, ORANGE end of the Pink/Orange motor coil

//Keeps track of the current step.
//We'll use a zero based index.
int currentStep = 0;





void setup() {
   
   
  Serial.begin(9600); 
 
  // put your setup code here, to run once:
 
 
  pinMode(bluePin, OUTPUT);
  pinMode(pinkPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(orangePin,OUTPUT);
 
  digitalWrite(bluePin, LOW);
  digitalWrite(pinkPin, LOW);
  digitalWrite(yellowPin, LOW);
  digitalWrite(orangePin, LOW);
}

void loop() {
 
  // print out values
 
  //Comment out the Serial prints to speed things up
  //Serial.print("Step: ");
  //Serial.println(currentStep);
 
  switch(currentStep){
    case 0:
      digitalWrite(bluePin, HIGH);
      digitalWrite(pinkPin, LOW);
      digitalWrite(yellowPin, LOW);
      digitalWrite(orangePin, LOW);
      break;
 
    case 1:
      digitalWrite(bluePin, LOW);
      digitalWrite(pinkPin, HIGH);
      digitalWrite(yellowPin, LOW);
      digitalWrite(orangePin, LOW);
      break;
 
    case 2:
      digitalWrite(bluePin, LOW);
      digitalWrite(pinkPin, LOW);
      digitalWrite(yellowPin, HIGH);
      digitalWrite(orangePin, LOW);
      break;
 
    case 3:
      digitalWrite(bluePin, LOW);
      digitalWrite(pinkPin, LOW);
      digitalWrite(yellowPin, LOW);
      digitalWrite(orangePin, HIGH);
      break;
 
  }

   currentStep = (++currentStep < 4) ? currentStep : 0;
 
  //2000 microseconds, or 2 milliseconds seems to be
  //about the shortest delay that is usable.  Anything
  //lower and the motor starts to freeze.
  //delayMicroseconds(2250);
  delay(2);
}

Armindo

#2
Oct 21, 2017, 03:55 pm Last Edit: Oct 21, 2017, 04:20 pm by Armindo

Can you explain what do you mean with that code? Particularly the meaning of the colours?



Robin2

try this code

DO NOT TRY THAT CODE - it is for an entirely different type of stepper motor driver.

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

AWOL

Did you try shortening the one millisecond delay in the original code?

Robin2

#5
Oct 21, 2017, 04:51 pm Last Edit: Oct 21, 2017, 04:55 pm by Robin2
1) But I cant get enough speed.
The code you have posted should be giving you about 1000 steps per second. With a 200 step motor that should be 5 revolutions per second.

What is the max number of steps per second you are actually getting without missing any steps?

How many steps per second do you want to achieve?

If you want the same number of revs per second with microstepping you will need a higher step rate. You could try changing millisBetweenSteps to microsBetweenSteps and a value of 1000 would be the equivalent of 1 millisec. Then use delayMicroseconds(microsBetweenSteps). That would allow you to have sub-millisecond intervals - but don't make the interval too short.

However, for high speeds you usually need to start the motor slowly and accelerate to the required speed and my simple code was not written for that. It is only intended to illustrate simple control principles. It would not be difficult to modify the coe to reduce the interval over, say, 50 steps from a slow rate the the desired maximum rate. And you also need to decelerate the motor to a stop.

Stepper motors often work better under load as the load can damp out resonances.

If my simple code (or a variation of it) is suitable for your needs then I suggest you use the second example as it does not use delay() which blocks the Arduino from doing other things. Simple Stepper Code

I am assuming that you have correctly adjusted the stepper driver to provide the current required by the motor.

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

Armindo

Thank you very much for the help.

Quote
What is the max number of steps per second you are actually getting without missing any steps?
Right now I am simply looking for the speed in the motors.
How can I test this? 

Quote
What is the max number of steps per second you are actually getting without missing any steps?
I am finishing the structure part and only after I will be able to test and see what I will really need. At the first look at least one motor should need more speed but I don't know how much more. Basically, I am trying to understand the better approach so When i have the structure ready I know what to do.


Robin2 Can you give an example, how you would incorporate this second part of code (http://forum.arduino.cc/index.php?topic=277692.0) into this code (I am using code similar to this functions  recvWithStartEndMarkers() and parseData() ): http://forum.arduino.cc/index.php?topic=288234.0

I am controlling the motors from C# trough serial port and for that I am using those functions.

Robin2

#7
Oct 21, 2017, 06:34 pm Last Edit: Oct 21, 2017, 06:37 pm by Robin2
Robin2 Can you give an example, how you would incorporate this second part of code (http://forum.arduino.cc/index.php?topic=277692.0) into this code (I am using code similar to this functions  recvWithStartEndMarkers() and parseData() ): http://forum.arduino.cc/index.php?topic=288234.0
It will be much easier to help if you make an attempt at what you require and post your code if it does not do what you want.

If you want to experiment with simple acceleration you might like to try this program
Code: [Select]
// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses micros() to manage timing to allow high step rates to be tested
// and illustrates a simple method for accleration and deceleration

byte directionPin = 9;
byte stepPin = 8;

unsigned long curMicros;
unsigned long prevStepMicros = 0;
unsigned long slowMicrosBetweenSteps = 6000; // microseconds
unsigned long fastMicrosBetweenSteps = 1500;
unsigned long stepIntervalMicros;
unsigned long stepAdjustmentMicros;
int numAccelSteps = 100; // 100 is a half turn of a 200 step mmotor
int numSteps = 1000;
int stepsToGo;
byte direction = 1;

void setup() {

    Serial.begin(115200);
    Serial.println("Starting Stepper Demo with acceleration");

    pinMode(directionPin, OUTPUT);
    pinMode(stepPin, OUTPUT);

    stepAdjustmentMicros = (slowMicrosBetweenSteps - fastMicrosBetweenSteps) / numAccelSteps;
    stepIntervalMicros = slowMicrosBetweenSteps;
    stepsToGo = numSteps;
    digitalWrite(directionPin, direction);
}

void loop() {

    moveMotor();

}

void moveMotor() {
    if (stepsToGo > 0) {
        if (micros() - prevStepMicros >= stepIntervalMicros) {
            prevStepMicros += stepIntervalMicros;
            singleStep();
            stepsToGo --;
            if (stepsToGo <= numAccelSteps) {
                if (stepIntervalMicros < slowMicrosBetweenSteps) {
                    stepIntervalMicros += stepAdjustmentMicros;
                }
            }
            else {
                if (stepIntervalMicros > fastMicrosBetweenSteps) {
                    stepIntervalMicros -= stepAdjustmentMicros;
                }
            }
        }
    }
    else {
        direction = ! direction;
        digitalWrite(directionPin, direction);
            // next two lines just for the demo
        delay(2000);
        Serial.println("Changing direction");
        stepsToGo = numSteps;
        prevStepMicros = micros();
    }
}

void singleStep() {

    digitalWrite(stepPin, HIGH);
    digitalWrite(stepPin, LOW);

}


...R

PS please post your program using the code button </> so it looks like the above. See How to use the Forum

Also please use the AutoFormat tool in the IDE to indent the code properly as that makes it much easier to read.

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

Armindo

Hi


Below is an example of the code that I am testing. Any suggestions to improve the code would be welcome.

I am using microstepping 1/4.

Insted of the user define the "MillisBetweenSteps" and/or "MicrosBetweenSteps" Can I use revolutions per second and than convert that to MillisBetweenSteps? If so what would be the better way to do that?


How should I implement the End limit switch at the beginning when the equipment is turned on?


As as previously asked how can I improve speed?


Code: [Select]


const byte numChars = 32;
char receivedChars[numChars]="<P00206000U00701580022023>"; // just for test purposes
 // P002 = PinStep = 2;
 // 06000 = NumbOfSteps = 6000
 // Direction = Dir = (U=HIGH or D=LOW);
 // Direction Pin= PinDir = 007;
 // 0158 = MillisBetweenSteps= 158;
 // EndLimitRight = 022;
 // EndLimitLeft= 023;           
           
int MicrosBetweenSteps = 1;  // microseconds  (just for test probably will be added to receivedChars variabel)

boolean newData = true;

void setup() {

  // Steps
  pinMode(2, OUTPUT);  // Step of Nema1
  pinMode(4, OUTPUT);  // Step of Nema2
  pinMode(6, OUTPUT);  // Step of Nema3
  pinMode(8, OUTPUT);  // Step of Nema4
  pinMode(10, OUTPUT); // Step of Nema5
 
  // Direction
  pinMode(3, OUTPUT);  // Direction of Nema1
  pinMode(5, OUTPUT);  // Direction of Nema2
  pinMode(7, OUTPUT);  // Direction of Nema3
  pinMode(9, OUTPUT);  // Direction of Nema4
  pinMode(11, OUTPUT); // Direction of Nema5

 // EndLimitRight and EndLimitLeft
  pinMode(22, INPUT); // Pin Up   of the end switch
  pinMode(23, INPUT); // Pin Down of the end switch

    Serial.begin(115200);
    Serial.println("<Arduino is ready>");

}

void loop() {
    RecvData();

  if (newData == true)
  {
    parseData();
    newData = false;
  }

}

void RecvData()
{
  // function recvWithStartEndMarkers by Robin2 of the Arduino forums
  // See  http://forum.arduino.cc/index.php?topic=288234.0

  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

// original code like this:
//  while (Serial.available() > 0 && newData == false) {
//    rc = Serial.read();

// only for demostration purposes
//----------------------------------
  for (int n = 0; n < sizeof(receivedChars); n++)
  {
   rc = receivedChars[n];
//----------------------------------

   

      if (recvInProgress == true) {
        if (rc != endMarker) {
          receivedChars[ndx] = rc;
          ndx++;
          if (ndx >= numChars) {
            ndx = numChars - 1;
          }
        }
        else {
          receivedChars[ndx] = '\0'; // terminate the string
          recvInProgress = false;
          ndx = 0;
          newData = true;
        }
      }
 
      else if (rc == startMarker) {
        recvInProgress = true;
      }
    }




}

void parseData()
{

  if (receivedChars[0] == 'P'  )  // control the motors
  {
    byte PinStep     = convertToNumber(1, 3); // get the step motor Pin
    int NumbOfSteps  = convertToNumber(4, 5); // get the number of steps
    int Dir;
    if ( receivedChars[9] == 'U') {
      Dir = HIGH; // direction
    }
    if ( receivedChars[9] == 'D') {
      Dir = LOW; // direction
    }
    byte PinDir             = convertToNumber(10, 3); // get the direcion motor Pin
    int  MillisBetweenSteps = convertToNumber(13, 4); // MillisBetweenSteps
    byte EndLimitRight      = convertToNumber(17, 3); // get the end limit Top Pin
    byte EndLimitLeft       = convertToNumber(20, 3); // get the end limit Bottom Pin

    RunMotor (PinDir, Dir, NumbOfSteps, PinStep, MillisBetweenSteps, EndLimitRight, EndLimitLeft);
    Message(PinStep, PinDir, Dir, NumbOfSteps,  MillisBetweenSteps, EndLimitRight, EndLimitLeft);


  }

}


void RunMotor (byte PinDir, int Dir, int NumbOfSteps, byte PinStep, int MillisBetweenSteps, byte EndLimitRight, byte EndLimitLeft)
{


  digitalWrite(PinDir, Dir); // define the direction of rotation (up=anti-clockwise  or down=clockwise )
 
  for (int n = 0; n < NumbOfSteps; n++)
  {
    if (digitalRead(EndLimitRight) == 0 & digitalRead(EndLimitLeft) == 0) // if EndLimits not active
    {
    digitalWrite(PinStep, HIGH);
    delayMicroseconds(MicrosBetweenSteps); // this line is probably unnecessary
    digitalWrite(PinStep, LOW);
    delayMicroseconds(MillisBetweenSteps);
   
    }
   else
   {
    break;
   }
  }


}


void Message(byte PinStep, byte PinDir, int Dir, int NumbOfSteps,  int MillisBetweenSteps, byte EndLimitRight, byte EndLimitLeft)
{
  String Str;

  Serial.print("PinStep = "); Serial.println(PinStep);
  Serial.print("PinDir = "); Serial.println(PinDir);
  if (Dir == 1) Str = "UP"; else Str = "Down";
  Serial.print("Direction = "); Serial.println(Str);
  Serial.print("NumbOfSteps = "); Serial.println(NumbOfSteps);
  Serial.print("PinEndLimitRight = "); Serial.println(EndLimitRight);
  Serial.print("PinEndLimitLeft = "); Serial.println(EndLimitLeft);
  Serial.println("------------------------------------");

}


// this should be possible to do in a much better way...

int convertToNumber( byte startPos, byte Numb)
{
  unsigned int tmp = 0;

  if (Numb == 5  ) // if 5
  {
    tmp = (receivedChars[startPos] - 48) * 10000;
    tmp = tmp + (receivedChars[startPos + 1] - 48) * 1000;
    tmp = tmp + (receivedChars[startPos + 2] - 48) * 100;
    tmp = tmp + (receivedChars[startPos + 3] - 48) * 10;
    tmp = tmp + receivedChars[startPos + 4] - 48;
  }

  else if (Numb == 4) // if 4
  {
    tmp = (receivedChars[startPos] - 48) * 1000;
    tmp = tmp + (receivedChars[startPos + 1] - 48) * 100;
    tmp = tmp + (receivedChars[startPos + 2] - 48) * 10;
    tmp = tmp + receivedChars[startPos + 3] - 48;
  }

  // if 3 digits
  else if (Numb == 3) // if 3
  {
    tmp = (receivedChars[startPos] - 48) * 100;
    tmp = tmp + (receivedChars[startPos + 1] - 48) * 10;
    tmp = tmp + receivedChars[startPos + 2] - 48;
  }

  return tmp;
}



Than you in advance for any help.

AWOL

Code: [Select]
     delayMicroseconds(MicrosBetweenSteps); // this line is probably unnecessary
...
delayMicroseconds(MillisBetweenSteps);
 

Millis or micros?
Confused.

Robin2

As as previously asked how can I improve speed?
As previously asked in Reply #5
Quote
What is the max number of steps per second you are actually getting without missing any steps?
...R
Two or three hours spent thinking and reading documentation solves most programming problems.

PaulS

Quote
Insted of the user define the "MillisBetweenSteps" and/or "MicrosBetweenSteps" Can I use revolutions per second and than convert that to MillisBetweenSteps?
Yes.

Quote
If so what would be the better way to do that?
Division.
The art of getting good answers lies in asking good questions.

Armindo

#12
Oct 31, 2017, 03:38 pm Last Edit: Oct 31, 2017, 03:45 pm by Armindo
 
Code: [Select]
     delayMicroseconds(MicrosBetweenSteps); // this line is probably unnecessary
...
delayMicroseconds(MillisBetweenSteps);
 

Millis or micros?
Confused.
Yes you are right. I made some changes to the code and that missed me.


What is the max number of steps per second you are actually getting without missing any steps?
How can I test this? Is there an easy way to test it? Or do I have to record the movement of the motor with a camera for instance?


Armindo

I used this site below to calculate the Maximum speed. Considering a full step i.e. 200 Steps/ revolution (360/1.8):

https://www.allaboutcircuits.com/tools/stepper-motor-calculator/


Maximum Speed:     0.592 revolutions/sec

Minimum Time/Step: 8.44 ms

Maximum Power: 15.9 Watts


considering microstepping like 1/4 I will have 800 Steps/revolution in this case I will get:

Maximum Speed:    0.148 revolutions/sec

Minimum Time/Step: 8.44 ms

Maximum Power:     15.9 Watts

If this is ok (I dont know if I will be missing any steps) what would be the best default values for MicrosBetweenSteps and MillisBetweenSteps to get the higher velocity? Can you help me understand how I can calculate these values?




Robin2

I used this site below to calculate the Maximum speed.
Never mind calculating the maximum speed.

Tell us how fast your stepper motor is actually operating and post the program that produces that performance.

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

Go Up