1

I should begin by saying I am not a programmer, do not really know much about programming, and am programming an Arduino Uno for the first time. I am using a Nema 23 motor (23HS22-2804S) with a microstep driver (ST-M5045). Within the following code is the description of what I need the program to do:

#include <AccelStepper.h>

/* Using a stepper motor,
 rotate a vibrational model using gears interconnected by springs
 in such a way as to induce torsional vibration, which should be visible by comparing
 movement of juxtaposed rotating gears with markers painted on. */

AccelStepper stepper(AccelStepper::FULL4WIRE, 2, 6, 4, 8);

int Microstepping = 8; /* Microstepping factor, as set on the ST-M5045 control board. 
                          Multiplies the number of steps per revolution on the stepper motor.
                          Reference controller manual for adjustments to this number. */
int Steps = 200; /* Number of steps on your stepper motor.*/
int SPS;
int Amp;
int Freq;
// int SC;
int n = 2;
int i;
int totalSteps = Microstepping * Steps;

/* It should be noted that the Microstepping and Steps factors are not necessary, and adjusting the microstepping factor
 *  on the fly will not break the code. However, be aware that changing the microstepping factor by more than one interval
 *  at a time can cause the motor to not keep up with the sudden changes, i.e. losing torque or vibrating/stuttering. */

void setup() {               // THIS RUNS ONCE //

  // read potentiometers; raw inputs from 0 to 1023 //
  SPS = analogRead(0)*0.733; // MAX RPM ~28, max speed ~750 steps per sec (speeds above 1000 steps per second are unreliable,
                             // according to AccelStepper documentation)// 
  Amp = analogRead(1)/20;     // MAX AMP ~51//
  Freq = analogRead(2)/170;   // MAX FREQ ~6 Hz//
  
  stepper.setMaxSpeed(SPS);
  stepper.setAcceleration(SPS/1.5);

  int nextStop = totalSteps/Freq;
  
  stepper.moveTo(nextStop);
  stepper.run();
}

void loop() {
  int nextStop = totalSteps/Freq;

// reaches here, doesn't execute if loop. 
   if(stepper.distanceToGo()== 0){
     SPS = analogRead(0)*0.733;
     Amp = analogRead(1)/20;
     Freq = analogRead(2)/170;
     i = SPS - Amp;
     if(i <=0)
       i = 1;
     stepper.setSpeed(i);
     stepper.moveTo(nextStop*n);
     stepper.run();
    }
    n++;
}

When I use Serial.println() to check where the program is working and where it isn't, I see that it completes the setup loop without ever moving, and in slightly different versions of the same code, it has entered the if() statement and executed it (also without moving.)

An earlier version of the program runs and executes all statements, but only moves a maximum of about 20 steps per second, without the fluctuations in speed I call for, and doesn't respond in real time to any input from the speed potentiometer that puts the speed above 20.

Ideally, the program would run the demo at full speed, and freq times per second, it would slow down just enough to be noticeable as a torsional vibration.

I have tried running the program with and without the run() lines, and I have tried using runToNewPosition() in attempts to get the program to stop and properly execute the movement.

I made the setup loop as close as possible to the setup loop in bounce.pde, the example program in the AccelStepper documentation which moves the stepper motor between two points repeatedly, accelerating and decelerating before changing directions. The reason I did this is because I know that the setup loop in bounce.pde works, and so I would feel more confident that my setup loop is not the root problem.

Any help you can offer me is appreciated! Thanks for your time.

2
  • That driver appears to use a STEP / DIR interface. You'll need the DRIVER MotorInterfaceType, not FULL4WIRE.
    – towe
    Oct 2 '20 at 12:45
  • towe, thank you for your response. As I began writing up this post, I began to realize that I am indeed using a driver between the Arduino and the stepper, which I had mistakenly taken to mean a special type of motor with only 2 wires, citing the AccelStepper documentation, which says "2 driver pins required." I'll try editing my program to use the DRIVER interface type.
    – czar1249
    Oct 2 '20 at 13:03
0

Please read the documentation for the AccelStepper library.

Poll the motor and step it if a step is due, implementing accelerations and decelerations to achieve the target position. You must call this as frequently as possible, but at least once per minimum step time interval, preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due, based on the current speed and the time since the last step.

source

You are only calling run once, after setting a new position.

Move stepper.run(); out of the if statement, the the end of the loop function.

      ...
      stepper.moveTo(nextStop*n);
    }
    stepper.run();
    n++;
}
4
  • Thank you for your answer. I have read the documentation a few times, and the description for the run() command means nothing to me because I have no clue what my step time interval is. Like I said, I don't know anything about these things.
    – czar1249
    Oct 2 '20 at 12:55
  • run checks if the motor needs to make a (single) step, right now. If not, it just does nothing. You don't need to know when to call it. It will itself keep track of when a new step is needed. So you need to call it as often as possible. I know it isn't all that intuitive. I still find it a bit weird, but I understand why they did it.
    – Gerben
    Oct 2 '20 at 13:01
  • 1
    Okay, thank you. I've run the program now with the edit you suggested, and it works. Doesn't achieve my end goal yet, but it's on its way.
    – czar1249
    Oct 2 '20 at 13:17
  • @czar1249 If this solved your issue, please accept the answer. Oct 3 '20 at 1:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.