Nema 23 + DQ542MA Driver

Hi All,

I’m trying to get a Nema 23 working, unfortunately it currently only vibrates.

Here’s my setup:
Peak: 2.84
RMS: 2.03

Pulse/rev: 400

Power: 24V 14.6A

The wiring is as follows:

Here’s my code:

int stepPin = 5;
int dirPin = 6;
int enblPin = 7;

void setup() {
  pinMode (stepPin, OUTPUT);
  pinMode (dirPin, OUTPUT);
  pinMode (enblPin, OUTPUT);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(enblPin, HIGH);
}

void loop() {
  for (int x = 0; x < 1600; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(200);
    digitalWrite(stepPin, LOW);

  }
  digitalWrite(enblPin, LOW);
  exit(0);
}

Thanks in advance!
Charles

Change:

  for (int x = 0; x < 1600; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(200);
    digitalWrite(stepPin, LOW);

  }

to:

  for (int x = 0; x < 1600; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(stepPin, LOW);
    delay (50);   // Much much slower if you expect a motor to accelerate from stationary
  }

What stepper driver are you using - its rather important part of the setup!

These links may be of interest.
Stepper Motor Basics
Simple Stepper Code

I think I would start with an even longer interval between steps - perhaps 200 millisecs. It is always easy to reduce the interval once you can see that the motor is working.

...R

@MarkT Thanks for your advice, that solved it. Here’s the updated code:

int stepPin = 5;
int dirPin = 6;
int enblPin = 7;

void setup() {
  pinMode (stepPin, OUTPUT);
  pinMode (dirPin, OUTPUT);
  pinMode (enblPin, OUTPUT);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(enblPin, HIGH);
}

void loop() {
  for (int x = 0; x < 400; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(400);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(400);
  }
  digitalWrite(enblPin, LOW);
  exit(0);
}

@Robin2 I checked your tutorials, very helpful - thanks for sharing.

Despite the motor working it’s extremely slow, how can I increase the speed?
Anything below a 400 delay seems to stop the motor.

This seems to be the fastest possible:

 for (int x = 0; x < 1200; x++) {
   digitalWrite(stepPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(stepPin, LOW);
   delayMicroseconds(350);
 }

CharlesTechnologist:
This seems to be the fastest possible:

 for (int x = 0; x < 1200; x++) {

digitalWrite(stepPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(350);
}

If my maths is correct that is about 3000 steps per second which, with a 400 step motor in single-step mode should about 7 revs per second or 420 rpm. Does that sound about right?

For higher speeds you probably need code that accelerates the motor rather than trying to start off at top speed.

What stepper motor driver are you using? Have you set the current limit properly to match your motor?

…R

@Robin2 Your maths is correct.

I’m using the Wantai DQ542MA as a driver which I initially though would be able to handle full-stepping but turns out can only do half.

I’ve tried this which slowly decreases the delay but I’m not having much luck - it stalls just below 350.

  int speed =350;

  for (int x = 0; x < 1600; x++) {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(spee);
    if(x % 10 == 0){
      if(speed > 300) spee--;
    }
  }

You seem to be starting your test with the interval at 350. Try starting with an interval of 1000 and adjust the value in steps of 10. Also leave a longer interval (maybe 1 or 2 revolutions) between speed changes.

As I don't have your hardware I can't replicate your experience and I can't think of anything else to suggest.

IIRC the modulus operator (%) is very slow and may not be appropriate for that sort of code. The way your code is written all the time adds together - so your actual interval is the time for the code plus the time in the delay(). In other words the actual interval is probably longer than you think.

Have a look at how the timing is done in the second example in my Simple Stepper Code. It will make steps at the correct timing regardless of any code in the interval. You can do the same thing with micros().

However I am not suggesting that better code will make the motor move faster.

Have you tried putting a load or a flywheel on the motor?

...R

CharlesTechnologist:
Despite the motor working it's extremely slow, how can I increase the speed?
Anything below a 400 delay seems to stop the motor.

You are not ramping the speed, so its stalling on the instruction to accelerate instantly.

Use AccelStepper library in the first instance, you can set the acceleration and top speed independently.
Large motors have significant inertia and cannot physically accelerate to 2500 steps/second in a mere
0.4ms!

@Robin2 The motor is used on a belt driven linear actuator which only takes 1.5 rotation to travel its full length. Hence why I need a short acceleration distance.

Thanks for your help, by the looks of it Stepper aren’t what I’m looking for.

@MarkT I’m not sure what you mean by not ramping speed?

I’ve tried the following with AccelStepper and the limit seems to be the same - 3000 steps per second

#include <AccelStepper.h>

AccelStepper Xaxis(1, 5, 6); // pin 3 = step, pin 6 = direction

void setup() {
  Xaxis.setMaxSpeed(2500);
  Xaxis.setAcceleration(10);
  Xaxis.setSpeed(2500);
}

void loop() {  
   Xaxis.runSpeed();
}

You are telling the motor to start moving at high speed from a complete standstill with that code.

It naturally fails to keep up and then stalls or judders having completely lost lock.

You have to ramp up the speed if the motor has any chance of keeping up (and ramp down
when stopping too).

The AccelStepper library does this for you so you don't have to code it (which is surprisingly hard
to do).

CharlesTechnologist:
@Robin2 The motor is used on a belt driven linear actuator which only takes 1.5 rotation to travel its full length. Hence why I need a short acceleration distance.

IMHO that probably means that you need a much more powerful motor.

...R

I'm detecting xyproblem again.

Tell us about this linear actuator and its load - all the numbers (force, time, acceleration, mass of load etc)

@Robin2 After some more research it seems I need to go with a DC motor.

@MarkT I've attached some pictures of my current setup, here's also some values as I understand them:

All the parts included in the linear movement weight approximately 400gr.
In the worst case scenario I need them to move 5cm within 30ms, or a speed of 166cm/s.

Given these figures can someone point me in the direction of an appropriate DC motor?


I can't see the pictures All I see are two big red Xs. Is it the same for others?

...R

CharlesTechnologist:
@Robin2 After some more research it seems I need to go with a DC motor.

@MarkT I've attached some pictures of my current setup, here's also some values as I understand them:

All the parts included in the linear movement weight approximately 400gr.
In the worst case scenario I need them to move 5cm within 30ms, or a speed of 166cm/s.

Given these figures can someone point me in the direction of an appropriate DC motor?


0.4kg move 5 cm in 30ms?? You need a huge voice-coil motor, nothing else has a hope.
You need an acceleration of 222m/s/s for that motion, so a force of 90N minimum, 150W minimum...

Lets do the maths:

Accelerate from standstill to Vmax and down to standstill again in 0.03 seconds, ie an
acceleration ramp followed by a deceleration ramp, each being:

s = 0.025m, t = 0.015s. 2 s = a t^2
Thus a = 222,
Vmax = a t = 3.33 m/s
KE at max speed = 0.5 m Vmax^2 = 2.22 J
power to accelerate on average = 2.22 / 0.015 = 148W
force = m a = 90N

I think you neglected to allow for the huge requirements of rapid acceleration - table football
is a real work out, know you know why...