I've been tasked with programming a Nema 23 stepper with a DM542T Driver and a Sparkfun Redboard (Equivalent to an Arduino Uno I believe).
I need one button to spin the motor clockwise when pressed down and stop when the button is not pushed, and another button to spin the motor counter clockwise when pressed down and stop when the button is not pushed.
I was able to get the two buttons to work, but I'm having trouble getting the motor to spin at an exact RPM. I think I need to fix the way my loop is set up to fix this issue, but what do you guys think?
In addition, how would you recommend adding a feature so I can input any desired RPM so the stepper motor will run at that speed? Is there a formula that relates Pulse/Rev and RPM?
Thank you!
// Pin Definitions
const int Dirp = 3;
const int stepPin = 4;
const int GreenPin= 8;
const int RedPin= 9;
// Variables
int GreenState = 0; // current state of the button
int RedState = 0; // current state of the button
bool isForward = false; // Set isForward as False
bool isBackward = false; // Set isBackward as False
void setup() {
pinMode(GreenPin, INPUT_PULLUP); // GreenPin is HIGH until button is pushed
pinMode(RedPin, INPUT_PULLUP); // RedPin is HIGH until button is pushed
pinMode(stepPin, OUTPUT); // Set stepPin as Output
pinMode(Dirp, OUTPUT); // Set Dirp as Output
}
void loop()
{
isForward = false;
isBackward = false;
GreenState = digitalRead(GreenPin);
RedState = digitalRead(RedPin);
if(GreenState == LOW)
{
digitalWrite(Dirp,HIGH);
isBackward = true;
delayMicroseconds(40);
}
if(RedState == LOW)
{
digitalWrite(Dirp,LOW);
isForward = true;
delayMicroseconds(40);
}
while(isForward || isBackward)
{
digitalWrite(stepPin,HIGH);
delayMicroseconds(40);
digitalWrite(stepPin,LOW);
delayMicroseconds(40);
GreenState = digitalRead(GreenPin);
RedState = digitalRead(RedPin);
if(GreenState == HIGH || RedState == HIGH)
{
isForward = false; // Stop Spinning if Button is not Pressed
isBackward = false;
}
}
}
That works in the church. Knowing is needed but hopefully there's a helper knowing.
Stepper motors are good at making precise moves. For speed control critical tasks DC motors are preferably used.
In the very last line, that delay looks very low. Does the stepper run without buzzing and stopping?
There are libraries that handles speed. Accelstepper is an old guy, not so easy to use and there's a younger one, Moto- something (can't find the name).
Let's hope a knowing helper can fill in the blanks.
I think that the library that @Railroader is thinking of is the MobaTools library with a class for steppers. Easier to use and learn than AccelStepper in my opinion. Documentation available on the GitHub page. The library should be installed through the IDE library manager.
Here is a code that, I believe, does what you describe. Push one button for steady clock wise rotation at a set RPM, push the other for a for steady anti-clock wise rotation at a set RPM, push or release both at the same time the stepper will stop. To get accurate RPM, the hardware and software settings must match. That is motor steps/rev and microstepping. Tested on real hardware.
Thank you for the help! This code works really well! I just have a few more questions:
Is microstepMultiplier based on the Stepper Driver? If so, how do I know what to set it as? (If the Pulse/Rev on the driver is 800 and the steps/rev on the motor is 200, is the microstepMultiplier = 4?)
Can the pins be set to 4 3 5 8 9 instead of 2 5 8 9 10? I changed it to 4 3 5 8 9 but wanted to make sure this doesn't somehow cause issues? (Super beginner question lol)
Yes. You set the microstepping on the driver with dip switches according to this table. With your driver, motorStepsPerRev = 200 and microstepMultiplier = Pulses/rev (from the table) / motorStepsPerRev . But that is not really important.
Your driver sets multistepping differently from the drivers that I use. With my drivers, I need to calculate the value for steps\rev, but your driver tells you that number from the table.
Of course. Set them however that you want or need. Just avoid using pins 0 or 1 since those pins are the hardware serial used for programs upload. The pins that I used are because I have a CNC shield and that dictates which pins are used for the motor step and dir terminals on the drivers.
It is recommended that one use at least about 4x microstepping (800 Pulses/rev) to mitigate resonance effects.
Thanks again! Is there a Pulse/Rev setting that works best with the stepper.setspeed() command? I noticed different speeds when changing the Pulse/Rev setting on the Driver/code.
I am not sure that I understand the question. The setSpeed() funcion should work fine up to the maximum allowed speed. The maximum speed depends on the library (AccelStepper, 4000 steps/second), the motor power supply (higher voltage allows higher speed) and other, lessor, factors.
AccelStepper uses steps/second as the speed unit. So, yes, at the same steps/sec and different Pulse/rev settings the visible speed will be different. At 200 Pulse/rev and 200 steps/sec there will be 1 rev per second (60RPM). At 800 Pulse/rev and 200 steps/sec there will be 1/4 rev per second (15RPM).
Howdy! I realized that holding the button down is hard on the fingers.
Is there a way to change the loop section of the code so that pressing one button starts clockwise movement and pressing the same button again ends clockwise movement? And so that pressing the other button starts counter-clockwise movement and pressing the same button again ends counter-clockwise movement?