Speed control using code and the DRV8825

Hello all

I have a project where I am controlling 2 stepper motors (SM42HT47-1684B and 17HS1070-C5X with gear box) and driving them using the DRV8825 and arduino uno, using 12V to power the system. I have written code that works great for my application. However, I now need to control the speed. I have tried using many codes on the web and examples to try and understand how to control the speed, but nothing is working for me. I have tried increasing the delay between high and low in the for loop, this does slow the speed but the noise and motor vibration is too high for my use. I am a beginner when it come to writing code, so some help with writing the code on how to control the speed would be greatly appreciated. Please see attached my code. Thank you for your time and help.

// Run a A4998 from an Arduino UNO.
// Applimed R & D, 02.2016
int x; 
#define BAUD (9600)
#include <Stepper.h>

void setup() 
{
  Serial.begin(BAUD);
  pinMode(6,OUTPUT); // Enable (Step motor one (tube length)).
  pinMode(5,OUTPUT); // Step
  pinMode(4,OUTPUT); // Dir
  digitalWrite(6,LOW); // Set Enable low (Step motor two (CAM)).
  pinMode(7,OUTPUT); // Enable2
  pinMode(8,OUTPUT); // Step2
  pinMode(9,OUTPUT); // Dir2
  digitalWrite(7,LOW); // Set Enable low

}

void loop() 
{
  // Step motor one (tube length).
  digitalWrite(6,LOW); // Set Enable low
  digitalWrite(4,LOW); // Set Dir high
  Serial.println("Loop 200 steps (1 rev)");
  for(x = 0; x < 118; x++) // Loop 200 times
  {
    digitalWrite(5,HIGH); // Output high
    delay(1); // Wait
    digitalWrite(5,LOW); // Output low
    delay(1); // Wait
  }
  Serial.println("Pause");
  delay(10); // pause one second

 // Step motor two (CAM).
    digitalWrite(7,LOW); // Set Enable low
  digitalWrite(9,HIGH); // Set Dir high
  Serial.println("Loop 200 steps (1 rev)");
  for(x = 0; x < 1036; x++) // Gear ratio 1 : 5.18. Loop 200 times
  {
    digitalWrite(8,HIGH); // Output step high
    delay(1); // Wait
    digitalWrite(8,LOW); // Output step low
    delay(1); // Wait
  }
  Serial.println("Pause");
  delay(100); // pause one second
}

Hello.

What microstepping mode are you using? The largest benefit of using microstepping is that it can smooth stepper movement at lower speeds. Also, what kind of mechanical load do you have on your motors? What did you set the current limit on the DRV8825 to?

-Nathan

Hi Nathan

Thanks for the tip. You know, I don’t know how to change or set the microstepping mode, so I have no idea but you make a good point. Can you tell me how can I change the microstepping please ?

The mechanical load is about 0.00125Nm. In fact, the reason why I want to slow the speed down is because that some times the motor skips. At first I changed the direct diver motor to one with a gear box (5.18 ratio) and now it is almost working right, so I figured if I slow it down it might take the load better.

For the current limit, I I found that the motor work their best when I turn the potentiometer 90 degrees from point zero. I never did find how to measure the real current.

Here is a pic of my system, it is a tube cutter.

Thanks for your help.

You should set current limit on the stepper driver to be sure it is using a reasonable value that is within the rating of the stepper driver and motor. There is a video on this post on our blog that shows how to set the current limit on your driver.

The microstepping mode of the driver is set by pulling the MODE pins (M0, M1, and M2) on the driver HIGH or LOW. There is a table on the product page for the DRV8825 that lists the pin configurations for different microstepping modes.

-Nathan

Hi Nathan

Thx it is working better now.

However, it is skipping, making A LOT of noise and sometimes just stops working all together.

I did not manage to activate the micro-stepping modes as I am very weak when it comes to writing code. How would one write the code to use the 1/16 step for example ? I just don’t know what to put under the void setup() , void loop() and so on. I found the table and some example code, but it’s just not helping.

Code is below:

// Run a A4998 from an Arduino UNO.
// Mark Vujicic Applimed R & D, 02.2016
int x; 
#define BAUD (9600)
#include <Stepper.h>
#include <Arduino.h>
#include "BasicStepperDriver.h"
#include "DRV8825.h"

// microstep control for DRV8825
// same pinout as A4988, different pin names, supports 32 microsteps
 #define MODE0 10
 #define MODE1 11
 #define MODE2 12
//  DRV8825 stepper(MOTOR_STEPS, DIR, STEP, MODE0, MODE1, MODE2);


void setup() 
{
  Serial.begin(BAUD);
  pinMode(6,OUTPUT); // Enable (Step motor one (tube length)).
  pinMode(5,OUTPUT); // Step
  pinMode(4,OUTPUT); // Dir
  digitalWrite(6,LOW); // Set Enable low (Step motor two (CAM)).
  pinMode(7,OUTPUT); // Enable2
  pinMode(8,OUTPUT); // Step2
  pinMode(9,OUTPUT); // Dir2
  digitalWrite(7,LOW); // Set Enable low
  }

void loop() 
{
  // Step motor one (tube length).
  digitalWrite(6,LOW); // Set Enable low
  digitalWrite(4,LOW); // Set Dir high
  Serial.println("Loop 200 steps (1 rev)");
  for(x = 0; x < 118; x++) // Loop 200 times
  {
    digitalWrite(5,HIGH); // Output high
    delay(1); // Wait
    digitalWrite(5,LOW); // Output low
    delay(1); // Wait
  }
  Serial.println("Pause");
  delay(10); // pause one second

 // Step motor two (CAM).
    digitalWrite(7,LOW); // Set Enable low
  digitalWrite(9,HIGH); // Set Dir high
  Serial.println("Loop 200 steps (1 rev)");
  for(x = 0; x < 1036; x++) // Gear ratio 1 : 5.18. Loop 200 times
  {
    digitalWrite(8,HIGH); // Output step high
    delay(4); // Wait
    digitalWrite(8,LOW); // Output step low
    delay(4); // Wait
  }
  Serial.println("Pause");
  delay(100); // pause one second
}

Help is greatly appreciated Thanks

Hello.

It looks like you might have included several different stepper libraries in your code, however it does not look like you are actually using any of them. You could probably just remove the include statements for those in that example. Also, some of the comments in your code are not consistent with the functions you are calling. For instance delay(10); will cause a 10 millisecond (0.01 second) pause. You can find documentation of these functions on the Arduino website; here is the page for the delay() function.

Setting the microstepping mode could just as easily be done with hardware as software. The mode for the driver is set by providing the appropriate HIGH or LOW voltages to the M0 - M2 pins. You could use the digitalWrite() function in your setup() routine to do this or remove the mode pin connections from your microcontroller and connect the mode pins directly to GND or 5V. When in a microstepping mode, each pulse sent to the STEP pin moves the stepper a microstep instead of a full step. So if you are in 1/16 microstepping mode, you will need to send 16 pulses to move a full step.

What did you set the current limit to for your motors? How are you supplying power to them? Could you post pictures that show you setup so I can look for any wiring mistakes?

-Nathan