Stepper cannot be controlled by pwm_lib but digitalWrite can it. Why?

I would like to control speed of some steppers.
So I prepare below equipment.

  • Arduino Due
  • TB6600 Stepper controler
    amazon.co.jp/gp/product/B06XSBB45M
  • Nema 23 Stepper
    amazon.co.jp/gp/product/B07HQ77RWG

First I tried below code. It can rotate motor.

int PUL=35; //define Pulse pin
int DIR=33; //define Direction pin
int ENA=31; //define Enable Pin
void setup() {
  pinMode (PUL, OUTPUT);
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);

}

void loop() {
  for (int i=0; i<6400; i++)    //Forward 5000 steps
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
  for (int i=0; i<6400; i++)   //Backward 5000 steps
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
}

To control speed, I must change frequency.
So I use below library because I can change frequency easily.

I have written code that works the same as the above code.

#include "pwm_lib.h"

using namespace arduino_due::pwm_lib;

#define PWM_PERIOD_PIN_35 10000000 // hundredth of usecs (1e-8 secs)
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;

int PUL=35; //define Pulse pin
int DIR=33; //define Direction pin
int ENA=31; //define Enable Pin

void setup() {
  // put your setup code here, to run once:
  pinMode (PUL, OUTPUT);
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);
  
//  pwm_pin35.start(PWM_PERIOD_PIN_35,PWM_DUTY_PIN_35);
}

void loop() {
  // put your main code here,to run repeatedly:
  for (int i=0; i<6400; i++)    //Forward 5000 steps
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
  for (int i=0; i<6400; i++)   //Backward 5000 steps
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }
}

When measured with an oscilloscope, the two programs output similar signals. However, the one using pwm_lib did not work.

Why I cannot control stepper by pwm?
Or can I control by other library?

Thanks.

Please show the line in the code where you using the PWM in the second sketch?

As far I see you still using digitalWrite() for PUL pin so the result of work will be same as for first code.

I don't think that you need the PWM and moreover, I dont think that the PWM will help you.
Let's see the code:

First - it is absolutely senseless to write HIGH to the DIR and ENA pins at the EVERY run of the loop. Move this lines outside the for cycle:

 digitalWrite(DIR,HIGH);
 digitalWrite(ENA,HIGH);
for (int i=0; i<6400; i++)   //Backward 5000 steps
  {
    digitalWrite(PUL,HIGH);
    delayMicroseconds(50);
    digitalWrite(PUL,LOW);
    delayMicroseconds(50);
  }

and now - to change the frequency the only thing what you need - increase or decrease the delay in the 2nd and 4th lines of the loop. Replace the hardcoded value to the variable and you can to regulate the speed of the motor:

ubsigned int step_interval = 50;
digitalWrite(DIR,HIGH);
digitalWrite(ENA,HIGH);
for (int i=0; i<6400; i++)   //Backward 5000 steps
 {
   digitalWrite(PUL,HIGH);
   delayMicroseconds(step_interval);
   digitalWrite(PUL,LOW);
   delayMicroseconds(step_interval);
 }

Sorry. I post wrong code for debug.
below is current.

#include "pwm_lib.h"

using namespace arduino_due::pwm_lib;

#define PWM_PERIOD_PIN_35 10000000 // hundredth of usecs (1e-8 secs)
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;

int DIR=33; //define Direction pin
int ENA=31; //define Enable Pin

void setup() {
  // put your setup code here, to run once:
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);
  
  // starting PWM signals
  pwm_pin35.start(PWM_PERIOD_PIN_35,(PWM_PERIOD_PIN_35>>1));
}

void loop() {
  // put your main code here,to run repeatedly:
  for (int i=0; i<6400; i++)    //Forward 5000 steps
  {
    digitalWrite(DIR,LOW);
    digitalWrite(ENA,HIGH);
    delayMicroseconds(50);
    delayMicroseconds(50);
  }
  for (int i=0; i<6400; i++)   //Backward 5000 steps
  {
    digitalWrite(DIR,HIGH);
    digitalWrite(ENA,HIGH);
    delayMicroseconds(50);
    delayMicroseconds(50);
  }
}

PWM is enabled by below line.

  pwm_pin35.start(PWM_PERIOD_PIN_35,(PWM_PERIOD_PIN_35>>1));

About of your revised code in the post #4 - your PWM period is 10 millions of usecs = 10 secs. What do you expected to view with such PWM?

And read post 3 - I think you don't need pvm at all, with pwm it will be difficult to run the motor the exact number of steps

I don't think that you need the PWM and moreover, I dont think that the PWM will help you.

In order to control multiple steppers, we think it would be preferable to use pwm or timer to control them, instead of writing the control in a loop function.

About of your revised code in the post #4 - your PWM period is 10 millions of usecs = 10 secs. What do you expected to view with such PWM?

I too wonder, but the time specified in this library is not usec, but hundredth of usecs, so the above code works in 100ms cycles.

Ok, but can you explain the purpose of this loop if you are using the PWM?

as I said before you dont need repeatedly put HIGH to the DIR and ENA pins. Now remove this lines from the loop - and what will be left? Thousands of delays?

To use PWM you must do the following

  • adjust the pvm frequency
  • turn on ENA and DIR pins ( once! )
  • start the PWM and wait for the required number of periods
  • turn off PWM

no cycles for 6400 steps are needed here

The PWM will not control the speed of a stepping motor, so however much you would like to use it to do this you can't.

Controlling the speed of a PWM doesn't affect anything, for example an LED is just as bright no matter what he speed. What controls the brightness of an LED with PWM is the duty cycle, that is the ratio of on to off time which you control with the duty cycle instruction badly named analogWrite function call.

The ONLY way to control a stepping motor is to change the frequency with which you pulse the coils.

That is what the work round above is doing in effect by pulsing the step driver. But you are faced with the bigger problem of counting the PWM pulses and turning it off when you have reached your required number. Which quite frankly is a harder task than doing it correctly.

Thank you for your response.

My final target is to control multi steppers by PC.
So loop function will have the method to purse commands from PC.
This method will take time.
So I had high hopes for the Arduino Due PWM generator.
However, since it is difficult to operate with the PWM generator in the current situation, I would consider writing all the processing in the loop function as you suggest.

Thank you for your response.

I know normal PWM cannot control stepper.
But the Arduino Due PWM generator can control frequency as the repository I posted tell.
I am already on the verge of producing a signal at an arbitrary frequency.
However, I found that I could not control it with the signal generated by the PWM generator, so I used this forum.
If possible, could you please tell me the difference between the signal generated by digitalWrite() and the signal generated by the PWM generator?

You can change the frequency of the PWM on any Arduino, even the UNO. There is nothing special about the Due.

As signals go they are very much the same.

But using the digitalWrite in some code is more flexible than PWM. For example if you want to ramp up to a speed to allow a faster motor movement you can do this with code with digitalWrite where as you can't change smoothly the speed of PWM.

I took your word for it, measured the signal again, and found that I had misunderstood the time units.
Since disitalWrite was running in microseconds, the PWM should have been set as follows.

pwm_pin35.start(10000, (10000>>1));

As a result of the above settings, I got the stepper to work.

Finally, I created a library and got multiple steppers to rotate at a given speed.
This library allows the steppers to rotate at the desired speed, even if there is a significant delay due to communication or other reasons.
The library is now available on GitHub.

I appreciate your support.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.