Rotate clockwise, pause, then rotate counterclockwise

Hi, I'm working on a project that requires a stepper motor to rotate clockwise while moving down, pause, then rotate counterclockwise moving up. When I download this code, the motor will keep rotating in one direction and rotate longer without stop and rotate reversely. So, I believe I would have to comment part 5 (counterclockwise rotation & moving up) at first, upload the code and let it run, then comment part 1 (clockwise rotation & moving down) and recover part 5, upload the code again to make the motor rotate in another direction. How could I revise my code to integrate my desired steps into one upload without having to uncomment & comment?

Below is my code:

// Include the Arduino Stepper Library
#include <Stepper.h>
 
// Number of steps per output rotation
const int stepsPerRevolution = 200;
float pi = 3.14159265;
 
// Create Instance of Stepper library
Stepper myStepper(stepsPerRevolution, 12, 11, 10, 9);
 
 
// Values measured in CAD (DO NOT CHANGE)
float r = 1.875*4;    // (mm)  radius of helical coil (x4 for tack scaling)
float phi = 7.256;    // (deg) helical angle 
  int pitch = 6;      // (mm)  linear displacement from one rotation (x4 for tack scaling) (1.5*4)
float depth = 14.25;  // (mm)  depth of helical tack (excluding tack head, x4 for tack scaling) (3.5625*4)
                      // Set dist_down as depth for actual tack tests
 
///////////////////////// INITIAL VARIABLES /////////////////////////
 
// Values set from lab computer (CHANGE THESE)
  // Variables/equations after this section will be based on these values)
  float d_speed     = 120;    // "Test Speed":       (mm/min)  linear displacement speed 
                               // If it goes below this speed, the motor will not turn (w cannot be less than 1 RPM)
  // Distances (dist_down, dist_up1, and dist_up2) can be related back to the "depth" variable from the CAD section
    //in the code below, I set dist_down equal to depth for full penetration
 
    
  float dist_down   = depth;     // "Distance":         (mm)    distance moved down
  float hold_bottom = 10;     // "Hold Time:         (sec)   hold time at the bottom
  float hold_mid    = 10;     // "Hold Time 2":      (sec)   hold time after it's pulled up, but not all the way
  float dist_up1    = depth/2;   // "Distance 2":       (mm)    distance it moves up from the very bottom (no rotation)
  float dist_up2    = depth/2;   // "Return Distance":  (mm)    distance it moves up after hold_mid (with rotation)
 
 
///////////////////////// EQUATIONS AND CALCULATIONS /////////////////////////
//time for each section
float t_part1 = dist_down/d_speed;   // time it takes to complete part 1 (rotate down)            (sec)
float t_part2 = hold_bottom;         // time it takes to complete part 2 (hold at bottom)         (sec)
float t_part3 = dist_up1/d_speed;    // time it takes to complete part 3 (pull up, no rotation)   (sec)
float t_part4 = hold_mid;            // time it takes to complete part 4 (hold at point)          (sec)
float t_part5 = dist_up2/d_speed;    // time it takes to complete part 5 (pull up with rotation)  (sec)
 
//calculating the rotational speed
float w = d_speed/(2*pi*r*sin(phi*pi/180)); // rotational speed (RPM) to match linear displacement speed
 
//calculated number of rotations for each part
float rot_down = dist_down/pitch;    // PART 1: ROTATE DOWN INTO THE TISSUE
float rot_up   = dist_up2/pitch;    // PART 5: PULL UP AND ROTATE OUT (negative for CCW rotation direction)
 
//all of the code is under void setup() as it only needs to run once (not looped)
void setup()
{
  myStepper.setSpeed(60);   // Sets the rotational speed (RPM)
  
  // initialize the serial port:
  Serial.begin(9600);
 
  ///////////////////////// CODE IMPLEMENTING ROTATIONAL MOVEMENT /////////////////////////
  // To see the serial prints, navigate to Tools > Serial Monitor. 
  
  // PART 1: Rotate down
  myStepper.step(-rot_down*stepsPerRevolution);   //total steps motor travels (this is how it measures changes)
  
  //PART 2-4: Hold at bottom, pull up (no rotation), hold at point
    //In all of these steps, the motor is not rotating, so the delay can be combined
  delay((t_part2 + t_part3 + t_part4)*1000); //delay is in milliseconds
  
  // PART 5: Pull up with rotation
  myStepper.step(rot_up*stepsPerRevolution);
}

//void loop() isn't used as the program does not need to repeat
void loop() 
{
}   

installing the mobaTools-library from the library-manager
and then use the back_ForthStepperPause.ino example-code as a base

adapt from 2 IO-pin step/dir-control
to 4 IO-pin control
then adapt speed and number of steps to your needs

Th advantage of the mobaTool-library is step-creation is done "in the backround".
This makes it easy to execute additional code that checks for sensor-values or button-presses.
And the MobaTools also offer button-handling.

/*  Example for MobaTools
    Moving a stepper back and forth
*/
#include <MobaTools.h>

// Adjust pins, steps and time as needed
const byte stepPin = 9;
const byte dirPin  = 8;
const int stepsPerRev = 800;   // Steps per Revolution ( example with 1/4 microsteps )
const long  targetPos = 1600;         // stepper moves between 0 and targetpos
long nextPos;


MoToStepper myStepper ( stepsPerRev, STEPDIR );
MoToTimer pause;                    // Pause between stepper moves
bool stepperRunning;

void setup() {
  myStepper.attach( stepPin, dirPin );
  myStepper.setSpeed( 600 );  // 60 Rev/Min ( if stepsPerRev is set correctly )
  myStepper.setRampLen( 200 );
  stepperRunning = true;
}

void loop() {
  if ( stepperRunning ) {
    // Wait till stepper has reached target, then set pause time
    if ( !myStepper.moving() ) {
      // stepper has reached target, start pause
      pause.setTime( 1000 );
      stepperRunning = false;
    }
  } else {
    // stepper doesn't move, wait till pause time expires
    if ( pause.expired() ) {
      // pause time expired. Start stepper in opposite direction
      if ( nextPos == 0 ) {
        nextPos = targetPos;
      } else {
        nextPos = 0;
      }
      myStepper.moveTo( nextPos );
      stepperRunning = true;
    }
  }

  // The sketch is not blocked while the stepper is moving nor while it is stopped.
  // Other nonblocking  tasks can be added here
}

best regards Stefan

+1 for MobaToos stepper. In my opinion, it is easier to learn than AccelStepper. The Stepper library is fine for testing or learning stepper basics, but not for more serious uses.

What stepper motor and stepper driver are you using?

I forgot to include this in the main post, but the moving up & down parts are done by a separate machine that the motor is attached to. Hence, I just need to fix the rotation, hold, reverse rotation part. Does this code still apply? Sorry, I'm really new to this!

I'm using the NEMA 23 bipolar stepper motor and the L293D motor driver. I'm testing, so that's why I was using the Stepper library. Would it be better to just transition to AccelStepper?

A Nema 23 stepper-motor has a pretty big size. The maximum current will be 1A or even 2A per coil. An L293D driver can deliver only 0,6 A.

What specs does your Nema 23 stepper-motor have?
Do you have to drive a significant load?
Do you have to accelerate pretty fast?

Only in case of:

  • almost no load
  • only slow accelereration

the 0,6A of the L293D will be sufficient.

the MobaTools code I have posted delivers the functionality of
move one direction - pause - move other direction

right away

best regards Stefan

It would be difficult to find a worse driver for a modern bipolar stepper than the ancient and inefficient L293. At anything close to 600mA the driver will drop 4V, or more, of your motor power supply voltage and that power is dissipated as heat.

Really, do yourself a favor and find a good modern driver with coil current control. What is the coil current specification for the motor? We can help you to find an appropriate driver for it.

The modern driver will likely be a step/dir driver so only needs 2 pins, minimum. The Stepper library is not compatible with step/dir type drivers.

You should explain a bit more how that machine works and what your stepper will do in this machine. Otherwise we cannot give useful advice about your code.

Usually NEMA23 steppers are designed to be driven by a current driver, that regulates the current through the coils. The ancient L293D driver cannot do this. As @groundFungus already wrote, please provide a datasheet to your stepper. NEMA23 doesn't tell anything about the electrical specification of the motor.

Given that a stepping motor takes the maximum current when it is stopped I find that assertion hard to believe.

a small current will create a holding torque that will be at least a little above resting-torque needed to rotate the rotor when motor is unpowered.

A very slow acceleration will create smaller forces caused through inertia than a fast acceleration.

Though if the current is too small the rotor won't turn at all.
Any load will increase the minimum current needed to make the rotor turn in a defined way without loosing steps

best regard Stefan

indeed ive an overview about the whole project.
What kind of "separate machine" ?
If this other machine does the moving up & down?

What kind of move do the stepper-motors do?
left / right? back and forth?

What sort of controller are you thinking of using that can throttle down the current when stationary?

This is not the way stepping motor controllers normally work.

I don't remember the stepper-controller-typ-numbers but a reasonable part of them have a switchable option reduce current if idling (to 70% or 50% of operating current)

Never seen one of those at all, I would be very interested in the part number

Would this low current be settable or just a percentage of the normal set current?

not a chip but a full populated high-current driver
http://www.leadshineusa.com/uploadfile/down/dm542e_m.pdf

see Automatic idle current reduction
7.2.2 Standstill Current Configuration
SW4 is used to set motor idle current percentage. At OFF position it means the standstill current is set to be 50% of the
selected output current. At ON position it means standstill current is set to be the same as the selected dynamic current.
The current automatically reduced to 50% of the selected dynamic current 0.4 second after the last pulse.

The Trinamic stepper-drivers have a "Coolstep-Option"

https://www.ebay.de/itm/304061205530

The trinamic-driverchips have more options like supersilent-mode etc.
You will doubt that the motor is moving in silent-mode

best regards Stefan

Thanks, very interesting.

Hi, @twoone

How do you know when to start the back and forth movement?
How do you know when the "machine" is in the lower position and when it is in the high position?

We need a bit more info on what your project actually is.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

@groundFungus @StefanL38 Attached is the data sheet for the motor. For what I'm trying to do, I'm trying to test the insertion and removal of a twist tack into a silicon block. A separate machine, more specifically a Stable Micro Systems machine, will lower the motor and the motor will have to spin clockwise, pause, then spin back around in the other direction.
23HS45-4204S.pdf (150.8 KB)

similar to what I have described and what I expected to find.

Weight 1,8 kg, torque 3 Nm. This is a bull of a steppermotor
Current: 4.2A that is seven times more than an L293D can do: maximum 0.6A

Your project sounds like developing a test-system at a university or a company
I suggest to make the whole thing professional that the institution / the company is spending
a well suited stepper-motor-driver
for example
leadshine DME 556 for around $60.

don't

order a cheap low-quality illegal copy from aliexpress or banggood you would regret it.

If you can post a picture of the twist jack and post the size of this twist jack maybe a smaller steppermotor will do

Did you do a pre-test with a small torque-limiting wrench to find out how much torque the motor must have?

best regards Stefan

That is the current per phase, so the motor as a whole will take twice that.